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

Compare commits

..

76 Commits
v0.3 ... v0.5

Author SHA1 Message Date
Albert Vaca
5583aa69b9 Version should be 0.5 instead of 0.6! 2014-02-19 16:31:12 +01:00
Albert Vaca
0600b1ee2e Oops, duplicate library 2014-02-14 20:11:22 +01:00
Albert Vaca
2f0059938d Increased version number to tag and release 2014-02-14 17:08:30 +01:00
Albert Vaca
a023316609 Renamed sftp plugin to "filesystem browser" 2014-02-14 17:08:30 +01:00
Albert Vaca
d94ed56c4e oops 2014-02-14 17:08:30 +01:00
Samoilenko Yuri
15a11cce02 Publick key auth for sftp plugin 2014-02-14 17:08:07 +01:00
Albert Vaca
36530b9580 Prefer IPv4 over IPv6 2014-02-14 17:07:42 +01:00
Samoilenko Yuri
f54acd7308 fix 2014-02-14 17:07:42 +01:00
Samoilenko Yuri
cfe9ccdc31 WORKAROUND new gradle android plugin bug 2014-02-14 17:07:42 +01:00
Samoilenko Yuri
52c7581f42 moved to updated gradle and Android Studio 2014-02-14 17:07:12 +01:00
Albert Vaca
a57dc71ad1 Libs are now included from Maven repo 2014-02-14 17:05:31 +01:00
Samoilenko Yuri
77d06cfe77 sftp implementations splits from sftpplugin 2014-02-14 17:04:36 +01:00
Samoilenko Yuri
13a7c1e5fe first draft SFTP implementation 2014-02-14 17:04:30 +01:00
l10n daemon script
5ccf215a54 SVN_SILENT made messages (after extraction) 2014-02-06 01:38:48 +00:00
l10n daemon script
fddf3c64b5 SVN_SILENT made messages (after extraction) 2014-02-01 01:41:08 +00:00
l10n daemon script
fb02b9bdf1 SVN_SILENT made messages (after extraction) 2014-01-29 01:40:11 +00:00
l10n daemon script
8453156d16 SVN_SILENT made messages (after extraction) 2014-01-23 01:37:44 +00:00
Albert Vaca
9bbe2908ed We will only sync actual notifications from now on
BUG: 325668
2014-01-10 19:29:50 +01:00
Albert Vaca
fb843f8789 Notifications with FLAG_FOREGROUND_SERVICE are not shown anymore
Actually, they are not 'notifications'.
2014-01-10 18:00:26 +01:00
Albert Vaca
c85619dfd2 Phone number shown next to contact name for calls/sms
BUG: 328197
2014-01-10 17:59:50 +01:00
Albert Vaca
de9f78adf3 Gradle upgrade to make Android Studio 4.2 happy 2014-01-10 17:07:00 +01:00
Samoilenko Yuri
9021ab9454 Partial impl of clipboard sync in early Android
Syncronization works only in one direction - incoming
2014-01-08 02:17:37 +04:00
Samoilenko Yuri
10210b3972 Fixed Ping notification on old phones
On old phones(LG P698) notification does not shown ultil all
fields are filles correctly: setContentIntent.
Added pendingIntent to notification as describved into official documentation for Notifications, to
fit support library requirements.
2014-01-08 01:20:24 +04:00
l10n daemon script
f83b9cbe0c SVN_SILENT made messages (after extraction) 2013-12-29 01:40:33 +00:00
l10n daemon script
7d821e7c88 SVN_SILENT made messages (after extraction) 2013-12-10 01:38:14 +00:00
l10n daemon script
02070343fe SVN_SILENT made messages (after extraction) 2013-11-28 01:42:19 +00:00
l10n daemon script
416a000dd3 SVN_SILENT made messages (after extraction) 2013-11-25 01:41:50 +00:00
Albert Vaca
a15cad9ec5 Increased version number to release 2013-11-24 17:49:15 +01:00
l10n daemon script
e98100f5f0 SVN_SILENT made messages (after extraction) 2013-11-24 01:37:28 +00:00
Albert Vaca
d19e7d2052 Missing permission (how could this work before?) 2013-11-23 01:49:34 +01:00
Albert Vaca
4e02c674f8 Still trying to fix the concurrency exception
I hope this doesn't cause infinite recursion.
2013-11-23 01:49:34 +01:00
Albert Vaca
6aa49757fc Fixed bug retrieving incorrect file sizes for file transfers
For some reason querying the content provider returns a different size than
using File.length()
2013-11-23 01:49:33 +01:00
Albert Vaca
3c10312d15 More Android Studio nonsensical project changes 2013-11-23 01:49:33 +01:00
l10n daemon script
26e3363b30 SVN_SILENT made messages (after extraction) 2013-11-19 01:37:14 +00:00
l10n daemon script
4033233ec1 SVN_SILENT made messages (after extraction) 2013-11-18 01:45:52 +00:00
Albert Vaca
34e53576e1 Trying to fix a concurrency exception 2013-11-15 15:31:38 +01:00
Albert Vaca
a15d76c588 Android Studio keeps changing the project files... 2013-11-14 18:41:35 +01:00
Albert Vaca
1acea73383 The battery percentage for low battery level is now signaled by the device
BatteryPlugin is now subscribed to the BATTERY_LOW event

REVIEW: 113838
2013-11-14 18:24:44 +01:00
Albert Vaca
6c8fdb0be7 Increased version number to release 2013-11-14 18:20:57 +01:00
l10n daemon script
749170a29c SVN_SILENT made messages (after extraction) 2013-11-14 01:36:45 +00:00
l10n daemon script
81b08cf89f SVN_SILENT made messages (after extraction) 2013-11-11 01:40:35 +00:00
Albert Vaca
786ea7658f Fixed bugs in NotificationsPlugin
Already existing notifications were not retrieved
Notifications without tickerText were crashing the plugin
2013-11-06 21:15:49 +01:00
Albert Vaca
996516ec88 Fixed a bug while pairing
Timeout was being fired after the pairing was done
Added lots of Log.e for debugging, now commented
2013-11-06 21:13:37 +01:00
Albert Vaca
a36e4a0c88 Added deviceType to the identity packages
This will tell if we are a phone, tablet, laptop or desktop
2013-11-06 19:06:18 +01:00
l10n daemon script
e08de81c73 SVN_SILENT made messages (after extraction) 2013-11-05 01:33:50 +00:00
Albert Vaca
30d2665b12 Upgraded project to new Android SDK
Now using gradle magic imports instead of jar files for libraries
2013-11-02 17:46:20 +01:00
l10n daemon script
c14946e9e4 SVN_SILENT made messages (after extraction) 2013-11-02 01:35:34 +00:00
l10n daemon script
1aab14fd50 SVN_SILENT made messages (after extraction) 2013-10-31 01:37:52 +00:00
l10n daemon script
549fc01c1d SVN_SILENT made messages (after extraction) 2013-10-30 01:42:44 +00:00
Albert Vaca
d59de8a0b6 Increased version to release 2013-10-30 01:46:00 +01:00
Mauro Panzeri
8823277e74 Follow the android guidelines for icons/drawables and their names.
Guidelines: http://goo.gl/E70Ez

REVIEW: 113200
2013-10-30 01:45:27 +01:00
Albert Vaca
30cf27e835 NetworkPackage.encrypt now returns a new package instead of changing itself
This was causing problems with plugins that keep a reference to the
packages they have already sent, like the telephony plugin, because the
package became encrypted (and thus inaccessible) after sending it.

BUG: 326275
2013-10-30 01:37:55 +01:00
Mauro Panzeri
9dbe1ec9cf Added a settings activity to change the publicly visible device name
When changed the new name will be used instead of the one from
HumanDeviceNames

REVIEW: 113204
BUG: 325061
2013-10-30 01:37:47 +01:00
Albert Vaca
0595662efc Spotify doesn't support seeking, disable mpris seek buttons for it 2013-10-30 01:31:21 +01:00
Albert Vaca
6609ae665c Fixed a crash trying to disconnect not-yet-active sessions. 2013-10-30 01:31:20 +01:00
Maksim Krylosov
2f26fa5188 Added rewind and fast-forward buttons to MPRIS controls 2013-10-30 01:31:20 +01:00
Albert Vaca
6471bafdd9 Fixed important bug trying to load device settings before deviceId was set
(Also improved code style and fixed minor TODOs)
2013-10-30 01:31:20 +01:00
Albert Vaca
0620810e4b Upgraded to build tools 18.1.1 and gradle 1.8 2013-10-30 01:31:20 +01:00
Albert Vaca
db9209765d Android Studio is getting confused if project name != directory name 2013-10-29 17:47:07 +01:00
Mauro Panzeri
e459d792d0 "Share to" now retrieves filename for file:// uris too
Querying the ContentProvider only works for content://... uris but when you
share a file from a file-manager, the uri you get has the form file://... and
ContentProvider returns a null cursor.

BUG: 325684
REVIEW: 113202
2013-10-29 17:47:07 +01:00
Albert Vaca
31fcc3e184 Project refactor because Android Studio was not able to open it
For some reason it was not detecting the directory as an Android project
Android Build Tools version increased from 18.0.1 to 18.1
2013-10-29 17:47:07 +01:00
l10n daemon script
544b5e8c87 SVN_SILENT made messages (after extraction) 2013-10-25 01:35:28 +00:00
l10n daemon script
7819ae1ca2 SVN_SILENT made messages (after extraction) 2013-10-18 01:44:45 +00:00
l10n daemon script
98885d6c35 SVN_SILENT made messages (after extraction) 2013-10-17 01:34:48 +00:00
l10n daemon script
485e646f6f SVN_SILENT made messages (after extraction) 2013-10-14 01:51:48 +00:00
l10n daemon script
dfece0a414 SVN_SILENT made messages (after extraction) 2013-10-11 01:53:05 +00:00
l10n daemon script
bbaf40165c SVN_SILENT made messages (after extraction) 2013-10-07 01:47:28 +00:00
Albert Vaca
b221fa04bf Increased version number for release 2013-10-05 17:26:51 +02:00
Albert Vaca
07bf1e9ebc Made sendPackage sync, so mutex hack in Device is no longer needed 2013-10-05 17:26:51 +02:00
Albert Vaca
a07c9a9fb7 Fixed warnings about cursors not closed 2013-10-05 17:26:51 +02:00
l10n daemon script
40a9171985 SVN_SILENT made messages (after extraction) 2013-10-04 01:52:34 +00:00
Albert Vaca
69197fd657 Increased version for release. 2013-10-03 15:52:10 +02:00
Albert Vaca
55e3861c5c Fixed a crash when pressing back from remote controls in action bar
Device activity isn't receiving the device id in that case.
2013-10-03 15:52:10 +02:00
Albert Vaca
5d00e6e168 Added a mutex to avoid files being sent all at the same time
It's a bit hackish but works.
2013-10-03 15:52:09 +02:00
l10n daemon script
967635a2f4 SVN_SILENT made messages (after extraction) 2013-10-03 01:46:02 +00:00
Albert Astals Cid
58b31fa032 Transition to the StaticMessages.sh thing
Let's see what next scripty run says
CCMAIL: albertvaka@gmail.com
2013-10-01 21:52:09 +02:00
100 changed files with 1952 additions and 357 deletions

9
.gitignore vendored
View File

@@ -1,4 +1,7 @@
local.properties
.gradle
.idea
out
.gradle/
.idea/
out/
build/
target/
classes/

View File

@@ -1 +0,0 @@
build/

View File

@@ -1,79 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="Debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebug" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleTest" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":KdeConnect" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/classes/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/source/r/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/test" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/assets" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/resources" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/apk" />
<excludeFolder url="file://$MODULE_DIR$/build/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android 4.3 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="android-support-v4" level="project" />
<orderEntry type="library" exported="" name="support-v4-18.0.0" level="project" />
<orderEntry type="library" exported="" name="ComAndroidSupportAppcompatV71800.aar" level="project" />
<orderEntry type="library" exported="" name="slf4j-api-1.6.6" level="project" />
<orderEntry type="library" exported="" name="mina-core-2.0.7" level="project" />
</component>
</module>

View File

@@ -1,26 +0,0 @@
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.5.+'
}
}
apply plugin: 'android'
dependencies {
compile "com.android.support:appcompat-v7:18.0.+"
compile files('libs/android-support-v4.jar')
compile files('libs/mina-core-2.0.7.jar')
compile files('libs/slf4j-api-1.6.6.jar')
}
android {
compileSdkVersion 18
buildToolsVersion "18.0.1"
defaultConfig {
minSdkVersion 9
targetSdkVersion 18
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,6 +0,0 @@
#!/usr/bin/env bash
mkdir locale
a2po export --android KdeConnect/src/main/res/ --gettext locale
mv locale/template.pot $podir/kdeconnect-android.pot
rm -rf locale

21
StaticMessages.sh Normal file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env bash
# The name of catalog we create (without the.pot extension), sourced from the scripty scripts
FILENAME="kdeconnect-android"
function export_pot_file # First parameter will be the path of the pot file we have to create, includes $FILENAME
{
potfile=$1
mkdir outdir
a2po export --android src/main/res/ --gettext outdir
mv outdir/template.pot $potfile
rm -rf outdir
}
function import_po_files # First parameter will be a path that will contain several .po files with the format LANG.po
{
podir=$1
a2po import --android src/main/res/ --gettext $podir
}

View File

@@ -1,2 +1,40 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.7.+'
}
}
apply plugin: 'android'
android {
compileSdkVersion 19
buildToolsVersion "19"
defaultConfig {
minSdkVersion 9
targetSdkVersion 19
}
packagingOptions {
exclude "META-INF/DEPENDENCIES"
exclude "META-INF/NOTICE"
exclude "META-INF/LICENSE"
exclude "META-INF/LICENSE.txt"
exclude "META-INF/NOTICE.txt"
}
}
dependencies {
repositories {
mavenCentral()
}
compile "com.android.support:support-v4:19.0.+"
compile "com.android.support:appcompat-v7:19.0.+"
compile "org.apache.mina:mina-core:2.0.+"
compile 'org.bouncycastle:bcprov-jdk16:1.45'
compile 'org.apache.sshd:sshd-core:0.8.0'
compile 'tomcat:tomcat-apr:5.5.+'
//compile fileTree(dir: 'libs', include: '*.jar')
}

View File

@@ -1,6 +1,6 @@
#Wed Apr 10 15:27:10 PDT 2013
#Sun Jan 12 12:44:14 MSK 2014
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.zip
distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-all.zip

View File

@@ -1,13 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugJava" />
<option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
<option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="false">
<output url="file://$MODULE_DIR$/build/classes/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/source/r/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/aidl/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/buildConfig/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/source/rs/test/debug" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/build/res/rs/test/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/assets" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/instrumentTest/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/.git" />
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/.idea" />
<excludeFolder url="file://$MODULE_DIR$/build/apk" />
<excludeFolder url="file://$MODULE_DIR$/build/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/res" />
<excludeFolder url="file://$MODULE_DIR$/build/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="sshd-core-0.8.0" level="project" />
<orderEntry type="library" exported="" name="tomcat-apr-5.5.15" level="project" />
<orderEntry type="library" exported="" name="slf4j-api-1.6.6" level="project" />
<orderEntry type="library" exported="" name="bcprov-jdk16-1.45" level="project" />
<orderEntry type="library" exported="" name="mina-core-2.0.7" level="project" />
<orderEntry type="library" exported="" name="support-v4-19.0.1" level="project" />
<orderEntry type="library" exported="" name="ComAndroidSupportAppcompatV71901.aar" level="project" />
</component>
</module>

View File

@@ -1 +0,0 @@
include ':KdeConnect'

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.kde.kdeconnect_tp"
android:versionCode="5"
android:versionName="0.3.0">
android:versionCode="12"
android:versionName="0.5">
<uses-sdk android:minSdkVersion="9"
android:targetSdkVersion="18" />
@@ -18,13 +18,15 @@
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:required="false"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:required="false" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" android:required="false"/>
<uses-permission android:name="android.permission.RECEIVE_SMS" android:required="false" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
@@ -44,11 +46,19 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.MainSettingsActivity"
android:label="@string/settings"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity"
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity
android:theme="@style/Theme.AppCompat"
android:name="org.kde.kdeconnect.UserInterface.DeviceActivity"
@@ -57,8 +67,7 @@
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
</activity>
<activity
android:theme="@style/Theme.AppCompat"
@@ -68,7 +77,6 @@
>
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity

View File

@@ -56,7 +56,7 @@ public abstract class BaseLink {
}
}
//TO OVERRIDE
//TO OVERRIDE, should be sync
public abstract boolean sendPackage(NetworkPackage np);
public abstract boolean sendPackageEncrypted(NetworkPackage np, PublicKey key);

View File

@@ -1,43 +1,28 @@
package org.kde.kdeconnect.Backends.LanBackend;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Base64;
import android.util.Log;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.future.IoFuture;
import org.apache.mina.core.future.IoFutureListener;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.json.JSONObject;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.NetworkPackage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.nio.charset.Charset;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
public class LanLink extends BaseLink {
private IoSession session = null;
public void disconnect() {
Log.i("LanLink", "Disconnect: "+session.getRemoteAddress().toString());
if (session == null) return;
//Log.i("LanLink", "Disconnect: "+session.getRemoteAddress().toString());
session.close(true);
}
@@ -46,10 +31,12 @@ public class LanLink extends BaseLink {
this.session = session;
}
private JSONObject sendPayload(final InputStream stream) {
private Thread sendPayload(NetworkPackage np) {
try {
final InputStream stream = np.getPayload();
ServerSocket candidateServer = null;
boolean success = false;
int tcpPort = 1739;
@@ -61,14 +48,17 @@ public class LanLink extends BaseLink {
} catch(Exception e) {
Log.e("LanLink", "Exception openning serversocket: "+e);
tcpPort++;
if (tcpPort >= 1764) return new JSONObject();
if (tcpPort >= 1764) {
Log.e("LanLink", "No more ports available");
return null;
}
}
}
JSONObject payloadTransferInfo = new JSONObject();
payloadTransferInfo.put("port", tcpPort);
final ServerSocket server = candidateServer;
new Thread(new Runnable() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//TODO: Timeout when waiting for a connection and close the socket
@@ -93,9 +83,12 @@ public class LanLink extends BaseLink {
try { server.close(); } catch(Exception e) { }
}
}
}).start();
});
thread.start();
return payloadTransferInfo;
np.setPayloadTransferInfo(payloadTransferInfo);
return thread;
} catch(Exception e) {
@@ -106,23 +99,41 @@ public class LanLink extends BaseLink {
}
}
//Blocking, do not call from main thread
@Override
public boolean sendPackage(final NetworkPackage np) {
if (session == null) {
Log.e("LanLink", "sendPackage failed: not yet connected");
return false;
}
if (np.hasPayload()) {
JSONObject transferInfo = sendPayload(np.getPayload());
np.setPayloadTransferInfo(transferInfo);
try {
Thread thread = null;
if (np.hasPayload()) {
thread = sendPayload(np);
if (thread == null) return false;
}
WriteFuture future = session.write(np.serialize());
future.awaitUninterruptibly();
if (!future.isWritten()) return false;
if (thread != null) {
thread.join(); //Wait for thread to finish
}
return true;
} catch (Exception e) {
e.printStackTrace();
Log.e("LanLink", "sendPackage exception");
return false;
}
session.write(np.serialize());
return true;
}
//Blocking, do not call from main thread
@Override
public boolean sendPackageEncrypted(NetworkPackage np, PublicKey key) {
@@ -133,19 +144,25 @@ public class LanLink extends BaseLink {
try {
Thread thread = null;
if (np.hasPayload()) {
JSONObject transferInfo = sendPayload(np.getPayload());
np.setPayloadTransferInfo(transferInfo);
thread = sendPayload(np);
if (thread == null) return false;
}
np.encrypt(key);
np = np.encrypt(key);
WriteFuture future = session.write(np.serialize());
if (!future.await().isWritten()) return false;
session.write(np.serialize());
if (thread != null) {
thread.join(); //Wait for thread to finish
}
return true;
} catch (Exception e) {
e.printStackTrace();
Log.e("LanLink", "Encryption exception");
Log.e("LanLink", "sendPackageEncrypted exception");
return false;
}

View File

@@ -58,11 +58,15 @@ public class LanLinkProvider extends BaseLinkProvider {
super.messageReceived(session, message);
//Log.e("LanLinkProvider","Incoming package, address: "+session.getRemoteAddress()).toString());
//Log.e("LanLinkProvider","Received:"+message);
String theMessage = (String) message;
NetworkPackage np = NetworkPackage.unserialize(theMessage);
if (theMessage.isEmpty()) {
Log.e("LanLinkProvider","Empty package received");
return;
}
LanLink prevLink = nioSessions.get(session.getId());
NetworkPackage np = NetworkPackage.unserialize(theMessage);
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
@@ -77,6 +81,7 @@ public class LanLinkProvider extends BaseLinkProvider {
nioSessions.put(session.getId(),link);
addLink(np, link);
} else {
LanLink prevLink = nioSessions.get(session.getId());
if (prevLink == null) {
Log.e("LanLinkProvider","2 Expecting an identity package");
} else {
@@ -128,17 +133,23 @@ public class LanLinkProvider extends BaseLinkProvider {
future.addListener(new IoFutureListener<IoFuture>() {
@Override
public void operationComplete(IoFuture ioFuture) {
IoSession session = ioFuture.getSession();
final IoSession session = ioFuture.getSession();
final LanLink link = new LanLink(session, identityPackage.getString("deviceId"), LanLinkProvider.this);
Log.i("LanLinkProvider", "Connection successful: " + session.isConnected());
LanLink link = new LanLink(session, identityPackage.getString("deviceId"), LanLinkProvider.this);
new Thread(new Runnable() {
@Override
public void run() {
NetworkPackage np2 = NetworkPackage.createIdentityPackage(context);
link.sendPackage(np2);
NetworkPackage np2 = NetworkPackage.createIdentityPackage(context);
link.sendPackage(np2);
nioSessions.put(session.getId(), link);
addLink(identityPackage, link);
}
}).start();
nioSessions.put(session.getId(), link);
addLink(identityPackage, link);
}
});

View File

@@ -26,7 +26,7 @@ public class LoopbackLink extends BaseLink {
@Override
public boolean sendPackageEncrypted(NetworkPackage in, PublicKey key) {
try {
in.encrypt(key);
in = in.encrypt(key);
String s = in.serialize();
NetworkPackage out= NetworkPackage.unserialize(s);
out.decrypt(privateKey);

View File

@@ -14,7 +14,7 @@ import android.util.Log;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
import org.kde.kdeconnect.Backends.LoopbackBackend.LoopbackLinkProvider;
import org.kde.kdeconnect.UserInterface.MainSettingsActivity;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
@@ -50,9 +50,11 @@ public class BackgroundService extends Service {
};
private void loadRememberedDevicesFromSettings() {
//Log.e("BackgroundService", "Loading remembered trusted devices");
SharedPreferences preferences = getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
Set<String> trustedDevices = preferences.getAll().keySet();
for(String deviceId : trustedDevices) {
//Log.e("BackgroundService", "Loading device "+deviceId);
if (preferences.getBoolean(deviceId, false)) {
Device device = new Device(this, deviceId);
devices.put(deviceId,device);
@@ -110,6 +112,7 @@ public class BackgroundService extends Service {
if (d != null) {
d.removeLink(link);
if (!d.isReachable() && !d.isPaired()) {
//Log.e("onConnectionLost","Removing connection device because it was not paired");
devices.remove(link.getDeviceId());
d.removePairingCallback(devicePairingCallback);
}
@@ -179,6 +182,7 @@ public class BackgroundService extends Service {
Log.i("BackgroundService","Service not started yet, initializing...");
initializeRsaKeys();
MainSettingsActivity.initializeDeviceName(this);
loadRememberedDevicesFromSettings();
registerLinkProviders();

View File

@@ -7,7 +7,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
@@ -40,7 +39,7 @@ public class Device implements BaseLink.PackageReceiver {
private String deviceId;
private String name;
private PublicKey publicKey;
public PublicKey publicKey;
private int notificationId;
private int protocolVersion;
@@ -93,17 +92,18 @@ public class Device implements BaseLink.PackageReceiver {
//Device known via an incoming connection sent to us via a devicelink, we know everything but we don't trust it yet
Device(Context context, NetworkPackage np, BaseLink dl) {
settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
//Log.e("Device","Constructor B");
this.context = context;
this.deviceId = np.getString("deviceId");
this.name = np.getString("deviceName");
this.name = np.getString("deviceName", "unidentified device");
this.protocolVersion = np.getInt("protocolVersion");
this.pairStatus = PairStatus.NotPaired;
this.publicKey = null;
settings = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE);
addLink(np, dl);
}
@@ -151,15 +151,21 @@ public class Device implements BaseLink.PackageReceiver {
Resources res = context.getResources();
if (pairStatus == PairStatus.Paired) {
for (PairingCallback cb : pairingCallback) cb.pairingFailed(res.getString(R.string.error_already_paired));
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(res.getString(R.string.error_already_paired));
}
return;
}
if (pairStatus == PairStatus.Requested) {
for (PairingCallback cb : pairingCallback) cb.pairingFailed(res.getString(R.string.error_already_requested));
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(res.getString(R.string.error_already_requested));
}
return;
}
if (!isReachable()) {
for (PairingCallback cb : pairingCallback) cb.pairingFailed(res.getString(R.string.error_not_reachable));
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(res.getString(R.string.error_not_reachable));
}
return;
}
@@ -169,6 +175,7 @@ public class Device implements BaseLink.PackageReceiver {
@Override
public void sendSuccessful() {
if (pairingTimer != null) pairingTimer.cancel();
pairingTimer = new Timer();
pairingTimer.schedule(new TimerTask() {
@Override
@@ -176,9 +183,10 @@ public class Device implements BaseLink.PackageReceiver {
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(context.getString(R.string.error_timed_out));
}
Log.e("Device","Unpairing (timeout A)");
pairStatus = PairStatus.NotPaired;
}
}, 20*1000);
}, 30*1000); //Time to wait for the other to accept
pairStatus = PairStatus.Requested;
}
@@ -187,6 +195,7 @@ public class Device implements BaseLink.PackageReceiver {
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(context.getString(R.string.error_could_not_send_package));
}
Log.e("Device","Unpairing (sendFailed A)");
pairStatus = PairStatus.NotPaired;
}
@@ -202,6 +211,7 @@ public class Device implements BaseLink.PackageReceiver {
if (!isPaired()) return;
//Log.e("Device","Unpairing (unpair)");
pairStatus = PairStatus.NotPaired;
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
@@ -217,44 +227,70 @@ public class Device implements BaseLink.PackageReceiver {
}
public void acceptPairing() {
private void pairingDone() {
Log.i("Device","Accepted pairing");
//Log.e("Device", "Storing as trusted, deviceId: "+deviceId);
//Send our own public key
NetworkPackage np = NetworkPackage.createPublicKeyPackage(context);
sendPackage(np); //TODO: Set a callback
if (pairingTimer != null) pairingTimer.cancel();
pairStatus = PairStatus.Paired;
//Store as trusted device
String encodedPublicKey = Base64.encodeToString(publicKey.getEncoded(), 0);
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
preferences.edit().putBoolean(deviceId,true).commit();
//Store device information needed to create a Device object in a future
SharedPreferences.Editor editor = settings.edit();
editor.putString("deviceName", getName());
String encodedPublicKey = Base64.encodeToString(publicKey.getEncoded(), 0);
editor.putString("publicKey", encodedPublicKey);
editor.commit();
reloadPluginsFromSettings();
for (PairingCallback cb : pairingCallback) cb.pairingSuccessful();
for (PairingCallback cb : pairingCallback) {
cb.pairingSuccessful();
}
}
public void acceptPairing() {
Log.i("Device","Accepted pair request started by the other device");
//Send our own public key
NetworkPackage np = NetworkPackage.createPublicKeyPackage(context);
sendPackage(np, new SendPackageFinishedCallback() {
@Override
public void sendSuccessful() {
pairingDone();
}
@Override
public void sendFailed() {
Log.e("Device","Unpairing (sendFailed B)");
pairStatus = PairStatus.NotPaired;
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(context.getString(R.string.error_not_reachable));
}
}
});
}
public void rejectPairing() {
Log.i("Device","Rejected pairing");
Log.i("Device","Rejected pair request started by the other device");
//Log.e("Device","Unpairing (rejectPairing)");
pairStatus = PairStatus.NotPaired;
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);
np.set("pair", false);
sendPackage(np);
for (PairingCallback cb : pairingCallback) cb.pairingFailed(context.getString(R.string.error_canceled_by_user));
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(context.getString(R.string.error_canceled_by_user));
}
}
@@ -321,9 +357,12 @@ public class Device implements BaseLink.PackageReceiver {
if (wantsPair == isPaired()) {
if (pairStatus == PairStatus.Requested) {
//Log.e("Device","Unpairing (pair rejected)");
pairStatus = PairStatus.NotPaired;
pairingTimer.cancel();
for (PairingCallback cb : pairingCallback) cb.pairingFailed(context.getString(R.string.error_canceled_by_other_peer));
if (pairingTimer != null) pairingTimer.cancel();
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(context.getString(R.string.error_canceled_by_other_peer));
}
}
return;
}
@@ -338,7 +377,9 @@ public class Device implements BaseLink.PackageReceiver {
} catch(Exception e) {
e.printStackTrace();
Log.e("Device","Pairing exception: Received incorrect key");
for (PairingCallback cb : pairingCallback) cb.pairingFailed(context.getString(R.string.error_invalid_key));
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(context.getString(R.string.error_invalid_key));
}
return;
}
@@ -346,23 +387,9 @@ public class Device implements BaseLink.PackageReceiver {
Log.i("Pairing","Pair answer");
pairStatus = PairStatus.Paired;
pairingTimer.cancel();
if (pairingTimer != null) pairingTimer.cancel();
//Store as trusted device
String encodedPublicKey = Base64.encodeToString(publicKey.getEncoded(), 0);
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
preferences.edit().putBoolean(deviceId,true).commit();
//Store device information needed to create a Device object in a future
SharedPreferences.Editor editor = settings.edit();
editor.putString("deviceName", getName());
editor.putString("publicKey", encodedPublicKey);
editor.commit();
reloadPluginsFromSettings();
for (PairingCallback cb : pairingCallback) cb.pairingSuccessful();
pairingDone();
} else {
@@ -389,15 +416,17 @@ public class Device implements BaseLink.PackageReceiver {
notificationId = (int)System.currentTimeMillis();
notificationManager.notify(notificationId, noti);
if (pairingTimer != null) pairingTimer.cancel();
pairingTimer = new Timer();
pairingTimer.schedule(new TimerTask() {
@Override
public void run() {
Log.e("Device","Unpairing (timeout B)");
pairStatus = PairStatus.NotPaired;
notificationManager.cancel(notificationId);
}
}, 19*1000); //Time to show notification
}, 25*1000); //Time to show notification, waiting for user to accept (peer will timeout in 30 seconds)
pairStatus = PairStatus.RequestedByPeer;
for (PairingCallback cb : pairingCallback) cb.incomingRequest();
@@ -407,13 +436,16 @@ public class Device implements BaseLink.PackageReceiver {
if (pairStatus == PairStatus.Requested) {
pairingTimer.cancel();
for (PairingCallback cb : pairingCallback) cb.pairingFailed(context.getString(R.string.error_canceled_by_other_peer));
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(context.getString(R.string.error_canceled_by_other_peer));
}
} else if (pairStatus == PairStatus.Paired) {
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
preferences.edit().remove(deviceId).commit();
reloadPluginsFromSettings();
}
//Log.e("Device","Unpairing (unpair request)");
pairStatus = PairStatus.NotPaired;
for (PairingCallback cb : pairingCallback) cb.unpaired();
@@ -441,33 +473,44 @@ public class Device implements BaseLink.PackageReceiver {
sendPackage(np,null);
}
//Async
public void sendPackage(final NetworkPackage np, final SendPackageFinishedCallback callback) {
final Exception backtrace = new Exception();
new Thread(new Runnable() {
@Override
public void run() {
//Log.e("sendPackage", "Sending package...");
//Log.e("sendPackage", np.serialize());
boolean useEncryption = (!np.getType().equals(NetworkPackage.PACKAGE_TYPE_PAIR) && isPaired());
//Log.e("sendPackage", "Sending...");
//We need a copy to avoid concurrent modification exception if the original list changes
ArrayList<BaseLink> mLinks = new ArrayList<BaseLink>(links);
for(BaseLink link : links) {
boolean success;
boolean success = false;
for(BaseLink link : mLinks) {
if (useEncryption) {
success = link.sendPackageEncrypted(np, publicKey);
} else {
success = link.sendPackage(np);
}
if (success) {
//Log.e("sendPackage", "Sent");
if (callback != null) callback.sendSuccessful();
return;
}
if (success) break;
}
if (callback != null) callback.sendFailed();
Log.e("sendPackage","Error: Package could not be sent ("+links.size()+" links available)");
if (success) {
// Log.e("sendPackage","Package sent");
} else {
backtrace.printStackTrace();
Log.e("sendPackage","Error: Package could not be sent ("+mLinks.size()+" links available)");
}
if (callback != null) {
if (success) callback.sendSuccessful();
else callback.sendFailed();
}
}
}).start();
@@ -486,7 +529,7 @@ public class Device implements BaseLink.PackageReceiver {
return plugins.get(name);
}
private void addPlugin(final String name) {
private synchronized void addPlugin(final String name) {
Plugin existing = plugins.get(name);
if (existing != null) {
Log.w("addPlugin","plugin already present:" + name);
@@ -532,7 +575,7 @@ public class Device implements BaseLink.PackageReceiver {
}
private boolean removePlugin(String name) {
private synchronized boolean removePlugin(String name) {
Plugin plugin = plugins.remove(name);
Plugin failedPlugin = failedPlugins.remove(name);

View File

@@ -35,10 +35,13 @@ public class ContactsHelper {
if (nameIndex != -1) {
String name = cursor.getString(nameIndex);
//Log.e("PhoneNumberLookup", "success: " + name);
return name;
cursor.close();
return name + " (" + number + ")";
}
}
if (cursor != null) cursor.close();
return number;
}

View File

@@ -1,10 +1,12 @@
package org.kde.kdeconnect;
package org.kde.kdeconnect.Helpers;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import java.util.HashMap;
public class HumanDeviceNames {
public class DeviceHelper {
//from https://github.com/meetup/android-device-names
//Converted to java using:
@@ -154,7 +156,7 @@ public class HumanDeviceNames {
humanReadableNames.put("XT907","Motorola Droid Razr M");
}
static String getDeviceName() {
public static String getDeviceName() {
String dictName = humanReadableNames.get(Build.MODEL.replace(' ','_'));
if (dictName != null) return dictName;
@@ -167,4 +169,11 @@ public class HumanDeviceNames {
}
public static boolean isTablet() {
Configuration config = Resources.getSystem().getConfiguration();
//This assumes that the values for the screen sizes are consecutive, so XXLARGE > XLARGE > LARGE
boolean isLarge = ((config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE);
return isLarge;
}
}

View File

@@ -10,11 +10,11 @@ import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.kde.kdeconnect.Helpers.DeviceHelper;
import org.kde.kdeconnect.UserInterface.MainSettingsActivity;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -26,12 +26,14 @@ public class NetworkPackage {
public final static int ProtocolVersion = 5;
//TODO: Move these to their respective plugins
public final static String PACKAGE_TYPE_IDENTITY = "kdeconnect.identity";
public final static String PACKAGE_TYPE_PAIR = "kdeconnect.pair";
public final static String PACKAGE_TYPE_ENCRYPTED = "kdeconnect.encrypted";
public final static String PACKAGE_TYPE_PING = "kdeconnect.ping";
public final static String PACKAGE_TYPE_TELEPHONY = "kdeconnect.telephony";
public final static String PACKAGE_TYPE_BATTERY = "kdeconnect.battery";
public final static String PACKAGE_TYPE_SFTP = "kdeconnect.sftp";
public final static String PACKAGE_TYPE_NOTIFICATION = "kdeconnect.notification";
public final static String PACKAGE_TYPE_CLIPBOARD = "kdeconnect.clipboard";
public final static String PACKAGE_TYPE_MPRIS = "kdeconnect.mpris";
@@ -74,6 +76,9 @@ public class NetworkPackage {
public double getDouble(String key) { return mBody.optDouble(key,Double.NaN); }
public double getDouble(String key, double defaultValue) { return mBody.optDouble(key,defaultValue); }
public void set(String key, double value) { try { mBody.put(key,value); } catch(Exception e) { } }
public JSONArray getJSONArray(String key) { return mBody.optJSONArray(key); }
public void set(String key, JSONArray value) { try { mBody.put(key,value); } catch(Exception e) { } }
public ArrayList<String> getStringList(String key) {
JSONArray jsonArray = mBody.optJSONArray(key);
ArrayList<String> list = new ArrayList<String>();
@@ -103,7 +108,6 @@ public class NetworkPackage {
}
}
public boolean has(String key) { return mBody.has(key); }
public boolean isEncrypted() { return mType.equals(PACKAGE_TYPE_ENCRYPTED); }
@@ -161,7 +165,7 @@ public class NetworkPackage {
return np;
}
public void encrypt(PublicKey publicKey) throws Exception {
public NetworkPackage encrypt(PublicKey publicKey) throws Exception {
String serialized = serialize();
@@ -183,17 +187,11 @@ public class NetworkPackage {
chunks.put(Base64.encodeToString(encryptedChunk, Base64.NO_WRAP));
}
mId = System.currentTimeMillis();
mType = NetworkPackage.PACKAGE_TYPE_ENCRYPTED;
mBody = new JSONObject();
try {
mBody.put("data", chunks);
}catch(Exception e){
e.printStackTrace();
Log.e("NetworkPackage","Exception");
}
//Log.i("NetworkPackage", "Encrypted " + chunks.length()+" chunks");
Log.i("NetworkPackage", "Encrypted " + chunks.length()+" chunks");
NetworkPackage encrypted = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_ENCRYPTED);
encrypted.set("data", chunks);
return encrypted;
}
@@ -221,15 +219,22 @@ public class NetworkPackage {
String deviceId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
try {
np.mBody.put("deviceId", deviceId);
np.mBody.put("deviceName", HumanDeviceNames.getDeviceName());
np.mBody.put("deviceName",
PreferenceManager.getDefaultSharedPreferences(context).getString(
MainSettingsActivity.KEY_DEVICE_NAME_PREFERENCE,
DeviceHelper.getDeviceName()));
np.mBody.put("protocolVersion", NetworkPackage.ProtocolVersion);
} catch (JSONException e) {
np.mBody.put("deviceType", DeviceHelper.isTablet()? "tablet" : "phone");
} catch (Exception e) {
e.printStackTrace();
Log.e("NetworkPacakge","Exception on createIdentityPackage");
}
return np;
}
static public NetworkPackage createPublicKeyPackage(Context context) {
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);

View File

@@ -17,9 +17,11 @@ import org.kde.kdeconnect_tp.R;
public class BatteryPlugin extends Plugin {
private NetworkPackage lastPackage = null;
// keep these fields in sync with kdeconnect-kded:BatteryPlugin.h:ThresholdBatteryEvent
private static final int THRESHOLD_EVENT_NONE= 0;
private static final int THRESHOLD_EVENT_BATTERY_LOW = 1;
private IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
NetworkPackage lastInfo = null;
/*static {
PluginFactory.registerPlugin(BatteryPlugin.class);
@@ -50,36 +52,36 @@ public class BatteryPlugin extends Plugin {
return true;
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
public void onReceive(Context context, Intent batteryIntent) {
Log.i("BatteryPlugin", "Battery event");
Intent batteryChargeIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryChargeIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryChargeIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 1);
int currentCharge = level*100 / scale;
boolean isCharging = (0 != batteryChargeIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
boolean lowBattery = Intent.ACTION_BATTERY_LOW.equals(batteryIntent.getAction());
int thresholdEvent = lowBattery? THRESHOLD_EVENT_BATTERY_LOW : THRESHOLD_EVENT_NONE;
boolean isCharging = (0 != intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0));
int currentCharge = 100;
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
if (status != BatteryManager.BATTERY_STATUS_FULL) {
Intent batteryStatus = context.registerReceiver(null, filter);
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
currentCharge = level*100 / scale;
}
//Only notify if change is meaningful enough
if (lastPackage == null
|| (
isCharging != lastPackage.getBoolean("isCharging")
|| currentCharge != lastPackage.getInt("currentCharge")
)
if (lastInfo != null
&& isCharging != lastInfo.getBoolean("isCharging")
&& currentCharge != lastInfo.getInt("currentCharge")
&& thresholdEvent != lastInfo.getInt("thresholdEvent")
) {
//Do not send again if nothing has changed
return;
} else {
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_BATTERY);
np.set("isCharging", isCharging);
np.set("currentCharge", currentCharge);
np.set("isCharging", isCharging);
np.set("thresholdEvent", thresholdEvent);
device.sendPackage(np);
lastPackage = np;
lastInfo = np;
}
}
@@ -87,12 +89,14 @@ public class BatteryPlugin extends Plugin {
@Override
public boolean onCreate() {
context.registerReceiver(receiver, filter);
context.registerReceiver(receiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
context.registerReceiver(receiver, new IntentFilter(Intent.ACTION_BATTERY_LOW));
return true;
}
@Override
public void onDestroy() {
//It's okay to call this only once, even though we registered it for two filters
context.unregisterReceiver(receiver);
}
@@ -101,8 +105,8 @@ public class BatteryPlugin extends Plugin {
if (!np.getType().equals(NetworkPackage.PACKAGE_TYPE_BATTERY)) return false;
if (np.getBoolean("request")) {
if (lastPackage != null) {
device.sendPackage(lastPackage);
if (lastInfo != null) {
device.sendPackage(lastInfo);
}
}

View File

@@ -10,12 +10,18 @@ import org.kde.kdeconnect.NetworkPackage;
public class ClipboardListener {
private Context context;
private String currentContent;
private ClipboardManager cm = null;
ClipboardManager.OnPrimaryClipChangedListener listener;
ClipboardListener(final Context context, final Device device) {
ClipboardListener(final Context ctx, final Device device) {
context = ctx;
if(android.os.Build.VERSION.SDK_INT < 11) {
return;
}
cm = (ClipboardManager)context.getSystemService(Context.CLIPBOARD_SERVICE);
listener = new ClipboardManager.OnPrimaryClipChangedListener() {
@Override
@@ -41,12 +47,24 @@ public class ClipboardListener {
}
public void stop() {
if(android.os.Build.VERSION.SDK_INT < 11) {
return;
}
cm.removePrimaryClipChangedListener(listener);
}
@SuppressWarnings("deprecation")
public void setText(String text) {
currentContent = text;
cm.setText(text);
if(android.os.Build.VERSION.SDK_INT < 11) {
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(text);
}
else
{
cm.setText(text);
}
}
}

View File

@@ -5,7 +5,6 @@ import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.widget.Button;
import org.kde.kdeconnect.NetworkPackage;
@@ -39,31 +38,21 @@ public class ClipboardPlugin extends Plugin {
@Override
public boolean isEnabledByDefault() {
return (Build.VERSION.SDK_INT >= 11);
//Disabled by default due to just one direction sync(incoming clipboard change) in early version of android.
return (android.os.Build.VERSION.SDK_INT >= 11);
}
private ClipboardListener listener;
@Override
public boolean onCreate() {
if (Build.VERSION.SDK_INT < 11) {
return false;
}
listener = new ClipboardListener(context, device);
return true;
}
@Override
public void onDestroy() {
if (Build.VERSION.SDK_INT < 11) return;
listener.stop();
}
@Override
@@ -76,7 +65,6 @@ public class ClipboardPlugin extends Plugin {
String content = np.getString("content");
listener.setText(content);
return true;
}
@Override

View File

@@ -93,8 +93,12 @@ public class MprisActivity extends Activity {
//Spotify doesn't support changing the volume yet...
if (player.equals("Spotify")) {
findViewById(R.id.volume_layout).setVisibility(View.INVISIBLE);
findViewById(R.id.rew_button).setVisibility(View.GONE);
findViewById(R.id.ff_button).setVisibility(View.GONE);
} else {
findViewById(R.id.volume_layout).setVisibility(View.VISIBLE);
findViewById(R.id.rew_button).setVisibility(View.VISIBLE);
findViewById(R.id.ff_button).setVisibility(View.VISIBLE);
}
}
@@ -187,6 +191,36 @@ public class MprisActivity extends Activity {
}
});
findViewById(R.id.rew_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId);
MprisPlugin mpris = (MprisPlugin)device.getPlugin("plugin_mpris");
if (mpris == null) return;
mpris.Seek(-10000000); // -10 seconds. TODO: plugin settings UI?
}
});
}
});
findViewById(R.id.ff_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
BackgroundService.RunCommand(MprisActivity.this, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId);
MprisPlugin mpris = (MprisPlugin)device.getPlugin("plugin_mpris");
if (mpris == null) return;
mpris.Seek(10000000); // 10 seconds. TODO: plugin settings UI?
}
});
}
});
findViewById(R.id.next_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {

View File

@@ -84,6 +84,13 @@ public class MprisPlugin extends Plugin {
device.sendPackage(np);
}
public void Seek(int offset) {
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_MPRIS);
np.set("player",player);
np.set("Seek",offset);
device.sendPackage(np);
}
@Override
public boolean onPackageReceived(NetworkPackage np) {
if (!np.getType().equals(NetworkPackage.PACKAGE_TYPE_MPRIS)) return false;

View File

@@ -27,7 +27,7 @@ public class NotificationReceiver extends NotificationListenerService {
@Override
public void onNotificationPosted(StatusBarNotification statusBarNotification) {
Log.i("NotificationReceiver.onNotificationPosted","listeners: " + listeners.size());
//Log.e("NotificationReceiver.onNotificationPosted","listeners: " + listeners.size());
for(NotificationListener listener : listeners) {
listener.onNotificationPosted(statusBarNotification);
}
@@ -49,7 +49,7 @@ public class NotificationReceiver extends NotificationListenerService {
//This will be called for each intent launch, even if the service is already started and is reused
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("NotificationReceiver", "onStartCommand");
//Log.e("NotificationReceiver", "onStartCommand");
for (InstanceCallback c : callbacks) {
c.onServiceStart(this);
}

View File

@@ -126,12 +126,10 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
public void onServiceStart(NotificationReceiver service) {
try {
service.addListener(NotificationsPlugin.this);
/*
StatusBarNotification[] notifications = service.getActiveNotifications();
for (StatusBarNotification notification : notifications) {
onNotificationPosted(notification);
sendNotification(notification, true);
}
*/
} catch(Exception e) {
e.printStackTrace();
Log.e("NotificationsPlugin","Exception");
@@ -178,6 +176,13 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
public void sendNotification(StatusBarNotification statusBarNotification, boolean requestAnswer) {
Notification notification = statusBarNotification.getNotification();
if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0
|| (notification.flags & Notification.FLAG_ONGOING_EVENT) != 0 ) {
//This is not a notification!
return;
}
NotificationId id = NotificationId.fromNotification(statusBarNotification);
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_NOTIFICATION);
@@ -204,7 +209,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
np.set("id", id.serialize());
np.set("appName", appName == null? packageName : appName);
np.set("isClearable", statusBarNotification.isClearable());
np.set("ticker", notification.tickerText.toString());
np.set("ticker", (notification != null && notification.tickerText != null)? notification.tickerText.toString() : "");
np.set("time", Long.toString(statusBarNotification.getPostTime()));
if (requestAnswer) np.set("requestAnswer", true);

View File

@@ -4,14 +4,18 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.view.View;
import android.widget.Button;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.UserInterface.MainActivity;
import org.kde.kdeconnect_tp.R;
@@ -63,9 +67,18 @@ public class PingPlugin extends Plugin {
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_PING)) {
//Log.e("PingPackageReceiver", "was a ping!");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(new Intent(context, MainActivity.class));
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
Notification noti = new NotificationCompat.Builder(context)
.setContentTitle(device.getName())
.setContentText("Ping!")
.setContentIntent(resultPendingIntent)
.setTicker("Ping!")
.setSmallIcon(android.R.drawable.ic_dialog_alert)
.setAutoCancel(true)

View File

@@ -7,6 +7,7 @@ import android.util.Log;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.Plugins.BatteryPlugin.BatteryPlugin;
import org.kde.kdeconnect.Plugins.SftpPlugin.SftpPlugin;
import org.kde.kdeconnect.Plugins.ClibpoardPlugin.ClipboardPlugin;
import org.kde.kdeconnect.Plugins.MprisPlugin.MprisPlugin;
import org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationsPlugin;
@@ -67,6 +68,7 @@ public class PluginFactory {
PluginFactory.registerPlugin(MprisPlugin.class);
PluginFactory.registerPlugin(ClipboardPlugin.class);
PluginFactory.registerPlugin(BatteryPlugin.class);
PluginFactory.registerPlugin(SftpPlugin.class);
PluginFactory.registerPlugin(NotificationsPlugin.class);
}

View File

@@ -0,0 +1,210 @@
package org.kde.kdeconnect.Plugins.SftpPlugin;
import android.content.Context;
import android.util.Log;
import org.apache.http.conn.util.InetAddressUtils;
import org.apache.sshd.SshServer;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.Session;
import org.apache.sshd.server.Command;
import org.apache.sshd.server.FileSystemFactory;
import org.apache.sshd.server.FileSystemView;
import org.apache.sshd.server.PasswordAuthenticator;
import org.apache.sshd.server.PublickeyAuthenticator;
import org.apache.sshd.server.SshFile;
import org.apache.sshd.server.command.ScpCommandFactory;
import org.apache.sshd.server.filesystem.NativeFileSystemView;
import org.apache.sshd.server.filesystem.NativeSshFile;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.sftp.SftpSubsystem;
import org.kde.kdeconnect.Device;
import java.io.File;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
class SimplePasswordAuthenticator implements PasswordAuthenticator {
public void setUser(String user) {this.user = user;}
public String getUser() {return this.user;}
public void setPassword(String password) {this.password = password;}
public String getPassword() {return this.password;}
@Override
public boolean authenticate(String user, String password, ServerSession session) {
return user.equals(this.user) && password.equals(this.password);
}
private String user;
private String password;
}
class SimplePublicKeyAuthenticator implements PublickeyAuthenticator {
private List<PublicKey> keys = new ArrayList<PublicKey>();
public void addKey(PublicKey key) {
keys.add(key);
}
@Override
public boolean authenticate(String user, PublicKey key, ServerSession session) {
for (PublicKey k : keys) {
if (key.equals(k)) {
return true;
}
}
return false;
}
}
class SimpleSftpServer {
private static final int STARTPORT = 1739;
private static final int ENDPORT = 1764;
private static final String USER = "kdeconnect";
public static int port = -1;
private static boolean started = false;
public final SimplePasswordAuthenticator passwordAuth = new SimplePasswordAuthenticator();
public final SimplePublicKeyAuthenticator keyAuth = new SimplePublicKeyAuthenticator();
private final SshServer sshd = SshServer.setUpDefaultServer();
public void init(Context ctx, Device device) {
passwordAuth.setUser(USER);
keyAuth.addKey(device.publicKey);
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(ctx.getFilesDir() + "/sftpd.ser"));
//sshd.setFileSystemFactory(new NativeFileSystemFactory());
sshd.setFileSystemFactory(new SecureFileSystemFactory());
//sshd.setShellFactory(new ProcessShellFactory(new String[] { "/bin/sh", "-i", "-l" }));
sshd.setCommandFactory(new ScpCommandFactory());
sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()));
sshd.setPasswordAuthenticator(passwordAuth);
sshd.setPublickeyAuthenticator(keyAuth);
}
public boolean start() {
if (!started) {
String password = Long.toHexString(Double.doubleToLongBits(Math.random()));
passwordAuth.setPassword(password);
port = STARTPORT;
while(!started) {
try {
sshd.setPort(port);
sshd.start();
started = true;
} catch(Exception e) {
port++;
if (port >= ENDPORT) {
port = -1;
Log.e("SftpServer", "No more ports available");
return false;
}
}
}
}
return true;
}
public void stop() {
try {
started = false;
sshd.stop();
} catch (InterruptedException e) {
}
}
public String getLocalIpAddress() {
String ip6 = null;
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
String address = inetAddress.getHostAddress();
if (InetAddressUtils.isIPv4Address(address)) { //Prefer IPv4 over IPv6, because sshfs doesn't seem to like IPv6
return address;
} else {
ip6 = address;
}
}
}
}
} catch (SocketException ex) {
}
return ip6;
}
}
class SecureFileSystemFactory implements FileSystemFactory {
public SecureFileSystemFactory() {}
@Override
public FileSystemView createFileSystemView(final Session username) {
final String base = "/";
return new SecureFileSystemView(base, username.getUsername());
}
}
class SecureFileSystemView extends NativeFileSystemView {
// the first and the last character will always be '/'
// It is always with respect to the root directory.
private String currDir = "/";
private String rootDir = "/";
private String userName;
private boolean caseInsensitive = false;
//
public SecureFileSystemView(final String rootDir, final String userName) {
super(userName);
this.rootDir = NativeSshFile.normalizeSeparateChar(rootDir);
this.userName = userName;
}
//
@Override
public SshFile getFile(final String file) {
return getFile(currDir, file);
}
@Override
public SshFile getFile(final SshFile baseDir, final String file) {
return getFile(baseDir.getAbsolutePath(), file);
}
//
protected SshFile getFile(final String dir, final String file) {
// get actual file object
String physicalName = NativeSshFile.getPhysicalName("/", dir, file, caseInsensitive);
File fileObj = new File(rootDir, physicalName); // chroot
// strip the root directory and return
String userFileName = physicalName.substring("/".length() - 1);
return new SecureSshFile(this, userFileName, fileObj, userName);
}
}
class SecureSshFile extends NativeSshFile {
//
public SecureSshFile(final SecureFileSystemView view, final String fileName, final File file, final String userName) {
super(fileName, file, userName);
}
}

View File

@@ -0,0 +1,79 @@
package org.kde.kdeconnect.Plugins.SftpPlugin;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.widget.Button;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect_tp.R;
public class SftpPlugin extends Plugin {
private static final SimpleSftpServer server = new SimpleSftpServer();
/*static {
PluginFactory.registerPlugin(SftpPlugin.class);
}*/
@Override
public String getPluginName() {return "plugin_sftp";}
@Override
public String getDisplayName() {
return context.getResources().getString(R.string.pref_plugin_sftp);
}
@Override
public String getDescription() {
return context.getResources().getString(R.string.pref_plugin_sftp_desc);
}
@Override
public Drawable getIcon() {
return context.getResources().getDrawable(R.drawable.icon);
}
@Override
public boolean isEnabledByDefault() {return true;}
@Override
public boolean onCreate() {
server.init(context, device);
return true;
}
@Override
public void onDestroy() {
server.stop();
}
@Override
public boolean onPackageReceived(NetworkPackage np) {
if (!np.getType().equals(NetworkPackage.PACKAGE_TYPE_SFTP)) return false;
if (np.getBoolean("startBrowsing")) {
if (server.start()) {
NetworkPackage np2 = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_SFTP);
np2.set("ip", server.getLocalIpAddress());
np2.set("port", server.port);
np2.set("user", server.passwordAuth.getUser());
np2.set("password", server.passwordAuth.getPassword());
np2.set("path", Environment.getExternalStorageDirectory().getAbsolutePath());
device.sendPackage(np2);
return true;
}
}
return false;
}
@Override
public AlertDialog getErrorDialog(Context baseContext) {return null;}
@Override
public Button getInterfaceButton(Activity activity) {return null;}
}

View File

@@ -96,6 +96,8 @@ public class TelephonyPlugin extends Plugin {
public void callBroadcastReceived(int state, String phoneNumber) {
//Log.e("TelephonyPlugin", "callBroadcastReceived");
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_TELEPHONY);
if (phoneNumber != null) {
phoneNumber = ContactsHelper.phoneNumberLookup(context,phoneNumber);
@@ -162,6 +164,7 @@ public class TelephonyPlugin extends Plugin {
@Override
public boolean onCreate() {
//Log.e("TelephonyPlugin", "onCreate");
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
context.registerReceiver(receiver, filter);

View File

@@ -24,11 +24,12 @@ import org.kde.kdeconnect_tp.R;
import java.util.ArrayList;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
public class DeviceActivity extends ActionBarActivity {
private String deviceId;
static private String deviceId; //Static because if we get here by using the back button in the action bar, the extra deviceId will not be set.
private Device device;
private Device.PluginsChangedListener pluginsChangedListener = new Device.PluginsChangedListener() {
@@ -58,23 +59,30 @@ public class DeviceActivity extends ActionBarActivity {
errorList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
Plugin p = failedPlugins.get(ids[position - 1]); //Header is position 0, so we have to substract one
Plugin p = failedPlugins.get(ids[position - 1]); //Header is position 0, so we have to subtract one
p.getErrorDialog(DeviceActivity.this).show();
}
});
//Buttons list
ArrayList<ListAdapter.Item> items = new ArrayList<ListAdapter.Item>();
final Collection<Plugin> plugins = device.getLoadedPlugins().values();
for (Plugin p : plugins) {
Button b = p.getInterfaceButton(DeviceActivity.this);
if (b != null) {
items.add(new SectionItem(p.getDisplayName()));
items.add(new ButtonItem(b));
try {
//Buttons list
ArrayList<ListAdapter.Item> items = new ArrayList<ListAdapter.Item>();
final Collection<Plugin> plugins = device.getLoadedPlugins().values();
for (Plugin p : plugins) {
Button b = p.getInterfaceButton(DeviceActivity.this);
if (b != null) {
items.add(new SectionItem(p.getDisplayName()));
items.add(new ButtonItem(b));
}
}
ListView buttonsList = (ListView)findViewById(R.id.buttons_list);
buttonsList.setAdapter(new ListAdapter(DeviceActivity.this, items));
} catch(ConcurrentModificationException e) {
Log.e("DeviceActivity", "ConcurrentModificationException");
this.run(); //Try again
}
ListView buttonsList = (ListView)findViewById(R.id.buttons_list);
buttonsList.setAdapter(new ListAdapter(DeviceActivity.this, items));
}
});
@@ -91,12 +99,15 @@ public class DeviceActivity extends ActionBarActivity {
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE);
actionBar.setDisplayHomeAsUpEnabled(true);
deviceId = getIntent().getStringExtra("deviceId");
if (getIntent().hasExtra("deviceId")) {
deviceId = getIntent().getStringExtra("deviceId");
}
BackgroundService.RunCommand(DeviceActivity.this, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
device = service.getDevice(deviceId);
if (device == null) return;
setTitle(device.getName());
device.addPluginsChangedListener(pluginsChangedListener);
pluginsChangedListener.onPluginsChanged(device);

View File

@@ -10,7 +10,7 @@ public class SectionItem implements ListAdapter.Item {
private final String title;
public boolean isEmpty;
public SectionItem(String title) {
this.title = title;
this.isEmpty = false;

View File

@@ -1,6 +1,7 @@
package org.kde.kdeconnect.UserInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
@@ -66,6 +67,9 @@ public class MainActivity extends ActionBarActivity {
}
}).start();
break;
case R.id.menu_settings:
startActivity(new Intent(this,MainSettingsActivity.class));
break;
default:
break;
}
@@ -79,7 +83,6 @@ public class MainActivity extends ActionBarActivity {
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
}

View File

@@ -0,0 +1,103 @@
package org.kde.kdeconnect.UserInterface;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import org.kde.kdeconnect.Helpers.DeviceHelper;
import org.kde.kdeconnect_tp.R;
public class MainSettingsActivity extends PreferenceActivity{
public static final String KEY_DEVICE_NAME_PREFERENCE = "device_name_preference";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initializeDeviceName(this);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
addPreferencesOldApi();
} else {
getFragmentManager().beginTransaction().
replace(android.R.id.content, new GeneralPrefsFragment()).commit();
}
}
@SuppressWarnings("deprecation")
private void addPreferencesOldApi() {
addPreferencesFromResource(R.xml.general_preferences);
initPreferences((EditTextPreference) findPreference(KEY_DEVICE_NAME_PREFERENCE));
}
private void initPreferences(final EditTextPreference deviceNamePref) {
final SharedPreferences sharedPreferences=PreferenceManager.getDefaultSharedPreferences(this);
deviceNamePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newDeviceName) {
if (newDeviceName.toString().isEmpty()) {
Toast.makeText(
MainSettingsActivity.this,
getString(R.string.invalid_device_name),
Toast.LENGTH_SHORT).show();
return false;
}else{
Log.i("MainSettingsActivity", "New device name: " + newDeviceName);
deviceNamePref.setSummary(getString(
R.string.device_name_preference_summary,
newDeviceName.toString()));
return true;
}
}
});
deviceNamePref.setSummary(getString(
R.string.device_name_preference_summary,
sharedPreferences.getString(KEY_DEVICE_NAME_PREFERENCE,"")));
}
/**
* Until now it sets only the default deviceName (if not already set).
* It's safe to call this multiple time because doesn't override any previous value.
* @param context
*/
public static void initializeDeviceName(Context context){
// I could have used getDefaultSharedPreferences(context).contains but we need to check
// to checkAgainst empty String also.
String deviceName=PreferenceManager.getDefaultSharedPreferences(context).getString(
KEY_DEVICE_NAME_PREFERENCE,
"");
if(deviceName.isEmpty()){
Log.i("MainSettingsActivity", "New device name: " + deviceName);
PreferenceManager.getDefaultSharedPreferences(context).edit().putString(
KEY_DEVICE_NAME_PREFERENCE,
DeviceHelper.getDeviceName()).commit();
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class GeneralPrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.general_preferences);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (getActivity() != null) {
((MainSettingsActivity)getActivity()).initPreferences(
(EditTextPreference) findPreference(KEY_DEVICE_NAME_PREFERENCE));
}
}
}
}

View File

@@ -24,6 +24,7 @@ import org.kde.kdeconnect.UserInterface.List.ListAdapter;
import org.kde.kdeconnect.UserInterface.List.SectionItem;
import org.kde.kdeconnect_tp.R;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
@@ -175,38 +176,62 @@ public class ShareToReceiver extends ActionBarActivity {
InputStream inputStream = cr.openInputStream(uri);
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_SHARE);
String[] proj = { MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.SIZE, MediaStore.MediaColumns.DISPLAY_NAME };
Cursor cursor = managedQuery(uri, proj, null, null, null);
int size = -1;
try {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.SIZE);
cursor.moveToFirst();
size = cursor.getInt(column_index);
} catch(Exception e) {
e.printStackTrace();
Log.e("ShareToReceiver", "Could not obtain file size");
}
//Log.e("ShareToReceiver", "Size "+size);
np.setPayload(inputStream, size);
if (uri.getScheme().equals("file")) {
// file:// is a non media uri, so we cannot query the ContentProvider
np.set("filename", uri.getLastPathSegment());
try {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
cursor.moveToFirst();
String path = cursor.getString(column_index);
np.set("filename", Uri.parse(path).getLastPathSegment());
} catch(Exception _) {
try {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME);
cursor.moveToFirst();
String name = cursor.getString(column_index);
np.set("filename", name);
} catch (Exception e) {
size = (int)new File(uri.getPath()).length();
np.setPayload(inputStream, size);
} catch(Exception e) {
e.printStackTrace();
Log.e("ShareToReceiver", "Could not obtain file name");
Log.e("ShareToReceiver", "Could not obtain file size");
}
}else{
// Probably a content:// uri, so we query the Media content provider
Cursor cursor = null;
try {
String[] proj = { MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.SIZE, MediaStore.MediaColumns.DISPLAY_NAME };
cursor = getContentResolver().query(uri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA);
cursor.moveToFirst();
String path = cursor.getString(column_index);
np.set("filename", Uri.parse(path).getLastPathSegment());
np.set("size", (int)new File(path).length());
} catch(Exception _) {
Log.e("ShareToReceiver", "Could not resolve media to a file, trying to get info as media");
try {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME);
cursor.moveToFirst();
String name = cursor.getString(column_index);
np.set("filename", name);
} catch (Exception e) {
e.printStackTrace();
Log.e("ShareToReceiver", "Could not obtain file name");
}
try {
int column_index = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.SIZE);
cursor.moveToFirst();
//For some reason this size can differ from the actual file size!
size = cursor.getInt(column_index);
} catch(Exception e) {
e.printStackTrace();
Log.e("ShareToReceiver", "Could not obtain file size");
}
} finally {
cursor.close();
}
np.setPayload(inputStream, size);
}
device.sendPackage(np, new Device.SendPackageFinishedCallback() {
@@ -218,12 +243,13 @@ public class ShareToReceiver extends ActionBarActivity {
@Override
public void sendFailed() {
Log.e("ShareToReceiver", "Failed to send attachment");
Log.e("ShareToReceiver", "Failed to send file");
}
});
} catch (Exception e) {
e.printStackTrace();
Log.e("ShareToReceiver", "Failed to send attachment");
Log.e("ShareToReceiver", "Exception sending files");
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:baselineAligned="false"
android:layout_height="wrap_content"

View File

@@ -37,7 +37,7 @@
<LinearLayout
android:orientation="horizontal"
android:layout_width="200dip"
android:layout_height="70dip"
android:layout_height="50dip"
android:layout_gravity="center"
>
@@ -45,19 +45,36 @@
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/prev_button"
android:src="@android:drawable/ic_media_rew"
android:src="@android:drawable/ic_media_previous"
android:contentDescription="@string/mpris_previous"
android:layout_weight="0.5"
android:layout_weight="0.25"
/>
<ImageButton
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/rew_button"
android:src="@android:drawable/ic_media_rew"
android:contentDescription="@string/mpris_rew"
android:layout_weight="0.25"
/>
<ImageButton
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/ff_button"
android:src="@android:drawable/ic_media_ff"
android:contentDescription="@string/mpris_ff"
android:layout_weight="0.25"
/>
<ImageButton
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/next_button"
android:src="@android:drawable/ic_media_ff"
android:layout_gravity="center"
android:src="@android:drawable/ic_media_next"
android:contentDescription="@string/mpris_next"
android:layout_weight="0.5"
android:layout_weight="0.25"
/>
</LinearLayout>
@@ -77,7 +94,7 @@
android:layout_weight="1"
android:layout_gravity="left|center_vertical"
android:contentDescription="@string/mpris_volume"
android:src="@drawable/volume"
android:src="@drawable/ic_volume"
/>
@@ -107,4 +124,4 @@
android:src="@android:drawable/ic_media_stop"
android:layout_gravity="center"/>
-->
</LinearLayout>
</LinearLayout>

View File

@@ -1,9 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:kdeconnect="http://schemas.android.com/apk/res-auto">
xmlns:kdeconnect="http://schemas.android.com/apk/res-auto/android">
<item
android:id="@+id/menu_refresh"
android:icon="@drawable/navigation_refresh"
android:icon="@drawable/ic_action_refresh"
android:orderInCategory="200"
kdeconnect:showAsAction="always"
android:title="@string/reconnect"
@@ -11,11 +11,17 @@
<item
android:id="@+id/menu_progress"
android:icon="@drawable/navigation_refresh"
android:orderInCategory="200"
android:visible="false"
kdeconnect:showAsAction="always"
kdeconnect:actionViewClass="android.widget.ProgressBar"
/>
<item
android:id="@+id/menu_settings"
android:icon="@drawable/ic_action_settings"
android:orderInCategory="300"
android:title="@string/settings"
kdeconnect:showAsAction="never"
/>
</menu>

View File

@@ -0,0 +1,8 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_battery">Baterijski izvještaj</string>
<string name="pref_plugin_battery_desc">Periodično javi baterijski status</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Šalji i primaj ping-ove</string>
<string name="pref_plugin_notifications">Sinhronizovano obavještenje</string>
</resources>

View File

@@ -0,0 +1,33 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_battery">Hlášení baterie</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Posílat a přijímat ping</string>
<string name="device_list_empty">Žádná zařízení</string>
<string name="ok">OK</string>
<string name="cancel">Zrušit</string>
<string name="open_settings">Otevřít nastavení</string>
<string name="send_ping">Poslat ping</string>
<string name="category_connected_devices">Připojená zařízení</string>
<string name="category_not_paired_devices">Nespárovaná zařízení</string>
<string name="category_remembered_devices">Zapamatovaná zařízení</string>
<string name="device_menu_plugins">Vyberte moduly</string>
<string name="unknown_device">Neznámé zařízení</string>
<string name="error_timed_out">Čas vypršel</string>
<string name="error_canceled_by_user">Přerušeno uživatelem</string>
<string name="reconnect">Znovu připojit</string>
<string name="pairing_accept">Přijmout</string>
<string name="pairing_reject">Odmítnout</string>
<string name="device">Zařízení</string>
<string name="remote_control">Vzdálené ovládání</string>
<string name="mpris_play">Přehrát</string>
<string name="mpris_previous">Předchozí</string>
<string name="mpris_rew">Přetočit zpět</string>
<string name="mpris_ff">Rychle vpřed</string>
<string name="mpris_next">Následující</string>
<string name="mpris_volume">Hlasitost</string>
<string name="general_settings">Obecná nastavení</string>
<string name="device_name">Název zařízení</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Neplatný název zařízení</string>
</resources>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Telefonibekendtgørelse</string>
<string name="pref_plugin_telephony_desc">Send bekendtgørelser om SMS\'er og opkald</string>
<string name="pref_plugin_battery">Batterirapport</string>
<string name="pref_plugin_battery_desc">Rapportér batteristatus periodisk</string>
<string name="pref_plugin_clipboard">Synk. af udklipsholder</string>
<string name="pref_plugin_clipboard_desc">Del indholdet af udklipsholderen</string>
<string name="pref_plugin_mpris">Fjernbetjening af multimedie</string>
<string name="pref_plugin_mpris_desc">Styr lyd og video fra din telefon</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Send og modtag ping</string>
<string name="pref_plugin_notifications">Synk. af bekendtgørelser</string>
<string name="pref_plugin_notifications_desc">Tilgå dine bekendtgørelser fra andre enheder</string>
<string name="plugin_not_available">Denne funktion er ikke tilgængelig i din Android-version</string>
<string name="device_list_empty">Ingen enheder</string>
<string name="ok">O.k.</string>
<string name="cancel">Annullér</string>
<string name="open_settings">Åbn indstillinger</string>
<string name="no_permissions">Du skal give tilladelse for at tilgå bekendtgørelser</string>
<string name="send_ping">Send ping</string>
<string name="open_mpris_controls">Åbn fjernbetjening</string>
<string name="category_connected_devices">Forbundne enheder</string>
<string name="category_not_paired_devices">Ikke parrede enheder</string>
<string name="category_remembered_devices">Huskede enheder</string>
<string name="plugins_failed_to_load">Plugins kunne ikke indlæses (tap for mere info):</string>
<string name="device_menu_plugins">Vælg plugins</string>
<string name="device_menu_unpair">Fjern parring</string>
<string name="unknown_device">Ukendt enhed</string>
<string name="error_not_reachable">Enheden kan ikke nås</string>
<string name="error_already_requested">Allerede anmodet om parring</string>
<string name="error_already_paired">Enhed allerede parret</string>
<string name="error_could_not_send_package">Kunne ikke sende pakke</string>
<string name="error_timed_out">Tidsudløb</string>
<string name="error_canceled_by_user">Annulleret af brugeren</string>
<string name="error_canceled_by_other_peer">Annulleret af modpart</string>
<string name="error_invalid_key">Ugyldige nøgle modtaget</string>
<string name="pair_requested">Anmodet om parring</string>
<string name="pairing_request_from">Parringsanmodning fra %1s</string>
<string name="tap_to_answer">Tap for at svare</string>
<string name="reconnect">Forbind igen</string>
<string name="device_not_paired">Enhed ikke parret</string>
<string name="request_pairing">Anmod om parring</string>
<string name="pairing_accept">Acceptér</string>
<string name="pairing_reject">Afvis</string>
<string name="device">Enhed</string>
<string name="pair_device">Par med enhed</string>
<string name="remote_control">Fjernbetjening</string>
<string name="settings">Indstilling af KDE Connect</string>
<string name="mpris_play">Afspil</string>
<string name="mpris_previous">Forrige</string>
<string name="mpris_rew">Spol tilbage</string>
<string name="mpris_ff">Spol frem</string>
<string name="mpris_next">Næste</string>
<string name="mpris_volume">Lydstyrke</string>
<string name="share_to">Del på...</string>
<string name="protocol_version_older">Denne enhed bruger en gammel protokolversion</string>
<string name="protocol_version_newer">Denne enhed bruger en nyere protokolversion</string>
<string name="general_settings">Generelle indstillinger</string>
<string name="device_name">Enhedsnavn</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Ugyldigt enhedsnavn</string>
</resources>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Telefon-Benachrichtigung</string>
<string name="pref_plugin_telephony_desc">Benachrichtigungen über SMS und Anrufe senden</string>
<string name="pref_plugin_battery">Akkubericht</string>
<string name="pref_plugin_battery_desc">Akkustatus periodisch berichten</string>
<string name="pref_plugin_clipboard">Abgleich der Zwischenablage</string>
<string name="pref_plugin_clipboard_desc">Inhalt der Zwischenablage freigeben</string>
<string name="pref_plugin_mpris">Multimedia-Fernbedienungen</string>
<string name="pref_plugin_mpris_desc">Audio und Video mit Ihrem Telefon steuern</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Senden und Empfangen von Pings</string>
<string name="pref_plugin_notifications">Benachrichtigungs-Abgleich</string>
<string name="pref_plugin_notifications_desc">Zugriff auf Ihre Benachrichtigungen von anderen Geräten</string>
<string name="plugin_not_available">Diese Funktion ist in Ihrer Android-Version nicht verfügbar</string>
<string name="device_list_empty">Keine Geräte</string>
<string name="ok">OK</string>
<string name="cancel">Abbrechen</string>
<string name="open_settings">Einstellungen öffnen</string>
<string name="no_permissions">Sie müssen die Erlaubnis zum Zugriff auf Benachrichtigungen erteilen</string>
<string name="send_ping">Ping senden</string>
<string name="open_mpris_controls">Fernbedienung öffnen</string>
<string name="category_connected_devices">Verbundene Geräte</string>
<string name="category_not_paired_devices">Keine angeschlossenen Geräte</string>
<string name="category_remembered_devices">Gemerkte Geräte</string>
<string name="plugins_failed_to_load">Laden der Module fehlgeschlagen, tippen Sie für weitere Details:</string>
<string name="device_menu_plugins">Module auswählen</string>
<string name="device_menu_unpair">Verbindung trennen</string>
<string name="unknown_device">Unbekanntes Gerät</string>
<string name="error_not_reachable">Das Gerät ist nicht erreichbar</string>
<string name="error_already_requested">Die Verbindung wurde bereits angefragt</string>
<string name="error_already_paired">Das Gerät ist bereits verbunden</string>
<string name="error_could_not_send_package">Das Paket kann nicht gesendet werden</string>
<string name="error_timed_out">Zeitüberschreitung</string>
<string name="error_canceled_by_user">Abbruch durch Benutzer</string>
<string name="error_canceled_by_other_peer">Abbruch durch Gegenstelle</string>
<string name="error_invalid_key">Ungültiger Schlüssel empfangen</string>
<string name="pair_requested">Verbindung angefordert</string>
<string name="pairing_request_from">Verbindungsanfrage von %1s</string>
<string name="tap_to_answer">Tippen zum Antworten</string>
<string name="reconnect">Erneut verbinden</string>
<string name="device_not_paired">Das Gerät ist nicht verbunden</string>
<string name="request_pairing">Verbindung angefordert</string>
<string name="pairing_accept">Annehmen</string>
<string name="pairing_reject">Ablehnen</string>
<string name="device">Gerät</string>
<string name="pair_device">Gerät verbinden</string>
<string name="remote_control">Fernbedienung</string>
<string name="settings">KDE-Verbindungseinstellungen</string>
<string name="mpris_play">Wiedergabe</string>
<string name="mpris_previous">Zurück</string>
<string name="mpris_rew">Schneller Rücklauf</string>
<string name="mpris_ff">Vorlauf</string>
<string name="mpris_next">Weiter</string>
<string name="mpris_volume">Lautstärke</string>
<string name="share_to">Freigeben für ...</string>
<string name="protocol_version_older">Dieses Gerät verwendet ein alte Protokollversion</string>
<string name="protocol_version_newer">Dieses Gerät verwendet ein neuere Protokollversion</string>
<string name="general_settings">Allgemeine Einstellungen</string>
<string name="device_name">Gerätename</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Ungültiger Gerätename</string>
</resources>

View File

@@ -0,0 +1,60 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Notificador de telefonía</string>
<string name="pref_plugin_telephony_desc">Enviar notificaciones de SMS y llamadas</string>
<string name="pref_plugin_battery">Informe de la batería</string>
<string name="pref_plugin_battery_desc">Informar periódicamente del estado de la batería</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_mpris">Controles remotos multimedia</string>
<string name="pref_plugin_mpris_desc">Controlar audio y vídeo desde el teléfono</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Enviar y recibir pings</string>
<string name="pref_plugin_notifications">Sincronizar notificaciones</string>
<string name="pref_plugin_notifications_desc">Acceder a las notificaciones desde otros dispositivos</string>
<string name="plugin_not_available">Esta función no está disponible en su versión de Android</string>
<string name="device_list_empty">Ningún dispositivo</string>
<string name="ok">Aceptar</string>
<string name="cancel">Cancelar</string>
<string name="open_settings">Abrir preferencias</string>
<string name="no_permissions">Debe otorgar permiso para acceder a las notificaciones</string>
<string name="send_ping">Enviar ping</string>
<string name="open_mpris_controls">Abrir control remoto</string>
<string name="category_connected_devices">Dispositivos conectados</string>
<string name="category_not_paired_devices">Dispositivos no vinculados</string>
<string name="category_remembered_devices">Dispositivos recordados</string>
<string name="plugins_failed_to_load">Complementos cuya carga ha fallado (toque para más información):</string>
<string name="device_menu_plugins">Seleccionar complementos</string>
<string name="device_menu_unpair">Desvincular</string>
<string name="unknown_device">Dispositivo desconocido</string>
<string name="error_not_reachable">No se encuentra el dispositivo</string>
<string name="error_already_requested">Ya ha solicitado vincularse</string>
<string name="error_already_paired">Dispositivo ya vinculado</string>
<string name="error_could_not_send_package">No se puede enviar el paquete</string>
<string name="error_timed_out">Se ha agotado el tiempo</string>
<string name="error_canceled_by_user">Cancelado por el usuario</string>
<string name="error_canceled_by_other_peer">Cancelado por la otra parte</string>
<string name="error_invalid_key">Se ha recibido una clave no valida</string>
<string name="pair_requested">Vinculación solicitada</string>
<string name="pairing_request_from">Solicitud de vinculación de %1s</string>
<string name="tap_to_answer">Toque para responder</string>
<string name="reconnect">Reconectar</string>
<string name="device_not_paired">Dispositivo no vinculado</string>
<string name="request_pairing">Solicitar vinculación</string>
<string name="pairing_accept">Aceptar</string>
<string name="pairing_reject">Rechazar</string>
<string name="device">Dispositivo</string>
<string name="pair_device">Vincular dispositivo</string>
<string name="remote_control">Control remoto</string>
<string name="settings">Preferencias de KDE Connect</string>
<string name="mpris_play">Reproducir</string>
<string name="mpris_previous">Anterior</string>
<string name="mpris_next">Siguiente</string>
<string name="mpris_volume">Volumen</string>
<string name="share_to">Compartir con...</string>
<string name="protocol_version_older">Este dispositivo usa una versión antigua del protocolo</string>
<string name="protocol_version_newer">Este dispositivo usa una versión más reciente del protocolo</string>
<string name="general_settings">Abrir preferencias</string>
<string name="device_name">Dispositivo no vinculado</string>
<string name="invalid_device_name">Se ha recibido una clave no valida</string>
</resources>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Puhelinilmoitukset</string>
<string name="pref_plugin_telephony_desc">Lähetä ilmoitukset tekstiviesteistä ja puheluista</string>
<string name="pref_plugin_battery">Akkuraportti</string>
<string name="pref_plugin_battery_desc">Raportoi akun tila säännöllisesti</string>
<string name="pref_plugin_clipboard">Leikepöydän synkronointi</string>
<string name="pref_plugin_clipboard_desc">Jaa leikepöydän sisältö</string>
<string name="pref_plugin_mpris">Multimediakauko-ohjaimet</string>
<string name="pref_plugin_mpris_desc">Ohjaa ääntä ja videota puhelimestasi</string>
<string name="pref_plugin_ping">Tiedustelupaketti</string>
<string name="pref_plugin_ping_desc">Lähetä ja vastaanota tiedustelupaketteja</string>
<string name="pref_plugin_notifications">Ilmoitusten synkronointi</string>
<string name="pref_plugin_notifications_desc">Näe ilmoituksesi muissa laitteissa</string>
<string name="plugin_not_available">Piirre ei ole käytettävissä Android-versiossasi</string>
<string name="device_list_empty">Ei laitteita</string>
<string name="ok">OK</string>
<string name="cancel">Peru</string>
<string name="open_settings">Avaa asetukset</string>
<string name="no_permissions">Sinun on annettava lupa ilmoitusten näkemiseen</string>
<string name="send_ping">Lähetä tiedustelupaketti</string>
<string name="open_mpris_controls">Avaa kauko-ohjain</string>
<string name="category_connected_devices">Yhdistetyt laitteet</string>
<string name="category_not_paired_devices">Ei laitepareja</string>
<string name="category_remembered_devices">Muistetut laitteet</string>
<string name="plugins_failed_to_load">Liitännäisten lataus epäonnistui (lisätietoa napsauttamalla):</string>
<string name="device_menu_plugins">Valitse liitännäiset</string>
<string name="device_menu_unpair">Irrota paritus</string>
<string name="unknown_device">Tuntematon laite</string>
<string name="error_not_reachable">Laite tavoittamattomissa</string>
<string name="error_already_requested">Paritusta on jo pyydetty</string>
<string name="error_already_paired">Laitepari on jo muodostettu</string>
<string name="error_could_not_send_package">Ei voitu lähettää pakettia</string>
<string name="error_timed_out">Aikakatkaisu</string>
<string name="error_canceled_by_user">Käyttäjä perui</string>
<string name="error_canceled_by_other_peer">Vertaiskäyttäjä perui</string>
<string name="error_invalid_key">Vastaanotettiin väärä avain</string>
<string name="pair_requested">Parituspyyntö</string>
<string name="pairing_request_from">Parituspyyntö kohteesta %1s</string>
<string name="tap_to_answer">Vastaa napsauttamalla</string>
<string name="reconnect">Yhdistä uudelleen</string>
<string name="device_not_paired">Ei laiteparia</string>
<string name="request_pairing">Pyydä paritusta</string>
<string name="pairing_accept">Hyväksy</string>
<string name="pairing_reject">Hylkää</string>
<string name="device">Laite</string>
<string name="pair_device">Parita laite</string>
<string name="remote_control">Kauko-ohjain</string>
<string name="settings">KDE Connectin asetukset</string>
<string name="mpris_play">Toista</string>
<string name="mpris_previous">Edellinen</string>
<string name="mpris_rew">Kelaa takaisin</string>
<string name="mpris_ff">Nopeasti eteenpäin</string>
<string name="mpris_next">Seuraava</string>
<string name="mpris_volume">Äänenvoimakkuus</string>
<string name="share_to">Jaa…</string>
<string name="protocol_version_older">Laite käyttää vanha yhteyskäytäntöversiota</string>
<string name="protocol_version_newer">Laite käyttää uudempaa yhteyskäytäntöversiota</string>
<string name="general_settings">Yleisasetukset</string>
<string name="device_name">Laitenimi</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Virheellinen laitenimi</string>
</resources>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Notificateur de téléphonie</string>
<string name="pref_plugin_telephony_desc">Envoie des notifications pour les SMS et les appels</string>
<string name="pref_plugin_battery">Rapport sur la batterie</string>
<string name="pref_plugin_battery_desc">Rapport périodique sur l\'état de la batterie</string>
<string name="pref_plugin_clipboard">Synchronisation avec le presse-papiers</string>
<string name="pref_plugin_clipboard_desc">Partage le contenu du presse-papiers</string>
<string name="pref_plugin_mpris">Contrôles distants multimédia</string>
<string name="pref_plugin_mpris_desc">Contrôle l\'audio / la vidéo depuis votre téléphone</string>
<string name="pref_plugin_ping">Commande « Ping »</string>
<string name="pref_plugin_ping_desc">Envoie et reçoit des commandes « Ping »</string>
<string name="pref_plugin_notifications">Synchronisation des notifications</string>
<string name="pref_plugin_notifications_desc">Accédez à vos notifications depuis d\'autres périphériques</string>
<string name="plugin_not_available">Cette fonctionnalité n\'est pas disponible dans votre version de Android</string>
<string name="device_list_empty">Pas de périphériques</string>
<string name="ok">Ok</string>
<string name="cancel">Annuler</string>
<string name="open_settings">Accéder aux paramètres</string>
<string name="no_permissions">Vous devez accorder la permission d\'accéder aux notifications</string>
<string name="send_ping">Envoyer un « Ping »</string>
<string name="open_mpris_controls">Ouvrir un contrôle distant</string>
<string name="category_connected_devices">Périphériques connectés</string>
<string name="category_not_paired_devices">Pas de périphériques appariés</string>
<string name="category_remembered_devices">Périphériques mémorisés</string>
<string name="plugins_failed_to_load">Le chargement des modules externes a échoué (cliquez pour plus d\'informations) :</string>
<string name="device_menu_plugins">Sélectionner des modules externes</string>
<string name="device_menu_unpair">Désapparier</string>
<string name="unknown_device">Périphérique inconnu</string>
<string name="error_not_reachable">Périphérique inaccessible</string>
<string name="error_already_requested">L\'appariement a déjà été demandé</string>
<string name="error_already_paired">Périphérique déjà apparié</string>
<string name="error_could_not_send_package">Il est impossible d\'envoyer un paquet</string>
<string name="error_timed_out">Délai expiré</string>
<string name="error_canceled_by_user">Annulé par l\'utilisateur</string>
<string name="error_canceled_by_other_peer">Annulé par un autre homologue</string>
<string name="error_invalid_key">Clé reçue non valable</string>
<string name="pair_requested">Paire demandée</string>
<string name="pairing_request_from">Demande d\'appariement provenant de %1s</string>
<string name="tap_to_answer">Cliquer pour répondre</string>
<string name="reconnect">Reconnecter</string>
<string name="device_not_paired">Périphérique non apparié</string>
<string name="request_pairing">Demande d\'appariement</string>
<string name="pairing_accept">Accepter</string>
<string name="pairing_reject">Rejeter</string>
<string name="device">Périphérique</string>
<string name="pair_device">Apparier un périphérique</string>
<string name="remote_control">Contrôle distant</string>
<string name="settings">Paramètres de connexion de KDE</string>
<string name="mpris_play">Lire</string>
<string name="mpris_previous">Précédent</string>
<string name="mpris_rew">Retour rapide</string>
<string name="mpris_ff">Avance rapide</string>
<string name="mpris_next">Suivant</string>
<string name="mpris_volume">Volume</string>
<string name="share_to">Partager vers...</string>
<string name="protocol_version_older">Le périphérique utilise une version ancienne du protocole</string>
<string name="protocol_version_newer">Le périphérique utilise une version plus récente du protocole</string>
<string name="general_settings">Paramètres généraux</string>
<string name="device_name">Nom du périphérique</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Nom de périphérique non valable</string>
</resources>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Telefon értesítő</string>
<string name="pref_plugin_telephony_desc">Értesítés küldése SMS-hez és hívásokhoz</string>
<string name="pref_plugin_battery">Akkumulátor jelentés</string>
<string name="pref_plugin_battery_desc">Akkumulátorállapot időszakos jelentése</string>
<string name="pref_plugin_clipboard">Vágólap szinkronizáció</string>
<string name="pref_plugin_clipboard_desc">A vágólap tartalmának megosztása</string>
<string name="pref_plugin_mpris">Multimedia távirányítók</string>
<string name="pref_plugin_mpris_desc">Hang vagy videó vezérlése a telefonról</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Pingek küldése és fogadása</string>
<string name="pref_plugin_notifications">Értesítés szinkronizáció</string>
<string name="pref_plugin_notifications_desc">Hozzáférés az értesítésekhez más eszközökről</string>
<string name="plugin_not_available">Ez a funkció nem érhető el az ön Android verziójában</string>
<string name="device_list_empty">Nincsenek eszközök</string>
<string name="ok">OK</string>
<string name="cancel">Mégse</string>
<string name="open_settings">Beállítások megnyitása</string>
<string name="no_permissions">Jogot kell adnia az értesítésekhez való hozzáféréshez</string>
<string name="send_ping">Ping küldése</string>
<string name="open_mpris_controls">Távirányító megnyitása</string>
<string name="category_connected_devices">Csatlakoztatott eszközök</string>
<string name="category_not_paired_devices">Nincsenek párosított eszközök</string>
<string name="category_remembered_devices">Megjegyzett eszközök</string>
<string name="plugins_failed_to_load">A bővítményeket nem sikerült betölteni (érintse meg a további információkért):</string>
<string name="device_menu_plugins">Bővítmények kijelölése</string>
<string name="device_menu_unpair">Leválasztás</string>
<string name="unknown_device">Ismeretlen eszköz</string>
<string name="error_not_reachable">Az eszköz nem érhető el</string>
<string name="error_already_requested">A párosítás már kérve lett</string>
<string name="error_already_paired">Az eszköz már párosítva van</string>
<string name="error_could_not_send_package">Nem sikerült elküldeni a csomagot</string>
<string name="error_timed_out">Időtúllépés</string>
<string name="error_canceled_by_user">Megszakítva a felhasználó által</string>
<string name="error_canceled_by_other_peer">A másik partner megszakította</string>
<string name="error_invalid_key">Érvénytelen kulcs érkezett</string>
<string name="pair_requested">Párosítás kérve</string>
<string name="pairing_request_from">Párosítási kérés innen: %1s</string>
<string name="tap_to_answer">Érintse meg a válaszhoz</string>
<string name="reconnect">Újracsatlakozás</string>
<string name="device_not_paired">Az eszköz nincs párosítva</string>
<string name="request_pairing">Párosítás kérése</string>
<string name="pairing_accept">Elfogadás</string>
<string name="pairing_reject">Elutasítás</string>
<string name="device">Eszköz</string>
<string name="pair_device">Eszköz párosítása</string>
<string name="remote_control">Távirányító</string>
<string name="settings">KDE csatlakozás beállítások</string>
<string name="mpris_play">Lejátszás</string>
<string name="mpris_previous">Előző</string>
<string name="mpris_rew">Visszatekerés</string>
<string name="mpris_ff">Gyors előretekerés</string>
<string name="mpris_next">Következő</string>
<string name="mpris_volume">Hangerő</string>
<string name="share_to">Megosztás…</string>
<string name="protocol_version_older">Ez az eszköz egy régi protokollverziót használ</string>
<string name="protocol_version_newer">Ez az eszköz egy újabb protokollverziót használ</string>
<string name="general_settings">Általános beállítások</string>
<string name="device_name">Eszköznév</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Érvénytelen eszköznév</string>
</resources>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Notifiche telefoniche</string>
<string name="pref_plugin_telephony_desc">Invia notifiche di SMS e chiamate</string>
<string name="pref_plugin_battery">Livello batteria</string>
<string name="pref_plugin_battery_desc">Comunica periodicamente lo stato della batteria</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_mpris">Telecomando multimediale</string>
<string name="pref_plugin_mpris_desc">Controlla la riproduzione audio/video dal telefono</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Invia e ricevi ping</string>
<string name="pref_plugin_notifications">Sincronizzazione notifiche</string>
<string name="pref_plugin_notifications_desc">Consenti l\'accesso alle notifiche dagli altri dispositivi</string>
<string name="plugin_not_available">Questa funzionalità non è disponibile sulla tua versione di Android</string>
<string name="device_list_empty">Nessun dispositivo</string>
<string name="ok">OK</string>
<string name="cancel">Annulla</string>
<string name="open_settings">Apri impostazioni</string>
<string name="no_permissions">Devi garantire a KDE Connect l\'accesso alle notifiche</string>
<string name="send_ping">Invia ping</string>
<string name="open_mpris_controls">Apri il telecomando multimediale</string>
<string name="category_connected_devices">Dispositivi connessi</string>
<string name="category_not_paired_devices">Dispositivi non associati</string>
<string name="category_remembered_devices">Dispositivi memorizzati</string>
<string name="plugins_failed_to_load">Alcune estensioni non si sono avviate correttamente (tocca per maggiori informazioni):</string>
<string name="device_menu_plugins">Estensioni</string>
<string name="device_menu_unpair">Disassocia</string>
<string name="unknown_device">Dispositivo sconosciuto</string>
<string name="error_not_reachable">Dispositivo fuori portata</string>
<string name="error_already_requested">Richiesta già inviata</string>
<string name="error_already_paired">Dispositivo già associato</string>
<string name="error_could_not_send_package">Impossibile inviare i dati</string>
<string name="error_timed_out">Richiesta scaduta</string>
<string name="error_canceled_by_user">Richiesta annullata dall\'utente</string>
<string name="error_canceled_by_other_peer">Richiesta annullata dal dispositivo remoto</string>
<string name="error_invalid_key">Ricevuta chiave non valida</string>
<string name="pair_requested">Richiesta di associazione</string>
<string name="pairing_request_from">Richiesta associazione da %1s</string>
<string name="tap_to_answer">Tocca per rispondere</string>
<string name="reconnect">Riconnetti</string>
<string name="device_not_paired">Dispositivo non associato</string>
<string name="request_pairing">Richiedi associazione</string>
<string name="pairing_accept">Accetta</string>
<string name="pairing_reject">Rifiuta</string>
<string name="device">Dispositivo</string>
<string name="pair_device">Associa dispositivo</string>
<string name="remote_control">Telecomando</string>
<string name="settings">Impostazioni</string>
<string name="mpris_play">Riproduci</string>
<string name="mpris_previous">Precedente</string>
<string name="mpris_rew">Riavvolgi</string>
<string name="mpris_ff">Avanti veloce</string>
<string name="mpris_next">Successivo</string>
<string name="mpris_volume">Volume</string>
<string name="share_to">Condividi…</string>
<string name="protocol_version_older">Questo dispositivo usa una vecchia versione del protocollo di rete</string>
<string name="protocol_version_newer">Questo dispositivo usa una nuova versione del protocollo di rete</string>
<string name="general_settings">Impostazioni generali</string>
<string name="device_name">Nome dispositivo</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Nome non valido</string>
</resources>

View File

@@ -0,0 +1,2 @@
<?xml version='1.0' encoding='utf-8'?>
<resources/>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Telefoniemelder</string>
<string name="pref_plugin_telephony_desc">Stuur meldingen voor SMS en oproepen</string>
<string name="pref_plugin_battery">Batterijrapportage</string>
<string name="pref_plugin_battery_desc">Rapporteer periodiek de status van de batterij</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_mpris">Afstandsbediening van multimedia</string>
<string name="pref_plugin_mpris_desc">Bedien de audio/video vanaf uw telefoon</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Pings verzenden en ontvangen</string>
<string name="pref_plugin_notifications">Synchronisatie van meldingen</string>
<string name="pref_plugin_notifications_desc">Bekijk uw meldingen van andere apparaten</string>
<string name="plugin_not_available">Deze functie is niet beschikbaar in uw versie van Android</string>
<string name="device_list_empty">Geen apparaten</string>
<string name="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>
<string name="send_ping">Ping verzenden</string>
<string name="open_mpris_controls">Afstandsbediening openen</string>
<string name="category_connected_devices">Verbonden apparaten</string>
<string name="category_not_paired_devices">Geen gepaarde apparaten</string>
<string name="category_remembered_devices">Onthouden apparaten</string>
<string name="plugins_failed_to_load">Laden van plug-ins is mislukt (tap voor meer informatie):</string>
<string name="device_menu_plugins">Plug-ins selecteren</string>
<string name="device_menu_unpair">Paar uit elkaar halen</string>
<string name="unknown_device">Onbekend apparaat</string>
<string name="error_not_reachable">Apparaat niet bereikbaar</string>
<string name="error_already_requested">Paar maken is al gevraagd</string>
<string name="error_already_paired">Apparaat is al gepaard</string>
<string name="error_could_not_send_package">Kon pakket niet verzenden</string>
<string name="error_timed_out">Tijdslimiet overschreden</string>
<string name="error_canceled_by_user">Geannuleerd door gebruiker</string>
<string name="error_canceled_by_other_peer">Geannuleerd door andere kant</string>
<string name="error_invalid_key">Ongeldige sleutel ontvangen</string>
<string name="pair_requested">Paar gevraagd</string>
<string name="pairing_request_from">Verzoek om een paar te maken van %1s</string>
<string name="tap_to_answer">Tap om te antwoorden</string>
<string name="reconnect">Opnieuw verbinden</string>
<string name="device_not_paired">Apparaat is niet gepaard</string>
<string name="request_pairing">Verzoek voor maken van paar</string>
<string name="pairing_accept">Accepteren</string>
<string name="pairing_reject">Afwijzen</string>
<string name="device">Apparaat</string>
<string name="pair_device">Apparaat voor paar</string>
<string name="remote_control">Afstandsbediening</string>
<string name="settings">Instellingen van KDE Connect</string>
<string name="mpris_play">Afspelen</string>
<string name="mpris_previous">Vorige</string>
<string name="mpris_rew">Terugspoelen</string>
<string name="mpris_ff">Snel vooruit</string>
<string name="mpris_next">Volgende</string>
<string name="mpris_volume">Volume</string>
<string name="share_to">Delen met...</string>
<string name="protocol_version_older">Dit apparaat gebruikt een oude protocolversie</string>
<string name="protocol_version_newer">Dit apparaat gebruikt een nieuwere protocolversie</string>
<string name="general_settings">Algemene instellingen</string>
<string name="device_name">Apparaatnaam</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Ongeldige apparaatnaam</string>
</resources>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Notificação telefônica</string>
<string name="pref_plugin_telephony_desc">Envia notificações de SMS e chamadas</string>
<string name="pref_plugin_battery">Relatório da bateria</string>
<string name="pref_plugin_battery_desc">Informa o status da bateria periodicamente</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_mpris">Controle remoto multimídia</string>
<string name="pref_plugin_mpris_desc">Controla áudio e vídeo a partir do seu telefone</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Envia e recebe pings</string>
<string name="pref_plugin_notifications">Sincronização de notificações</string>
<string name="pref_plugin_notifications_desc">Acesse suas notificações a partir de outros dispositivos</string>
<string name="plugin_not_available">Esta funcionalidade não está disponível na sua versão do Android</string>
<string name="device_list_empty">Sem dispositivos</string>
<string name="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>
<string name="send_ping">Enviar ping</string>
<string name="open_mpris_controls">Abra o controle remoto</string>
<string name="category_connected_devices">Dispositivos conectados</string>
<string name="category_not_paired_devices">Dispositivos não emparelhados</string>
<string name="category_remembered_devices">Dispositivos lembrados</string>
<string name="plugins_failed_to_load">Plugins não carregados (toque para mais informações):</string>
<string name="device_menu_plugins">Selecionar plugins</string>
<string name="device_menu_unpair">Cancelar emparelhamento</string>
<string name="unknown_device">Dispositivo desconhecido</string>
<string name="error_not_reachable">Dispositivo inacessível</string>
<string name="error_already_requested">O emparelhamento já foi solicitado</string>
<string name="error_already_paired">Dispositivo já emparelhado</string>
<string name="error_could_not_send_package">Não foi possível enviar o pacote</string>
<string name="error_timed_out">Tempo limite expirou</string>
<string name="error_canceled_by_user">Cancelado pelo usuário</string>
<string name="error_canceled_by_other_peer">Cancelado pelo outro dispositivo</string>
<string name="error_invalid_key">Chave inválida recebida</string>
<string name="pair_requested">Emparelhamento solicitado</string>
<string name="pairing_request_from">Emparelhando solicitação de %1s</string>
<string name="tap_to_answer">Toque para responder</string>
<string name="reconnect">Reconectar</string>
<string name="device_not_paired">Dispositivo não emparelhado</string>
<string name="request_pairing">Solicitar emparelhamento</string>
<string name="pairing_accept">Aceitar</string>
<string name="pairing_reject">Rejeitar</string>
<string name="device">Dispositivo</string>
<string name="pair_device">Emparelhar dispositivo</string>
<string name="remote_control">Controle remoto</string>
<string name="settings">Configurações do KDE Connect</string>
<string name="mpris_play">Reproduzir</string>
<string name="mpris_previous">Anterior</string>
<string name="mpris_rew">Retornar</string>
<string name="mpris_ff">Avançar rapidamente</string>
<string name="mpris_next">Próximo</string>
<string name="mpris_volume">Volume</string>
<string name="share_to">Compartilhar com...</string>
<string name="protocol_version_older">Este dispositivo usa uma versão antiga do protocolo</string>
<string name="protocol_version_newer">Este dispositivo usa uma versão mais recente do protocolo</string>
<string name="general_settings">Configurações gerais</string>
<string name="device_name">Nome do dispositivo</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Nome do dispositivo inválido</string>
</resources>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Notificação telefónica</string>
<string name="pref_plugin_telephony_desc">Enviar notificações para os SMS\'s e chamadas</string>
<string name="pref_plugin_battery">Relatório da bateria</string>
<string name="pref_plugin_battery_desc">Comunicar periodicamente o estado da bateria</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_mpris">Comando à distância multimédia</string>
<string name="pref_plugin_mpris_desc">Controlar o áudio/vídeo a partir do seu telefone</string>
<string name="pref_plugin_ping">Contacto</string>
<string name="pref_plugin_ping_desc">Enviar e receber pedidos de contacto (\'ping\')</string>
<string name="pref_plugin_notifications">Sincronização da notificação</string>
<string name="pref_plugin_notifications_desc">Aceder às suas notificações a partir de outros dispositivos</string>
<string name="plugin_not_available">Esta funcionalidade não está disponível na sua versão do Android</string>
<string name="device_list_empty">Sem dispositivos</string>
<string name="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>
<string name="send_ping">Enviar um pedido de contacto</string>
<string name="open_mpris_controls">Abrir o comando à distância</string>
<string name="category_connected_devices">Dispositivos ligados</string>
<string name="category_not_paired_devices">Dispositivos não emparelhados</string>
<string name="category_remembered_devices">Dispositivos recordados</string>
<string name="plugins_failed_to_load">Não foi possível carregar os \'plugin\' (toque para mais informações):</string>
<string name="device_menu_plugins">Seleccionar os \'plugins\'</string>
<string name="device_menu_unpair">Desemparelhar</string>
<string name="unknown_device">Dispositivo desconhecido</string>
<string name="error_not_reachable">Dispositivo inacessível</string>
<string name="error_already_requested">O emparelhamento já foi pedido</string>
<string name="error_already_paired">O dispositivo já foi emparelhado</string>
<string name="error_could_not_send_package">Não foi possível enviar o pacote</string>
<string name="error_timed_out">Expirou o tempo-limite</string>
<string name="error_canceled_by_user">Cancelado pelo utilizador</string>
<string name="error_canceled_by_other_peer">Cancelado pela outra máquina</string>
<string name="error_invalid_key">Chave inválida recebida</string>
<string name="pair_requested">Emparelhamento pedido</string>
<string name="pairing_request_from">Pedido de emparelhamento de %1s</string>
<string name="tap_to_answer">Toque para responder</string>
<string name="reconnect">Ligar de Novo</string>
<string name="device_not_paired">Dispositivo não emparelhado</string>
<string name="request_pairing">Pedir o emparelhamento</string>
<string name="pairing_accept">Aceitar</string>
<string name="pairing_reject">Rejeitar</string>
<string name="device">Dispositivo</string>
<string name="pair_device">Emparelhar o dispositivo</string>
<string name="remote_control">Comando à distância</string>
<string name="settings">Configuração do KDE Connect</string>
<string name="mpris_play">Tocar</string>
<string name="mpris_previous">Anterior</string>
<string name="mpris_rew">Recuar</string>
<string name="mpris_ff">Avançar</string>
<string name="mpris_next">Seguinte</string>
<string name="mpris_volume">Volume</string>
<string name="share_to">Partilhar Com...</string>
<string name="protocol_version_older">Este dispositivo usa uma versão antiga do protocolo</string>
<string name="protocol_version_newer">Este dispositivo usa uma versão mais recente do protocolo</string>
<string name="general_settings">Configuração Geral</string>
<string name="device_name">Nome do dispositivo</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Nome do dispositivo inválido</string>
</resources>

View File

@@ -0,0 +1,62 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Уведомления телефонии</string>
<string name="pref_plugin_telephony_desc">Отправлять уведомления о SMS и звонках</string>
<string name="pref_plugin_battery">Состояние батареи</string>
<string name="pref_plugin_battery_desc">Периодически сообщать о состоянии батареи</string>
<string name="pref_plugin_sftp">Доступ по SFTP</string>
<string name="pref_plugin_sftp_desc">Возможность доступа к файлам по SFTP</string>
<string name="pref_plugin_clipboard">Синхронизация буфера обмена</string>
<string name="pref_plugin_clipboard_desc">Сделать содержимое буфера обмена общим</string>
<string name="pref_plugin_mpris">ДУ для мультимедия</string>
<string name="pref_plugin_mpris_desc">Управление аудио/видео с устройства</string>
<string name="pref_plugin_ping">Пинг</string>
<string name="pref_plugin_ping_desc">Посылать и получать пинги</string>
<string name="pref_plugin_notifications">Синхронизация уведомлений</string>
<string name="pref_plugin_notifications_desc">Доступ к уведомлениям с других устройств</string>
<string name="plugin_not_available">Этот функционал недоступен в вашей версии Android</string>
<string name="device_list_empty">Нет устройств</string>
<string name="ok">OK</string>
<string name="cancel">Отмена</string>
<string name="open_settings">Открыть настройки</string>
<string name="no_permissions">Вы должны разрешить доступ к уведомлениям</string>
<string name="send_ping">Послать пинг</string>
<string name="open_mpris_controls">Открыть дистанционное управление</string>
<string name="category_connected_devices">Подключённые устройства</string>
<string name="category_not_paired_devices">Не спаренные устройства</string>
<string name="category_remembered_devices">Запомненные устройства</string>
<string name="plugins_failed_to_load">Сбой загрузки следующих модулей (прикоснитесь чтобы получить подробности):</string>
<string name="device_menu_plugins">Выбрать модули</string>
<string name="device_menu_unpair">Разделить спаренные устройства</string>
<string name="unknown_device">Неизвестное устройство</string>
<string name="error_not_reachable">Устройство недоступно</string>
<string name="error_already_requested">Запрос на спаривание уже был сделан</string>
<string name="error_already_paired">Устройство уже спарено</string>
<string name="error_could_not_send_package">Не удалось послать пакет</string>
<string name="error_timed_out">Истекло время ожидания</string>
<string name="error_canceled_by_user">Отменено пользователем</string>
<string name="error_canceled_by_other_peer">Отменено другим участником</string>
<string name="error_invalid_key">Недопустимый получатель ключа</string>
<string name="pair_requested">Запрошено спаривание</string>
<string name="pairing_request_from">Запрос на спаривание от %1s</string>
<string name="tap_to_answer">Коснитесь чтобы ответить</string>
<string name="reconnect">Переподключить</string>
<string name="device_not_paired">Устройство не спарено</string>
<string name="request_pairing">Запросить спаривание</string>
<string name="pairing_accept">Принять</string>
<string name="pairing_reject">Отклонить</string>
<string name="device">Устройство</string>
<string name="pair_device">Спарить устройство</string>
<string name="remote_control">Дистанционное управление</string>
<string name="settings">Настройки KDE Connect</string>
<string name="mpris_play">Воспроизвести</string>
<string name="mpris_previous">Предыдущий</string>
<string name="mpris_next">Следующее</string>
<string name="mpris_volume">Громкость</string>
<string name="share_to">Сделать общим с...</string>
<string name="protocol_version_older">Это устройство использует старую версию протокола</string>
<string name="protocol_version_newer">Это устройство использует более свежую версию протокола</string>
<string name="general_settings">Открыть настройки</string>
<string name="device_name">Устройство не спарено</string>
<string name="invalid_device_name">Недопустимый получатель ключа</string>
</resources>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Telefónny notifikátor</string>
<string name="pref_plugin_telephony_desc">Poslať pripomienky pre SMS a 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_clipboard">Synchronizácia schránky</string>
<string name="pref_plugin_clipboard_desc">Zdieľať obsah schránky</string>
<string name="pref_plugin_mpris">Multimediálne diaľkové ovládače</string>
<string name="pref_plugin_mpris_desc">Ovládať audio/video z vášho telefónu</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Poslať a prijať 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="plugin_not_available">Táto funkcia nie je dostupná vo vašej verzii Androidu</string>
<string name="device_list_empty">Žiadne zariadenia</string>
<string name="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="send_ping">Poslať ping</string>
<string name="open_mpris_controls">Otvoriť diaľkové ovládanie</string>
<string name="category_connected_devices">Pripojené zariadenia</string>
<string name="category_not_paired_devices">Nespárované zariadenia</string>
<string name="category_remembered_devices">Zapamätané zariadenia</string>
<string name="plugins_failed_to_load">Zlyhalo načítanie pluginov (tapnite pre viac info):</string>
<string name="device_menu_plugins">Vybrať pluginy</string>
<string name="device_menu_unpair">Odpárovať</string>
<string name="unknown_device">Neznáme zariadenie</string>
<string name="error_not_reachable">Zariadenie nedostupné</string>
<string name="error_already_requested">Spárovanie už vyžiadané</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_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="error_invalid_key">Získaný nesprávny kľúč</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="tap_to_answer">Tapnite na odpoveď</string>
<string name="reconnect">Znovu pripojiť</string>
<string name="device_not_paired">Zariadenie nespárované</string>
<string name="request_pairing">Požiadavka na spárovanie</string>
<string name="pairing_accept">Prijať</string>
<string name="pairing_reject">Odmietnuť</string>
<string name="device">Zariadenie</string>
<string name="pair_device">Spárovať zariadenie</string>
<string name="remote_control">Diaľkové ovládanie</string>
<string name="settings">Nastavenia KDE Connect</string>
<string name="mpris_play">Prehrať</string>
<string name="mpris_previous">Predošlé</string>
<string name="mpris_rew">Pretočiť dozadu</string>
<string name="mpris_ff">Pretočiť dopredu</string>
<string name="mpris_next">Nasledovné</string>
<string name="mpris_volume">Hlasitosť</string>
<string name="share_to">Zdieľať pre...</string>
<string name="protocol_version_older">Toto zariadenie používa starú verziu protokolu</string>
<string name="protocol_version_newer">Toto zariadenie používa novšiu verziu protokolu</string>
<string name="general_settings">Všeobecné nastavenia</string>
<string name="device_name">Názov zariadenia</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Neplatný názov zariadenia</string>
</resources>

View File

@@ -0,0 +1,63 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Telefonunderrättelser</string>
<string name="pref_plugin_telephony_desc">Skicka underrättelser för SMS och samtal</string>
<string name="pref_plugin_battery">Batterirapport</string>
<string name="pref_plugin_battery_desc">Rapportera periodiskt batteriets status</string>
<string name="pref_plugin_clipboard">Synkronisera klippbord</string>
<string name="pref_plugin_clipboard_desc">Dela klippbordets innehåll</string>
<string name="pref_plugin_mpris">Fjärrkontroll av multimedia</string>
<string name="pref_plugin_mpris_desc">Styr ljud och video från telefonen</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Skicka och ta emot ping</string>
<string name="pref_plugin_notifications">Synkronisering av underrättelser</string>
<string name="pref_plugin_notifications_desc">Kom åt underrättelser från andra apparater</string>
<string name="plugin_not_available">Funktionen är inte tillgänglig i Android-versionen</string>
<string name="device_list_empty">Inga apparater</string>
<string name="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>
<string name="send_ping">Skicka ping</string>
<string name="open_mpris_controls">Öppna fjärrkontroll</string>
<string name="category_connected_devices">Anslutna apparater</string>
<string name="category_not_paired_devices">Inga parade apparater</string>
<string name="category_remembered_devices">Ihågkomna apparater</string>
<string name="plugins_failed_to_load">Misslyckades ladda insticksprogram (rör för mer information):</string>
<string name="device_menu_plugins">Välj insticksprogram</string>
<string name="device_menu_unpair">Ta bort ihopparning</string>
<string name="unknown_device">Okänd apparat</string>
<string name="error_not_reachable">Apparaten kan inte nås</string>
<string name="error_already_requested">Ihopparning redan begärd</string>
<string name="error_already_paired">Apparat redan ihopparad</string>
<string name="error_could_not_send_package">Kunde inte skicka paket</string>
<string name="error_timed_out">Tidsgräns överskriden</string>
<string name="error_canceled_by_user">Avbruten av användaren</string>
<string name="error_canceled_by_other_peer">Avbruten av motparten</string>
<string name="error_invalid_key">Ogiltig nyckel mottagen</string>
<string name="pair_requested">Ihopparning begärd</string>
<string name="pairing_request_from">Begäran om ihopparning från %1s</string>
<string name="tap_to_answer">Rör för att svara</string>
<string name="reconnect">Anslut igen</string>
<string name="device_not_paired">Apparat inte ihopparad</string>
<string name="request_pairing">Begära ihopparning</string>
<string name="pairing_accept">Acceptera</string>
<string name="pairing_reject">Avslå</string>
<string name="device">Apparat</string>
<string name="pair_device">Para ihop apparat</string>
<string name="remote_control">Fjärrkontroll</string>
<string name="settings">KDE anslutningsinställningar</string>
<string name="mpris_play">Spela</string>
<string name="mpris_previous">Föregående</string>
<string name="mpris_rew">Snabbspola bakåt</string>
<string name="mpris_ff">Snabbspola framåt</string>
<string name="mpris_next">Nästa</string>
<string name="mpris_volume">Volym</string>
<string name="share_to">Dela med...</string>
<string name="protocol_version_older">Apparaten använder en gammal protokollversion</string>
<string name="protocol_version_newer">Apparaten använder en nyare protokollversion</string>
<string name="general_settings">Allmänna inställningar</string>
<string name="device_name">Apparatnamn</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Ogiltigt apparatnamn</string>
</resources>

View File

@@ -0,0 +1,65 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Телефонний сповіщувач</string>
<string name="pref_plugin_telephony_desc">Надсилання сповіщень щодо SMS та дзвінків</string>
<string name="pref_plugin_battery">Звіт щодо заряду</string>
<string name="pref_plugin_battery_desc">Періодична інформація щодо стану акумулятора</string>
<string name="pref_plugin_sftp">Доступ по SFTP</string>
<string name="pref_plugin_sftp_desc">Возможность доступа к файлам по SFTP</string>
<string name="pref_plugin_clipboard">Синхронізація буфера</string>
<string name="pref_plugin_clipboard_desc">Спільне використання буфера обміну даними</string>
<string name="pref_plugin_mpris">Дистанційне керування відтворенням</string>
<string name="pref_plugin_mpris_desc">Керування відтворенням звуку та відео з вашого телефону</string>
<string name="pref_plugin_ping">Підтримання зв’язку</string>
<string name="pref_plugin_ping_desc">Надсилання і отримання сигналів підтримання зв’язку</string>
<string name="pref_plugin_notifications">Синхронізація сповіщень</string>
<string name="pref_plugin_notifications_desc">Доступ до ваших сповіщень з інших пристроїв</string>
<string name="plugin_not_available">Ця можливість є недоступною для вашої версії для Android</string>
<string name="device_list_empty">Немає пристроїв</string>
<string name="ok">Гаразд</string>
<string name="cancel">Скасувати</string>
<string name="open_settings">Відкрити вікно параметрів</string>
<string name="no_permissions">Вам слід надати доступ до сповіщень</string>
<string name="send_ping">Надіслати сигнал підтримання зв’язку</string>
<string name="open_mpris_controls">Відкрити дистанційне керування</string>
<string name="category_connected_devices">З’єднані пристрої</string>
<string name="category_not_paired_devices">Непов’язані пристрої</string>
<string name="category_remembered_devices">Відомі пристрої</string>
<string name="plugins_failed_to_load">Додатки, які не вдалося завантажити (натисніть, щоб дізнатися більше):</string>
<string name="device_menu_plugins">Виберіть додатки</string>
<string name="device_menu_unpair">Скасувати пов’язування</string>
<string name="unknown_device">Невідомий пристрій</string>
<string name="error_not_reachable">Немає доступу до пристрою</string>
<string name="error_already_requested">Запит щодо пов’язування вже надіслано</string>
<string name="error_already_paired">Пристрій вже пов’язано</string>
<string name="error_could_not_send_package">Не вдалося надіслати пакунок</string>
<string name="error_timed_out">Час очікування вичерпано</string>
<string name="error_canceled_by_user">Скасовано користувачем</string>
<string name="error_canceled_by_other_peer">Скасовано з іншого вузла пов’язування</string>
<string name="error_invalid_key">Отримано некоректний ключ</string>
<string name="pair_requested">Запит щодо пов’язування</string>
<string name="pairing_request_from">Запит щодо пов’язування від %1s</string>
<string name="tap_to_answer">Натисніть, щоб відповісти</string>
<string name="reconnect">З\'єднати знову</string>
<string name="device_not_paired">Пристрій не пов’язано</string>
<string name="request_pairing">Надіслати запит щодо пов’язування</string>
<string name="pairing_accept">Прийняти</string>
<string name="pairing_reject">Відмовити</string>
<string name="device">Пристрій</string>
<string name="pair_device">Пов’язати пристрій</string>
<string name="remote_control">Дистанційне керування</string>
<string name="settings">Параметри з’єднання з KDE</string>
<string name="mpris_play">Пуск</string>
<string name="mpris_previous">Назад</string>
<string name="mpris_rew">Повний назад</string>
<string name="mpris_ff">Повний вперед</string>
<string name="mpris_next">Далі</string>
<string name="mpris_volume">Гучність</string>
<string name="share_to">Спільно використовувати з…</string>
<string name="protocol_version_older">На цьому пристрої використовується стара версія протоколу</string>
<string name="protocol_version_newer">На цьому пристрої використовується новіша версія протоколу</string>
<string name="general_settings">Загальні параметри</string>
<string name="device_name">Назва пристрою</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Некоректна назва пристрою</string>
</resources>

View File

@@ -5,6 +5,8 @@
<string name="pref_plugin_telephony_desc">Send notifications for SMS and calls</string>
<string name="pref_plugin_battery">Battery report</string>
<string name="pref_plugin_battery_desc">Periodically report battery status</string>
<string name="pref_plugin_sftp">Filesystem expose</string>
<string name="pref_plugin_sftp_desc">Allows to browse the phone\'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_mpris">Multimedia remote controls</string>
@@ -50,11 +52,16 @@
<string name="settings">KDE Connect Settings</string>
<string name="mpris_play">Play</string>
<string name="mpris_previous">Previous</string>
<string name="mpris_rew">Rewind</string>
<string name="mpris_ff">Fast-forward</string>
<string name="mpris_next">Next</string>
<string name="mpris_volume">Volume</string>
<string name="share_to">Share To...</string>
<string name="protocol_version_older">This device uses an old protocol version</string>
<string name="protocol_version_newer">This device uses a newer protocol version</string>
<string name="general_settings">General Settings</string>
<string name="device_name">Device name</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Invalid device name</string>
</resources>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/general_settings">
<EditTextPreference
android:key="device_name_preference"
android:title="@string/device_name"
android:summary="@string/device_name_preference_summary"
android:dialogTitle="@string/device_name"
android:singleLine="true" />
</PreferenceCategory>
</PreferenceScreen>