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

Compare commits

..

128 Commits

Author SHA1 Message Date
Albert Vaca
b1dcc3c40f Bumped version to release 2018-05-15 00:55:28 +02:00
Albert Vaca
f5254e504d Hopefully fixed crash in Android 8.1 2018-05-15 00:55:28 +02:00
Albert Vaca
55a0ad657e Bumped version to release 2018-05-15 00:55:28 +02:00
l10n daemon script
8add0c4fbe GIT_SILENT made messages (after extraction) 2018-05-14 03:35:55 +02:00
l10n daemon script
187e47aec2 GIT_SILENT made messages (after extraction) 2018-05-13 03:25:31 +02:00
l10n daemon script
27b390a9bd GIT_SILENT made messages (after extraction) 2018-05-12 03:31:41 +02:00
Nicolas Fella
9bf5a9c489 Fix SharePlugin devices list
Summary: D12212 broke the devices list in the SharePlugin. No devices was shown even when there were devices available.

Test Plan: Open up share devices list with 0/1 devices available

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: kdeconnect, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12334
2018-05-11 21:18:58 +02:00
l10n daemon script
a907c02ecf GIT_SILENT made messages (after extraction) 2018-05-11 03:42:17 +02:00
Nicolas Fella
4deeb5e061 Send Runcommand setup package from phone
Summary: Also remove some leftover code from the prevoius attempt

Test Plan: Open command list, click Floating Action Button, look for KCM window on desktop.

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: albertvaka, kdeconnect, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12332
2018-05-10 19:47:15 +02:00
Nicolas Fella
ff2354a7a6 Update gitignore 2018-05-10 19:01:32 +02:00
Yoann Laissus
5463be96a4 Add detection of Android TV devices with a proper icon
KDE app :  https://phabricator.kde.org/D12802

Test Plan: Tested with an Android TV device (Nvidia Shield)

Reviewers: #kde_connect, nicolasfella

Reviewed By: #kde_connect, nicolasfella

Subscribers: tfella, nicolasfella, kdeconnect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12803
2018-05-10 17:02:45 +02:00
Nicolas Fella
0c6b584d57 [WIP] Add MprisReceiverPlugin (Android)
Summary:
Exposes media sessions to the desktop for use with the MprisRemote plugin and the app.
Still contains some Logs, will remove them when its time.

Test Plan:
What works:
- Displaying and updating title, artist and album.
- PlayPause, next and previous
- Playing state
- multiple sessions

What doesn't work:
- volume control
- length and position
- Album art
- can* abilities are not exposed, e.g. canGoNext, not sure if possible at all

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: kdeconnect, mtijink, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12559
2018-05-09 15:30:06 +02:00
Nicolas Fella
e712c69e15 Use lambdas where possible
Summary: Let Android Studio replace anonymous types with lambdas. No manual code change.

Test Plan: Compile and superficial behaviour test

Reviewers: #kde_connect, philipc

Reviewed By: #kde_connect, philipc

Subscribers: philipc, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12229
2018-05-09 14:03:08 +02:00
l10n daemon script
7536eb7427 GIT_SILENT made messages (after extraction) 2018-05-05 03:26:35 +02:00
l10n daemon script
04e5f6b451 GIT_SILENT made messages (after extraction) 2018-05-04 03:29:32 +02:00
l10n daemon script
f75bf2129a GIT_SILENT made messages (after extraction) 2018-05-03 03:36:08 +02:00
Albert Vaca
acd98da83a Upgraded gradle 2018-05-01 19:30:32 +02:00
Matthijs Tijink
d6c3803ea2 Add assertions and checks to album art fetch code
Summary:
Add a couple of assertions and checks to the album art fetch code. Hopefully fixes bug https://bugs.kde.org/show_bug.cgi?id=393274, or otherwise at least gives a bit more information.

BUG 393274

Test Plan: Fixes the bug, according to the reporter.

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: albertvaka, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12618
2018-05-01 19:27:24 +02:00
Albert Vaca
d688621f27 Set hardcoded 'Dark theme' switch to be translatable 2018-05-01 19:09:31 +02:00
l10n daemon script
774759746d GIT_SILENT made messages (after extraction) 2018-04-30 03:34:10 +02:00
Nicolas Fella
d65b3153ae Bump gradle version
Reviewers: #kde_connect, philipc

Reviewed By: #kde_connect, philipc

Subscribers: philipc, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12501
2018-04-27 21:23:07 +02:00
Nicolas Fella
8a2ea77030 Add marginEnd for RTL layouts
Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12345
2018-04-24 19:58:48 +02:00
Philip Cohn-Cort
a1f1693d0b Add a dark theme
Summary:
BUG: 375376

This revision adds dark mode support to the app ( T7044 ). It does so by injecting
theme information into each activity, and making sure that all Views
define their colors by reference to theme attributes.

In order to make this work, all of the buttons with images (like the list
of available devices) now are tinted according to the theme.

While all versions of android support the theme, only devices running
Android ICS or higher will have a toggle button in the drawer.

Test Plan: Open all the screens, both with and without the dark theme on.

Reviewers: #kde_connect, mtijink, #vdg, nicolasfella

Reviewed By: #kde_connect, mtijink, nicolasfella

Subscribers: apol, ngraham, nicolasfella, mtijink

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D11694
2018-04-23 18:35:43 +02:00
l10n daemon script
b228fb2377 GIT_SILENT made messages (after extraction) 2018-04-23 03:30:04 +02:00
Nicolas Fella
bc330018e1 Rename list layout
Summary: Give it a proper name

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12289
2018-04-17 20:50:23 +02:00
Nicolas Fella
9837c89f35 Hide Available devices section if no devices are available
Summary:
Before:
{F5807970}

After:
{F5807971}

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12212
2018-04-17 20:48:08 +02:00
Simon Redman
4d2357f016 Allow JSONObject in a NetworkPacket
Summary: Allow a mapping of fields to be a field of a NetworkPacket

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: albertvaka, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D11870
2018-04-17 19:03:46 +02:00
Karl Heinz
d4d9e8ba6d Update DeviceHelper.java 2018-04-16 16:55:31 +02:00
Matthijs Tijink
2cd7d4b7a9 Fix default Find My Phone ringtone
Summary:
Previously, if the user hadn't set a ringtone, the code raised an exception (because an empty string isn't an uri). Thus, no sound was played.

This fixes it.

BUG: 392853

Test Plan: Without having set a ringtone, it works. Otherwise, it works too.

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: nicolasfella, sredman, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D12070
2018-04-09 19:00:55 +02:00
l10n daemon script
8bbd3f55b1 GIT_SILENT made messages (after extraction) 2018-04-09 03:23:13 +02:00
Albert Vaca
1bf96454cf required is not part of the uses-permission tag
BUG: 392856
2018-04-08 17:20:48 +02:00
l10n daemon script
6883ed2847 GIT_SILENT made messages (after extraction) 2018-04-07 03:23:18 +02:00
l10n daemon script
91be51ea5a GIT_SILENT made messages (after extraction) 2018-04-06 03:31:04 +02:00
l10n daemon script
3bb54816ed GIT_SILENT made messages (after extraction) 2018-04-04 03:26:25 +02:00
l10n daemon script
810f53449a GIT_SILENT made messages (after extraction) 2018-04-03 03:28:03 +02:00
l10n daemon script
efa4668448 GIT_SILENT made messages (after extraction) 2018-04-01 03:29:58 +02:00
l10n daemon script
b70370005b GIT_SILENT made messages (after extraction) 2018-03-31 03:22:14 +02:00
l10n daemon script
9631cacb69 GIT_SILENT made messages (after extraction) 2018-03-30 03:25:50 +02:00
Matthijs Tijink
94ef1294c5 Add share action button to received file notification
Summary: You can share the just-received file. It doesn't work with a custom download directory (just like opening such files doesn't work yet). It also won't close the notification once shared.

Test Plan: Sharing to other apps works.

Reviewers: #kde_connect, nicolasfella

Reviewed By: #kde_connect, nicolasfella

Subscribers: nicolasfella, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D11680
2018-03-28 22:58:27 +02:00
Matthijs Tijink
7c8301a7cc Disables album art download on metered connections (e.g. 4G)
Summary: Won't typically be a problem (you're usually connected via wifi with KDE Connect anyway), but shouldn't hurt.

Test Plan: Works with the bluetooth backend on 4G (i.e. no album art is downloaded). Still downloads album art otherwise, as expected.

Reviewers: #kde_connect, nicolasfella

Reviewed By: #kde_connect, nicolasfella

Subscribers: #kde_connect

Differential Revision: https://phabricator.kde.org/D11682
2018-03-27 21:23:08 +02:00
Albert Vaca
64fd08f3ac Bump version to release 2018-03-27 20:34:56 +02:00
Albert Vaca
e67e43efa1 Revert "Synchronize everything to see if this fixes a crash in 8.1"
This reverts commit cf808c03ba.
and commit 3d4bf643d4.
2018-03-27 20:34:56 +02:00
Philip Cohn-Cort
fda08929af Add method documentation to LanLinkProvider.java
Summary:
This adds some simple explanation to the `identityPacketReceived` and
`addLink` methods.

Test Plan: N/A

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Differential Revision: https://phabricator.kde.org/D11672
2018-03-26 13:54:04 +02:00
Albert Vaca
2cb025e368 Bump version to release 2018-03-25 22:01:06 +02:00
Albert Vaca
cf808c03ba Add timeout so handshake doesn't block forever 2018-03-25 22:00:39 +02:00
Albert Vaca
2b52cd1547 Bumped version to release 2018-03-25 20:42:52 +02:00
Albert Vaca
3d4bf643d4 Synchronize everything to see if this fixes a crash in 8.1 2018-03-25 20:33:19 +02:00
Matthijs Tijink
00b6677aa4 When receiving a file Android, show the image in the notification
Summary: The image is shown, similar to when you take a screenshot.

Test Plan: Works great! Doesn't crash for non-images.

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: #kde_connect

Differential Revision: https://phabricator.kde.org/D11679
2018-03-25 14:51:12 +02:00
Matthijs Tijink
bf0cab9ef2 Support file url album art - Android
Summary: If the album art is a file url, the code will ask the remote device to transfer that file. It's then stored in the album art cache.

Test Plan: Works fine for me, even when quickly skipping songs.

Reviewers: #kde_connect, nicolasfella, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: albertvaka, nicolasfella, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D11018
2018-03-25 13:41:40 +02:00
Matthijs Tijink
1c3e6f84a7 Add album art to media notification and lock screen
Summary:
Adds the album art to the media notification and lock screen.

How it looks on my phone (disregard the somewhat weird look, that's just the weird UI my phone vendor uses):
{F5728066}

Google images shows how it'll look on other phones (this one includes the lock screen image):
{F5728069}

And Android Oreo automatically colors the notification based on the album art color (untested, but should work):
{F5728070}

Test Plan: Changes are minor and it works fine for me.

Reviewers: #kde_connect, nicolasfella, albertvaka

Reviewed By: #kde_connect, nicolasfella, albertvaka

Subscribers: nicolasfella

Differential Revision: https://phabricator.kde.org/D10798
2018-03-25 13:39:17 +02:00
Matthijs Tijink
c8dbbb1fe8 Show connected devices on top
Summary: After that, available devices and then remembered devices.

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: nicolasfella, #kde_connect

Differential Revision: https://phabricator.kde.org/D11641
2018-03-24 21:55:53 +01:00
Philip Cohn-Cort
a17b75264d Use simpler syntax for Google Maven repository
Summary: This follows the guidelines described at https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html#apply_plugin

Test Plan: Try to build with this change (`./gradlew assembleRelease` or similar)

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Differential Revision: https://phabricator.kde.org/D11645
2018-03-24 20:23:11 +01:00
Philip Cohn-Cort
7276e60aa4 Only make one request for list of MPRIS players during plugin creation
Summary:
MPrisPlugin previously made two calls to `requestPlayerList()` in its
`onCreate()` method. This change deletes the first of those, so that
only one network packet is sent and received.

Test Plan:
Pair a new device, confirm that only one request for media players is
received by remote client.

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Differential Revision: https://phabricator.kde.org/D11648
2018-03-24 18:38:23 +01:00
Matthijs Tijink
7877d2803c Fix blurry rasterized icons
Summary:
The vector icons were rastizered for older Android versions, but these were on the small side. This fixes the size.

BUG: 392061

Test Plan: The icons aren't blurry anymore on Android 4.2.

Reviewers: #kde_connect, nicolasfella

Reviewed By: #kde_connect, nicolasfella

Subscribers: #kde_connect

Differential Revision: https://phabricator.kde.org/D11644
2018-03-24 18:35:07 +01:00
Matthijs Tijink
b1c4b6e1e9 Show the same mpris player in the notification as in the app
Summary:
So switching (currently playing) players in the app will also switch the
notification.

Test Plan: Tested with two players playing at the same time, and switching between them.

Reviewers: #kde_connect, nicolasfella

Reviewed By: #kde_connect, nicolasfella

Subscribers: #kde_connect

Differential Revision: https://phabricator.kde.org/D11647
2018-03-24 18:34:35 +01:00
Matthijs Tijink
eb801fa535 Don't show flash of pairing buttons when opening a device
Summary:
The buttons are now hidden, and only showed once we know that the device
is unpaired.

Test Plan: Pairing, pairing request and opening a device still work.

Reviewers: #kde_connect, nicolasfella

Reviewed By: #kde_connect, nicolasfella

Subscribers: #kde_connect

Differential Revision: https://phabricator.kde.org/D11627
2018-03-24 11:07:46 +01:00
Nicolas Fella
ac4aaf1b39 Make MPRIS Activity singletop 2018-03-23 22:20:13 +01:00
Matthijs Tijink
9840a39992 Always show/hide both next and previous buttons
Summary: As @kossebau mentioned, a disappearing "previous" button is not really great, since you'll likely press "next". This diff makes sure that when you can press previous and/or next, both buttons are shown (potentially disabled).

Test Plan: Works in all combinations of enabled/disabled for both buttons

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: kossebau, #kde_connect

Differential Revision: https://phabricator.kde.org/D11437
2018-03-23 19:18:41 +01:00
l10n daemon script
e73c18d2e3 GIT_SILENT made messages (after extraction) 2018-03-17 03:13:39 +01:00
Albert Vaca
dbdbb0496b Bump version to release 2018-03-15 23:51:30 +01:00
Albert Vaca
5a0b5673ed Do not send the group summary notifications
Reviewed by Aleix Pol
2018-03-15 23:47:35 +01:00
Albert Vaca
2962ebf61f Don't hide media controls in lock screen 2018-03-15 23:17:48 +01:00
Albert Vaca
d0e1175f4a Remove unecessary allocations in a loop
Plus database not being closed on return
2018-03-15 20:26:55 +01:00
l10n daemon script
41ce204a12 GIT_SILENT made messages (after extraction) 2018-03-15 03:17:50 +01:00
l10n daemon script
20a9e69d1d GIT_SILENT made messages (after extraction) 2018-03-12 03:13:38 +01:00
l10n daemon script
28af7672da GIT_SILENT made messages (after extraction) 2018-03-11 03:15:01 +01:00
l10n daemon script
014bfacd89 GIT_SILENT made messages (after extraction) 2018-03-09 03:13:42 +01:00
l10n daemon script
2d21d9e868 GIT_SILENT made messages (after extraction) 2018-03-07 03:20:21 +01:00
l10n daemon script
cec8d9de3f GIT_SILENT made messages (after extraction) 2018-03-06 03:17:05 +01:00
Albert Vaca
9b70e1e61f Rename NetworkPackage -> NetworkPacket
Summary: KDE Connect, now with correct naming!

Test Plan: It still builds.

Reviewers: #kde_connect, apol, nicolasfella

Reviewed By: #kde_connect, apol, nicolasfella

Subscribers: nicolasfella, apol

Differential Revision: https://phabricator.kde.org/D11035
2018-03-05 20:07:29 +01:00
Nicolas Fella
fbeb5523b4 Use sp instead of dp for text size
Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D11016
2018-03-04 14:40:16 +01:00
Nicolas Fella
ae0538ae0c Make it possible to add commands for the RunCommandsPlugin from Android
Summary: Add an ActionBar entry for adding a command to the list. The current way to add commands is quite hidden.

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: philipc, mtijink, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D7959
2018-03-04 14:38:20 +01:00
Nicolas Fella
f615a0f7f9 Clean up TelepathyPlugin
Summary:
Depends on D10907

Remove permission checks, unused imports, empty methode
Inline permissionexplanation

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10908
2018-03-04 13:22:06 +01:00
Nicolas Fella
679b163bd5 Clean up CustomDevicesActivity
Summary: Won't have a practical impact, but Lint is happy

Test Plan: Add entries to ip list

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10949
2018-03-04 13:20:03 +01:00
Nicolas Fella
fb7dc4be65 Use correct plural
Summary: Some languages have more plurals than the english language. This enables translaters to select the appropriate plural form.

Test Plan: No change in english

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D11001
2018-03-04 13:18:59 +01:00
Nicolas Fella
22e65626cc Fix accessibility issues
Summary: Add some image contentDescriptions and one focusable property

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D11004
2018-03-04 13:18:21 +01:00
Nicolas Fella
961f8e0308 Delete unused file
Test Plan: Android Studios Safe delete did not find any usage

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D11005
2018-03-04 13:17:51 +01:00
Nicolas Fella
8d9681a05d Avoid empty XML tags
Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D11006
2018-03-04 13:16:22 +01:00
Matthijs Tijink
59f72f658a Change mpris play/pause button color instead of removing it
Summary:
This prevents issues with buttons jumping around when canPlay/canPause is false, as some mpris players do not report consistent values.

Additionally, gives the play/pause button a bit more attention when enabled. What do you think?

When playing/pausing is enabled (i.e. nearly always):
{F5728047}

When disabled:
{F5728048}

Reviewers: #kde_connect, #vdg, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: albertvaka, nicolasfella

Differential Revision: https://phabricator.kde.org/D10796
2018-03-04 11:54:40 +01:00
l10n daemon script
f42993d03f GIT_SILENT made messages (after extraction) 2018-03-04 03:17:22 +01:00
Nicolas Fella
e72e0f61dd Rename MaterialActivity to MainActivity
Summary: Its more descriptive

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10951
2018-03-03 19:35:29 +01:00
Nicolas Fella
889251ed94 Avoid deprecated API
Summary:
Depends on D10905

Use proper API

Test Plan: Pairing a device and using the drawer is still possible.

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10934
2018-03-03 16:28:35 +01:00
Nicolas Fella
93c19cbb76 Convert fields to local variables
Summary:
Depends on D10905

Convert to local variables where Android Studio suggested

Test Plan: Compiles

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10911
2018-03-03 16:26:53 +01:00
Nicolas Fella
1456026bfc Simplify switch to if statement
Summary: Depends on D10946

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10947
2018-03-03 16:24:17 +01:00
Nicolas Fella
b54d4948d7 Remove commented code for real 2018-03-03 16:22:28 +01:00
Nicolas Fella
cfb7da7fd3 Merge branch 'master' of git://anongit.kde.org/kdeconnect-android 2018-03-03 16:18:00 +01:00
Nicolas Fella
ee952b0b3a Remove commented code
Summary: Depends on D10905

Test Plan: Compiles

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10907
2018-03-03 16:15:41 +01:00
Nicolas Fella
60049dab2a Apply coding style to whole project
Summary: Sorry for the huge diff, but all I did was applying Android Studio's 'Reformat Code' to all files. If everyone does that before submitting a patch we can keep it clean easily.

Test Plan: Compiles

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, sredman, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10905
2018-03-03 16:14:42 +01:00
Nicolas Fella
c2e9edc09c Remove unnecessary semicolons
Summary: Depends on D10905

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10946
2018-03-03 16:11:27 +01:00
Nicolas Fella
fa5a37c472 Apply coding style to whole project
Summary: Sorry for the huge diff, but all I did was applying Android Studio's 'Reformat Code' to all files. If everyone does that before submitting a patch we can keep it clean easily.

Test Plan: Compiles

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, sredman, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10905
2018-03-03 16:09:52 +01:00
Nicolas Fella
0a08cd43cb Inline more variables
Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10945
2018-03-03 15:56:32 +01:00
Nicolas Fella
49021b87af Remove unused imports
Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10948
2018-03-03 15:50:40 +01:00
Nicolas Fella
959c7c7220 Correctly handle changing canPlay, canPause, canGoNext and canGoPrevious
Summary:
Gwenview is adding MPRIS support in D10972. I tested it and noticed that it was quite buggy. Turns out,
Gwenviews implementation is (almost) fine, the problem was on our side. Unlike pure music players like
Spotify Gwenview changes canPlay, canPause, canGoNext and canGoPrevious when needed, but those updates
didn't reach our UI. The packages containing those updates were not parsed because they didn't contain
several fields.

Test Plan: Controlling Spotify and Gwenview (patched to support playPause)  works fine now.

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10981
2018-03-03 15:26:49 +01:00
Nicolas Fella
6aa75a2e7e Format AndroidManifest.xml
Summary: Format it properly, replace empty bodies with sef-closing tag and remove commented tags

Test Plan: Runs

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10969
2018-03-03 15:25:20 +01:00
Kai Dombrowe
0b0b90f778 Fix stuck notifications in the share plugin
Summary:
Android has a rate limit for updating notifications which was reduced
from 50 to 10 updates/sec since Nougat.
The share plugin updates the progress every time the percentage changes.
The final notification update which makes the notification removable,
is ignored if this happens more than 10 times in a second.
This patch reduces the progress updates to a maximum of 10 times per second.
BUG: 391059

Reviewers: #kde_connect, nicolasfella

Reviewed By: #kde_connect, nicolasfella

Subscribers: nicolasfella, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10976
2018-03-03 15:17:27 +01:00
Matthijs Tijink
702977a01d Fix album art url canonicalization 2018-03-03 14:45:26 +01:00
l10n daemon script
6d84f5dd86 GIT_SILENT made messages (after extraction) 2018-03-01 03:24:15 +01:00
Nicolas Fella
79a933708e Remove unneded return 2018-03-01 02:45:21 +01:00
l10n daemon script
e8f9e2daf0 GIT_SILENT made messages (after extraction) 2018-02-28 03:17:07 +01:00
Tobias Fella
7130421624 Make encryption info available while not paired
Summary:
BUG:385796
 Make encryption info available while there is no device paired. Previously, the menu option to show it was hidden when not connected.

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, #kde_connect

Tags: #kde_connect

Maniphest Tasks: T7212

Differential Revision: https://phabricator.kde.org/D10841
2018-02-26 19:40:08 +01:00
l10n daemon script
6ccae1ca45 GIT_SILENT made messages (after extraction) 2018-02-26 03:15:09 +01:00
Matthijs Tijink
f280e8f44e Prefer selecting the playing player in the MPRIS activity
Summary: Previously, the MPRIS activity just showed the first player in the list when you opened the activity. Now it shows a playing player, when possible.

Test Plan: Tested with zero, one and multiple players, and with both playing and not playing players.

Reviewers: #kde_connect, nicolasfella

Reviewed By: #kde_connect, nicolasfella

Differential Revision: https://phabricator.kde.org/D10821
2018-02-25 16:42:24 +01:00
Matthijs Tijink
abc5526252 Put keyboard button in navigation bar when possible
Summary:
In the remote input activity, the keyboard button was in the overflow menu, even though it fit on the navigation bar. The previous code used the wrong namespace, so this fixes it.

BUG: 390640

Before:
{F5729325}

After:
{F5729326}

Reviewers: #kde_connect, nicolasfella

Reviewed By: #kde_connect, nicolasfella

Subscribers: nicolasfella

Differential Revision: https://phabricator.kde.org/D10827
2018-02-25 16:41:34 +01:00
Matthijs Tijink
63349d3643 Use small notification icons when available
Summary:
The notification plugin now sends small notification icons, if the large
icon is not available.

Before patch, with icon:

{F5698607}

{F5698608}

Before patch, without icon:

{F5698612}

{F5698613}

After patch, without icon:

{F5698614}

{F5698616}

Test Plan: I tested notifications with small icons and those with large icons, and it works as expected.

Reviewers: #kde_connect, #vdg, fabianr, albertvaka

Reviewed By: #kde_connect, #vdg, fabianr, albertvaka

Subscribers: albertvaka, mmustac, fabianr, apol, nicolasfella

Differential Revision: https://phabricator.kde.org/D10165
2018-02-25 11:43:28 +01:00
l10n daemon script
d931820d09 GIT_SILENT made messages (after extraction) 2018-02-25 03:17:21 +01:00
Matthijs Tijink
2f127b3047 Add MPRIS media control notification
Summary:
BUG: 337485

Adds a notification to show and control mpris players. It shows the title, artist etc. (so depends on D9083, but can easily be adapted to work without it, but that leads to less features).

The notification appears as soon as one of your connected devices plays music. If multiple devices/players are playing, it shows the information and controls for only one of these. If it stops playing, it tries to switch to another playing device/player. If those do not exist, it shows the same player, but allows starting it again.

Dismissing the notification is only possible if the showed player is paused (as effect, only when all players are paused). It automatically closes if the device or player disappears or disconnects and no other players are playing. I think this behaviour is intuitive, other native android music players have similar behaviour.

About the implementation: there are two parts to this: the notification and the media session control API. The first shows the notification and its controls. The second allows lock screen controls on older Android versions and control using e.g. headphone buttons. Since nearly all code is shared between the two parts, and the rest is mostly straightforward, I put them in the same diff.

Test Plan:
Tested on Android Nougat 7.1 (shows the notification with buttons, as expected; no lock screen controls, as expected) and Android Gingerbread 2.3 (shows a notification without buttons, lock screen controls work, so as expected).

I am not able to test with multiple desktops, so testing that would be appreciated.

Disabling buttons when not available should work, but all players I tested always allowed next/previous/play/pause.

Reviewers: #kde_connect, nicolasfella

Reviewed By: #kde_connect, nicolasfella

Subscribers: apol, albertvaka, nicolasfella

Tags: #kde_connect

Maniphest Tasks: T6512

Differential Revision: https://phabricator.kde.org/D9266
2018-02-24 17:01:08 +01:00
Matthijs Tijink
0d00b8aa4a Add album cover art support.
Summary:
Fetches http(s) album art urls, as supplied by MPRIS, to display as album art. Fetched urls and failed fetches are cached to prevent unneccessary network activity.

The bulk of the code is in the fetching+caching class `AlbumArtCache`.

Takes the comments from d52be10 into account:
 - The images (HTTP(S) only for now) are cached. This is limited to 5 MB on disk or 10 entries in memory.
 - The image gets viewing space depending on the remaining screen space. Thus, controls should never be pushed off-screen.
 - "Edge cases" like going from cover art to no cover art is handled correctly (actually a result of earlier mpris code changes).

Additionally, it adds a landscape mode to the MPRIS activity, which shows the cover art and controls side by side.

Desktop part is in D9563.

FEATURE: 345015

Test Plan: Works both with/without album art. Switching players and tracks correctly changes the album art.

Reviewers: #kde_connect, #vdg, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: albertvaka, ngraham, nicolasfella, apol

Differential Revision: https://phabricator.kde.org/D9564
2018-02-24 16:21:11 +01:00
Nicolas Fella
e9a35d3bb2 Allow to blacklist numbers in the telephony plugin
Summary:
Depends on D10519

Allow to specify a newline separated list of blocked numbers. This can be useful for 2FA/TAN that could be leaked to the desktop.

The protection is incomplete because the notification might be leaked trough the notificationsplugin anyway (T6651).

Test Plan:
Block my number, send SMS to self -> only notification from Notificationsplugin is shown.
Unblock it again -> both notifications are shown

Reviewers: #kde_connect, albertvaka, mtijink

Reviewed By: #kde_connect, albertvaka, mtijink

Subscribers: mtijink, albertvaka, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10520
2018-02-24 15:53:56 +01:00
l10n daemon script
101918f323 GIT_SILENT made messages (after extraction) 2018-02-24 03:16:06 +01:00
l10n daemon script
d8c0b40b9c GIT_SILENT made messages (after extraction) 2018-02-23 03:22:19 +01:00
Nicolas Fella
4d5d744920 Allow choosing a ringtone for FindMyPhone
Summary:
BUG: 379023

Let users choose a ring tone in the settings.

Test Plan: Open settings, choose a ringtone, search for device.

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: mtijink, andyholmes, albertvaka, apol, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10332
2018-02-22 00:50:32 +01:00
Nicolas Fella
82db080a51 Apply some coding style to TelephonyPlugin
Summary: Unify coding style, remove commented code

Reviewers: #kde_connect, albertvaka

Reviewed By: #kde_connect, albertvaka

Subscribers: albertvaka, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D10519
2018-02-22 00:49:04 +01:00
l10n daemon script
97d69c674a GIT_SILENT made messages (after extraction) 2018-02-19 03:09:08 +01:00
Albert Vaca
7dd4583a24 Increased version number to release 2018-02-17 10:07:57 +01:00
Nicolas Fella
c05f13afac Loop ringtone in FindMyPhonePlugin
Summary:
BUG: 368089

FindMyPhone does not loop ringtones, which makes problems with short ringtones. Additionally, it depends on the volume of the alarm channel, so if the alarms are muted, no
sound can be heard. This patch raises the alarm volume to max when the activity gets started and restores the previous value when it stops.

Test Plan: Trigger findmyphone, hear sound looping. Set alarm volume to zero and check if it gets restored.

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: mtijink, #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D9947
2018-02-01 11:47:45 +01:00
Nicolas Fella
de7d944230 Get rid of MaxWidthImageButton
Summary: There is no need to implement a custom view for that. It is only used in MPRIS Activity, which looks almost the same now, except that the play button aligns with the buttons beneath, which is better IMHO.

Reviewers: #kde_connect, mtijink

Reviewed By: #kde_connect, mtijink

Subscribers: #kde_connect

Tags: #kde_connect

Differential Revision: https://phabricator.kde.org/D9520
2018-02-01 11:45:28 +01:00
l10n daemon script
b1daf1af0c GIT_SILENT made messages (after extraction) 2018-01-30 03:15:19 +01:00
l10n daemon script
baeec6afbf GIT_SILENT made messages (after extraction) 2018-01-29 03:17:09 +01:00
l10n daemon script
2187b273b9 GIT_SILENT made messages (after extraction) 2018-01-28 03:16:00 +01:00
l10n daemon script
1fa0585100 GIT_SILENT made messages (after extraction) 2018-01-27 03:15:25 +01:00
l10n daemon script
4e2460bf37 GIT_SILENT made messages (after extraction) 2018-01-25 03:18:02 +01:00
l10n daemon script
5e3e32d289 GIT_SILENT made messages (after extraction) 2018-01-23 03:18:45 +01:00
Albert Vaca
167f86affa Fix gradle deprecation warnings 2018-01-23 00:41:33 +01:00
Albert Vaca
53dfb299a7 Fix build from gradle's cli 2018-01-23 00:41:33 +01:00
l10n daemon script
c4e6c66809 GIT_SILENT made messages (after extraction) 2018-01-22 03:09:49 +01:00
l10n daemon script
1703276f37 GIT_SILENT made messages (after extraction) 2018-01-21 03:12:07 +01:00
Chris Holland
91ade6a846 Mention 2 fingers to scroll in mousepad_info
BUG: 389185

Differential Revision: https://phabricator.kde.org/D9977
2018-01-19 01:03:00 -05:00
Albert Vaca
1b62a5ae32 Use stringbuilder 2018-01-17 00:05:57 +01:00
169 changed files with 5553 additions and 3705 deletions

1
.gitignore vendored
View File

@@ -13,3 +13,4 @@ gradlew.bat
*.iml
*.keystore
.directory
GPUCache/

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="1710"
android:versionName="1.7.1">
android:versionCode="1840"
android:versionName="1.8.4">
<supports-screens
android:anyDensity="true"
@@ -11,7 +11,9 @@
android:smallScreens="true"
android:xlargeScreens="true" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<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" />
@@ -20,10 +22,10 @@
<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.BATTERY_STATS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" android:required="false" />
<uses-permission android:name="android.permission.RECEIVE_SMS" android:required="false" />
<uses-permission android:name="android.permission.SEND_SMS" android:required="false" />
<uses-permission android:name="android.permission.READ_SMS" android:required="false" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<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" />
@@ -34,25 +36,26 @@
android:icon="@drawable/icon"
android:label="KDE Connect"
android:supportsRtl="true"
android:theme="@style/KdeConnectTheme"
>
android:theme="@style/KdeConnectTheme">
<service
android:name="org.kde.kdeconnect.BackgroundService"
android:enabled="true" >
</service>
android:enabled="true" />
<service android:name="org.kde.kdeconnect.Plugins.RemoteKeyboardPlugin.RemoteKeyboardService"
<service
android:name="org.kde.kdeconnect.Plugins.RemoteKeyboardPlugin.RemoteKeyboardService"
android:label="KDE Connect Remote Keyboard"
android:permission="android.permission.BIND_INPUT_METHOD">
<intent-filter>
<action android:name="android.view.InputMethod" />
</intent-filter>
<meta-data android:name="android.view.im" android:resource="@xml/remotekeyboardplugin_method" />
<meta-data
android:name="android.view.im"
android:resource="@xml/remotekeyboardplugin_method" />
</service>
<activity
android:name="org.kde.kdeconnect.UserInterface.MaterialActivity"
android:name="org.kde.kdeconnect.UserInterface.MainActivity"
android:label="KDE Connect"
android:theme="@style/KdeConnectTheme.NoActionBar">
<intent-filter>
@@ -64,31 +67,31 @@
<activity
android:name="org.kde.kdeconnect.UserInterface.SettingsActivity"
android:label="@string/device_menu_plugins"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MaterialActivity" >
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MaterialActivity" />
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.CustomDevicesActivity"
android:label="@string/custom_devices_settings"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MaterialActivity" >
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MaterialActivity" />
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.Plugins.SharePlugin.SendFileActivity"
android:label="KDE Connect"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MaterialActivity" >
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MaterialActivity" />
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.UserInterface.PluginSettingsActivity"
android:label="@string/device_menu_plugins"
android:parentActivityName="org.kde.kdeconnect.UserInterface.SettingsActivity" >
android:parentActivityName="org.kde.kdeconnect.UserInterface.SettingsActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.SettingsActivity" />
@@ -96,15 +99,14 @@
<activity
android:name="org.kde.kdeconnect.Plugins.SharePlugin.ShareSettingsActivity"
android:label="@string/device_menu_plugins"
android:parentActivityName="org.kde.kdeconnect.UserInterface.SettingsActivity" >
android:parentActivityName="org.kde.kdeconnect.UserInterface.SettingsActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.Plugins.SharePlugin.ShareSettingsActivity" />
</activity>
<receiver android:name="org.kde.kdeconnect.KdeConnectBroadcastReceiver" >
<receiver android:name="org.kde.kdeconnect.KdeConnectBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
@@ -122,17 +124,6 @@
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
<!--
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BATTERY_CHANGED" />
</intent-filter>
-->
</receiver>
<activity
@@ -140,43 +131,46 @@
android:configChanges="orientation|screenSize"
android:excludeFromRecents="true"
android:label="@string/findmyphone_title"
android:launchMode="singleInstance">
</activity>
android:launchMode="singleInstance" />
<!-- Plugin-related activities and services -->
<activity
android:name="org.kde.kdeconnect.Plugins.MprisPlugin.MprisActivity"
android:label="@string/remote_control"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MaterialActivity"
>
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity"
android:launchMode="singleTop">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MaterialActivity" />
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<receiver android:name="org.kde.kdeconnect.Plugins.MprisPlugin.MprisMediaNotificationReceiver">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
<activity
android:name="org.kde.kdeconnect.Plugins.RunCommandPlugin.RunCommandActivity"
android:label="@string/remote_control"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MaterialActivity"
>
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MaterialActivity" />
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.Plugins.MousePadPlugin.MousePadActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/remote_control"
android:parentActivityName="org.kde.kdeconnect.UserInterface.MaterialActivity"
android:windowSoftInputMode="stateHidden|adjustResize" >
android:parentActivityName="org.kde.kdeconnect.UserInterface.MainActivity"
android:windowSoftInputMode="stateHidden|adjustResize">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.MaterialActivity" />
android:value="org.kde.kdeconnect.UserInterface.MainActivity" />
</activity>
<activity
android:name="org.kde.kdeconnect.Plugins.SharePlugin.ShareActivity"
android:label="KDE Connect"
>
android:label="KDE Connect">
<intent-filter>
<action android:name="android.intent.action.SEND" />
@@ -191,10 +185,12 @@
<data android:mimeType="*/*" />
</intent-filter>
<meta-data
android:name="android.service.chooser.chooser_target_service"
android:value="org.kde.kdeconnect.Plugins.SharePlugin.ShareChooserTargetService" />
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="org.kde.kdeconnect_tp.fileprovider"
@@ -204,9 +200,10 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/fileprovider_paths" />
</provider>
<service
android:name="org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationReceiver"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
@@ -217,12 +214,12 @@
<intent-filter>
<action android:name="android.service.chooser.ChooserTargetService" />
</intent-filter>
</service>
</service>
<activity
android:name="org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationFilterActivity"
android:label="@string/title_activity_notification_filter"
android:parentActivityName="org.kde.kdeconnect.UserInterface.PluginSettingsActivity" >
android:parentActivityName="org.kde.kdeconnect.UserInterface.PluginSettingsActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.kde.kdeconnect.UserInterface.PluginSettingsActivity" />

View File

@@ -1,23 +1,17 @@
allprojects {
buildscript {
repositories {
jcenter()
maven {
url 'https://maven.google.com/'
name 'Google'
}
google()
}
}
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.android.tools.build:gradle:3.1.2'
}
}
apply plugin: 'com.android.application'
android {
buildToolsVersion '26.0.2'
buildToolsVersion '27.0.3'
compileSdkVersion 25
defaultConfig {
minSdkVersion 9
@@ -29,10 +23,8 @@ android {
javaMaxHeapSize "2g"
}
compileOptions {
// Use Java 1.7, requires minSdk 8
//SSHD requires mina when running on JDK < 7
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main {
@@ -75,21 +67,23 @@ android {
dependencies {
repositories {
mavenCentral()
jcenter()
google()
}
compile 'com.android.support:support-v4:25.4.0'
compile 'com.android.support:appcompat-v7:25.4.0'
compile 'com.android.support:design:25.4.0'
implementation 'com.android.support:support-v4:25.4.0'
implementation 'com.android.support:appcompat-v7:25.4.0'
implementation 'com.android.support:design:25.4.0'
implementation 'com.jakewharton:disklrucache:2.0.2' //For caching album art bitmaps
compile 'org.apache.sshd:sshd-core:0.8.0' //0.9 seems to fail on Android 6 and 1.+ requires java.nio.file, which doesn't exist in Android
implementation 'org.apache.sshd:sshd-core:0.8.0' //0.9 seems to fail on Android 6 and 1.+ requires java.nio.file, which doesn't exist in Android
compile 'com.madgag.spongycastle:pkix:1.54.0.0' //For SSL certificate generation
implementation 'com.madgag.spongycastle:pkix:1.54.0.0' //For SSL certificate generation
// Testing
androidTestCompile 'org.mockito:mockito-core:1.10.19'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.1'// Because mockito has some problems with dex environment
androidTestCompile 'org.skyscreamer:jsonassert:1.3.0'
testCompile 'junit:junit:4.12'
androidTestImplementation 'org.mockito:mockito-core:1.10.19'
androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.1'// Because mockito has some problems with dex environment
androidTestImplementation 'org.skyscreamer:jsonassert:1.3.0'
testImplementation 'junit:junit:4.12'
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

View File

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

13
res/drawable/ic_add.xml Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
<path
android:pathData="M0 0h24v24H0z" />
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="192dp"
android:height="192dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#000000"
android:pathData="M12,3v10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55 -2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4V7h4V3h-6z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M6,18l8.5,-6L6,6v12zM16,6v12h2V6h-2z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M6,19h4L10,5L6,5v14zM14,5v14h4L18,5h-4z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M8,5v14l11,-7z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M6,6h2v12L6,18zM9.5,12l8.5,6L18,6z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
</vector>

View File

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

View File

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

View File

@@ -0,0 +1,18 @@
<android.support.v7.widget.SwitchCompat
android:id="@+id/dark_theme"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="16dp"
android:paddingEnd="48dp"
android:paddingLeft="16dp"
android:paddingRight="48dp"
android:paddingStart="16dp"
android:paddingTop="4dp"
android:text="@string/dark_theme"
android:textColor="@android:color/white"
app:switchPadding="12dp"
tools:background="@drawable/drawer_header"
/>

View File

@@ -1,106 +1,120 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/activity_vertical_margin"
tools:context="org.kde.kdeconnect.UserInterface.DeviceFragment"
android:orientation="vertical">
tools:context="org.kde.kdeconnect.UserInterface.DeviceFragment">
<LinearLayout
android:id="@+id/pairing_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/pairing_buttons"
android:layout_gravity="center">
android:layout_gravity="center"
android:visibility="gone"
android:orientation="vertical">
<ProgressBar
android:visibility="gone"
android:id="@+id/pair_progress"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/pair_progress" />
android:visibility="gone" />
<TextView
android:id="@+id/pair_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/device_not_paired"
android:id="@+id/pair_message"
/>
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/pair_button"
android:background="@drawable/button_round"
android:textColor="@android:color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_round"
android:text="@string/request_pairing"
/>
android:textColor="@android:color/white" />
<LinearLayout
android:id="@+id/pair_request"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:id="@+id/pair_request"
android:layout_gravity="center">
android:layout_gravity="center"
android:visibility="gone">
<Button
android:background="@drawable/button_round"
android:textColor="@android:color/white"
android:layout_margin="4dip"
android:id="@+id/accept_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/pairing_accept"
android:layout_margin="4dip"
android:layout_weight="1"
/>
android:background="@drawable/button_round"
android:text="@string/pairing_accept"
android:textColor="@android:color/white" />
<Button
android:background="@drawable/button_round"
android:textColor="@android:color/white"
android:layout_margin="4dip"
android:id="@+id/reject_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="4dip"
android:layout_weight="1"
android:background="@drawable/button_round"
android:text="@string/pairing_reject"
android:layout_weight="1" />
android:textColor="@android:color/white" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/not_reachable_message"
android:visibility="gone"
<LinearLayout
android:id="@+id/error_message_container"
android:layout_width="match_parent"
android:drawableStart="@drawable/ic_error_outline_black_48dp"
android:drawableLeft="@drawable/ic_error_outline_black_48dp"
android:drawablePadding="8dip"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="@string/unreachable_description"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
android:orientation="horizontal"
android:gravity="center"
android:visibility="gone" >
<android.support.v7.widget.AppCompatImageView
android:id="@+id/error_message_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:importantForAccessibility="no"
android:paddingEnd="8dip"
android:paddingLeft="0dip"
android:paddingRight="8dip"
android:paddingStart="0dip"
android:src="@drawable/ic_error_outline_black_48dp"
app:tint="?attr/colorHighContrast"
tools:ignore="UnusedAttribute"/>
<TextView
android:id="@+id/not_reachable_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@string/unreachable_description"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
<TextView
android:id="@+id/on_data_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:text="@string/on_data_message"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
</LinearLayout>
<TextView
android:id="@+id/on_data_message"
android:visibility="gone"
android:layout_width="match_parent"
android:drawableStart="@drawable/ic_error_outline_black_48dp"
android:drawableLeft="@drawable/ic_error_outline_black_48dp"
android:drawablePadding="8dip"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:text="@string/on_data_message"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
<ListView
android:id="@+id/buttons_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".DeviceActivity"
/>
tools:context=".DeviceActivity" />
</LinearLayout>

View File

@@ -2,25 +2,22 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="org.kde.kdeconnect.Plugins.FindMyPhonePlugin.FindMyPhoneActivity">
<Button
android:id="@+id/bFindMyPhone"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="@string/findmyphone_found"
android:textSize="50dp"
android:id="@+id/bFindMyPhone"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
android:layout_alignParentStart="true"
android:text="@string/findmyphone_found"
android:textSize="50sp" />
</RelativeLayout>

View File

@@ -1,11 +0,0 @@
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dip"
android:paddingRight="16dip"
tools:context="org.kde.kdeconnect.UserInterface.MaterialActivity"
android:id="@+id/listView1"
android:addStatesFromChildren="true"
android:orientation="vertical">
</ListView>

View File

@@ -1,45 +1,37 @@
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="org.kde.kdeconnect.UserInterface.MaterialActivity"> <!-- fitSystemWindows to make the drawer slide below the Lollipop transparent status bar -->
tools:context="org.kde.kdeconnect.UserInterface.MainActivity"> <!-- fitSystemWindows to make the drawer slide below the Lollipop transparent status bar -->
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
android:elevation="8dp"
android:background="?attr/colorPrimary" />
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
android:layout_height="match_parent" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_drawer"
android:background="@drawable/state_list_drawer_background"
app:itemBackground="@drawable/state_list_drawer_background"
app:itemTextColor="@color/state_list_drawer_text"
app:itemIconTint="@color/state_list_drawer_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header"
/>
style="?attr/mainNavigationViewStyle" />
</android.support.v4.widget.DrawerLayout>

View File

@@ -1,25 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:keepScreenOn="true"
android:orientation="vertical"
android:id="@+id/mousepad_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mousepad_view">
android:keepScreenOn="true"
android:orientation="vertical">
<TextView
style="@android:style/TextAppearance.Medium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/mousepad_info"
android:gravity="center"
style="@android:style/TextAppearance.Medium"
android:layout_centerInParent="true"
android:padding="12dip" />
android:gravity="center"
android:padding="12dip"
android:text="@string/mousepad_info" />
<view
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/keyListener"
class="org.kde.kdeconnect.Plugins.MousePadPlugin.KeyListenerView"
android:id="@+id/keyListener" />
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="25dp"
android:paddingLeft="25dp"
android:paddingRight="25dp"
android:paddingTop="25dp">
<ImageView
android:id="@+id/album_art"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginBottom="25dp"
android:layout_weight="4"
android:contentDescription="@string/mpris_coverart_description"
android:scaleType="fitCenter" />
<include
layout="@layout/mpris_control"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

View File

@@ -6,27 +6,26 @@
tools:context="org.kde.kdeconnect.Plugins.NotificationsPlugin.NotificationFilterActivity">
<TextView
android:text="@string/filter_apps_info"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:id="@+id/tFilter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="5dp"
android:id="@+id/tFilter"/>
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:text="@string/filter_apps_info" />
<ProgressBar
android:layout_marginTop="64dip"
android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/spinner" />
android:layout_marginTop="64dip" />
<ListView
android:id="@+id/lvFilterApps"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/lvFilterApps"
android:visibility="gone"
/>
android:visibility="gone" />
</LinearLayout>

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/refresh_list_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dip"
android:paddingRight="16dip"
tools:context=".MainActivity"
android:id="@+id/listView1"
android:addStatesFromChildren="true"
android:orientation="vertical"/>
</android.support.v4.widget.SwipeRefreshLayout>

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/runcommandslist"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp"
android:addStatesFromChildren="true"
android:orientation="vertical" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/add_command_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_action_image_edit"
app:backgroundTint="@color/primary"
app:layout_anchor="@id/runcommandslist"
app:layout_anchorGravity="bottom|end" />
<TextView
android:id="@+id/addcomand_explanation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="30dp"
android:text="@string/addcommand_explanation"
android:textAlignment="center"
android:textSize="16sp" />
</android.support.design.widget.CoordinatorLayout>

View File

@@ -1,36 +1,35 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
android:orientation="vertical">
android:paddingTop="@dimen/activity_vertical_margin">
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:id="@android:id/list"
android:layout_weight="1"
/>
android:layout_weight="1" />
<TextView
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="@string/custom_dev_list_help"/>
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="@string/custom_dev_list_help" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:imeOptions="actionSend"
android:hint="@string/add_host_hint"
android:id="@+id/ip_edittext"/>
android:id="@+id/ip_edittext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="@string/add_host_hint"
android:imeOptions="actionSend" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/add_host"
android:id="@android:id/button1"/>
android:id="@android:id/button1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/add_host" />
</LinearLayout>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/refresh_list_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/devices_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:addStatesFromChildren="true"
android:orientation="vertical"
android:paddingLeft="16dip"
android:paddingRight="16dip"
tools:context=".MainActivity" />
</android.support.v4.widget.SwipeRefreshLayout>

View File

@@ -1,34 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:drawableBottom="@drawable/text_section_header"
android:textStyle="bold"
android:id="@+id/list_item_category_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textColor="?android:textColorSecondary"
android:drawableBottom="@drawable/text_section_header"
android:drawablePadding="4dp"
android:textSize="14sp"
android:textAllCaps="true"
android:paddingLeft="8dip"
android:paddingRight="8dip"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="@+id/list_item_category_text"
/>
android:textAllCaps="true"
android:textColor="?android:textColorSecondary"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/list_item_category_empty_placeholder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="10dip"
android:visibility="gone"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="@string/device_list_empty"
android:id="@+id/list_item_category_empty_placeholder"
android:layout_gravity="center" />
android:textAppearance="?android:attr/textAppearanceSmall"
android:visibility="gone" />
</LinearLayout>

View File

@@ -1,37 +1,38 @@
<?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"
android:paddingLeft="12dip"
android:paddingStart="12dip"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:paddingEnd="?android:attr/scrollbarSize"
android:background="@drawable/abc_list_selector_holo_dark"
android:orientation="vertical">
android:baselineAligned="false"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="vertical"
android:paddingEnd="?android:attr/scrollbarSize"
android:paddingLeft="12dip"
android:paddingRight="?android:attr/scrollbarSize"
android:paddingStart="12dip">
<!-- We should use android:background="@android:/listChoiceBackgroundIndicator"
instead of abc_list_selector_holo_dark but that's only supported from API11 -->
<TextView android:id="@+id/list_item_entry_title"
<TextView
android:id="@+id/list_item_entry_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:text="" />
android:singleLine="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView android:id="@+id/list_item_entry_summary"
<TextView
android:id="@+id/list_item_entry_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:singleLine="true"
android:visibility="gone"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="@android:color/darker_gray"
android:text="" />
android:visibility="gone" />
</LinearLayout>

View File

@@ -1,73 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:baselineAligned="false"
android:layout_height="wrap_content"
android:paddingLeft="12dip"
android:paddingStart="12dip"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:paddingEnd="?android:attr/scrollbarSize"
android:orientation="horizontal">
<ImageView android:id="@+id/list_item_entry_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_device_laptop"
android:layout_weight="0" />
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_weight="1"
android:layout_height="wrap_content">
<TextView android:id="@+id/list_item_entry_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dip"
android:layout_marginStart="8dip"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:text=""/>
<TextView android:id="@+id/list_item_entry_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:singleLine="true"
android:textColor="#CC2222"
android:visibility="gone"
android:text="" />
</LinearLayout>
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:layout_weight="0"
android:indeterminate="true" />
<Button
android:layout_width="wrap_content"
android:minWidth="128dip"
android:layout_height="wrap_content"
android:text="@string/request_pairing"
android:padding="8dip"
android:background="@drawable/button_round"
android:textColor="#FFFFFF"
android:id="@+id/entry_pair_button"
android:layout_weight="0"
android:nestedScrollingEnabled="false" />
</LinearLayout>

View File

@@ -1,52 +1,59 @@
<?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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:baselineAligned="false"
android:layout_height="wrap_content"
android:paddingLeft="12dip"
android:paddingStart="12dip"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize"
android:paddingEnd="?android:attr/scrollbarSize"
android:clickable="true"
android:background="@drawable/abc_list_selector_holo_dark"
android:orientation="horizontal">
android:baselineAligned="false"
android:clickable="true"
android:focusable="true"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:paddingEnd="?android:attr/scrollbarSize"
android:paddingLeft="12dip"
android:paddingRight="?android:attr/scrollbarSize"
android:paddingStart="12dip">
<ImageView android:id="@+id/list_item_entry_icon"
<android.support.v7.widget.AppCompatImageView
android:id="@+id/list_item_entry_icon"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:src="@drawable/ic_device_laptop"
/>
android:contentDescription="@string/device_icon_description"
app:tint="?attr/colorControlNormal"
android:src="@drawable/ic_device_laptop" />
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView android:id="@+id/list_item_entry_title"
<TextView
android:id="@+id/list_item_entry_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dip"
android:layout_marginStart="8dip"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:fadingEdge="horizontal"
android:text="" />
android:singleLine="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView android:id="@+id/list_item_entry_summary"
<TextView
android:id="@+id/list_item_entry_summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dip"
android:layout_marginStart="8dip"
android:textAppearance="?android:attr/textAppearanceSmall"
android:singleLine="true"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="#CC2222"
android:visibility="gone"
android:text="" />
android:visibility="gone" />
</LinearLayout>

View File

@@ -2,184 +2,162 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:id="@+id/mpris_control_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mpris_control_view"
android:layout_gravity="center"
android:gravity="center"
android:paddingLeft="30dip"
android:paddingTop="5dip"
android:paddingRight="30dip"
android:paddingBottom="5dip">
android:orientation="vertical">
<TextView
android:id="@+id/no_players"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_gravity="center_horizontal"
android:text="@string/no_players_connected"
android:id="@+id/no_players"
android:layout_gravity="center_horizontal" />
android:textAppearance="?android:attr/textAppearanceMedium" />
<Spinner
android:id="@+id/player_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/player_spinner"
android:layout_gravity="center"
/>
android:layout_gravity="center" />
<TextView
android:id="@+id/now_playing_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/now_playing_textview"
android:layout_gravity="center"
android:ellipsize="marquee"
android:gravity="center"
android:marqueeRepeatLimit="marquee_forever"
android:padding="8dip"
android:scrollHorizontally="true"
android:singleLine="true"
android:gravity="center"
android:padding="8dip"
android:layout_gravity="center"
/>
android:textAppearance="?android:attr/textAppearanceMedium" />
<org.kde.kdeconnect.UserInterface.MaxWidthImageButton
android:layout_width="fill_parent"
android:layout_height="75dip"
app:maxWidth="300dip"
<ImageButton
android:id="@+id/play_button"
android:src="@drawable/ic_play_black"
android:contentDescription="@string/mpris_play"
android:layout_width="fill_parent"
android:layout_height="75dp"
android:layout_gravity="center"
android:layout_weight="0"
android:clickable="false"
android:adjustViewBounds="false"
android:baselineAlignBottom="true" />
android:baselineAlignBottom="true"
android:clickable="false"
android:contentDescription="@string/mpris_play"
android:theme="@style/DisableableButton"
android:src="@drawable/ic_play_black" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dip"
android:layout_gravity="center"
>
android:orientation="horizontal">
<ImageButton
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/prev_button"
android:src="@drawable/ic_previous_black"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.25"
android:contentDescription="@string/mpris_previous"
android:layout_weight="0.25"
/>
android:theme="@style/DisableableButton"
android:src="@drawable/ic_previous_black" />
<ImageButton
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/rew_button"
android:src="@drawable/ic_rewind_black"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.25"
android:contentDescription="@string/mpris_rew"
android:layout_weight="0.25"
/>
android:theme="@style/DisableableButton"
android:src="@drawable/ic_rewind_black" />
<ImageButton
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/ff_button"
android:src="@drawable/ic_fast_forward_black"
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="@drawable/ic_next_black"
android:contentDescription="@string/mpris_next"
android:layout_weight="0.25"
/>
android:contentDescription="@string/mpris_ff"
android:theme="@style/DisableableButton"
android:src="@drawable/ic_fast_forward_black" />
<ImageButton
android:id="@+id/next_button"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_weight="0.25"
android:contentDescription="@string/mpris_next"
android:theme="@style/DisableableButton"
android:src="@drawable/ic_next_black" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:id="@+id/progress_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/progress_slider">
android:orientation="horizontal">
<TextView
android:id="@+id/progress_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/progress_textview"
android:singleLine="true"
android:layout_gravity="center"
android:gravity="center"
android:padding="8dip"
android:layout_gravity="center"
android:text="00:00" />
android:singleLine="true"
android:text="00:00"
android:textAppearance="?android:attr/textAppearanceMedium" />
<SeekBar
android:id="@+id/positionSeek"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/positionSeek"
android:layout_weight="1"
android:layout_gravity="center" />
android:layout_gravity="center"
android:layout_weight="1" />
<TextView
android:id="@+id/time_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:id="@+id/time_textview"
android:singleLine="true"
android:layout_gravity="center"
android:gravity="center"
android:padding="8dip"
android:layout_gravity="center"
android:text="00:00" />
android:singleLine="true"
android:text="00:00"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/volume_layout"
android:layout_gravity="center"
android:layout_marginTop="8dip">
android:id="@+id/volume_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="8dip"
android:orientation="horizontal">
<ImageView
<android.support.v7.widget.AppCompatImageView
android:id="@+id/imageView"
android:layout_width="30dip"
android:layout_height="30dip"
android:maxWidth="30dip"
android:layout_marginRight="10dip"
android:layout_marginEnd="10dip"
android:id="@+id/imageView"
android:layout_marginRight="10dip"
android:layout_weight="0"
android:contentDescription="@string/mpris_volume"
android:src="@drawable/ic_volume_black"
/>
android:maxWidth="30dip"
app:tint="?attr/colorHighContrast"
android:src="@drawable/ic_volume_black" />
<SeekBar
android:id="@+id/volume_seek"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/volume_seek"
android:layout_weight="1"
android:max="100"
android:layout_gravity="center"
/>
android:layout_weight="1"
android:max="100" />
</LinearLayout>
<!--
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/pause_button"
android:src="@android:drawable/ic_media_pause"
android:layout_gravity="center"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/pause_button"
android:src="@android:drawable/ic_media_stop"
android:layout_gravity="center"/>
-->
</LinearLayout>

View File

@@ -3,51 +3,34 @@
android:layout_width="match_parent"
android:layout_height="160dp"
android:background="@drawable/drawer_header"
android:orientation="vertical"
android:gravity="bottom">
android:gravity="bottom"
android:orientation="vertical">
<TextView
android:id="@+id/kdeconnect_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="KDE Connect"
android:textColor="#FFF"
android:textStyle="bold"
android:id="@+id/kdeconnect_label"
android:paddingEnd="48dp"
android:paddingLeft="16dp"
android:paddingRight="48dp"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingRight="48dp"
android:paddingEnd="48dp"
/>
android:text="KDE Connect"
android:textColor="#FFF"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My device"
android:id="@+id/device_name"
android:layout_marginBottom="0dp"
android:textColor="#fff"
android:paddingBottom="16dp"
android:paddingTop="4dp"
android:paddingRight="48dp"
android:paddingEnd="48dp"
android:paddingStart="16dp"
android:paddingLeft="16dp" />
<!--
<ImageView
android:src="@drawable/ic_action_image_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:clickable="true"
android:background="@drawable/abc_list_selector_holo_dark"
android:layout_gravity="center_vertical"
android:contentDescription="@string/rename_device"
android:id="@+id/rename"
/>
-->
android:layout_marginBottom="0dp"
android:paddingBottom="16dp"
android:paddingEnd="48dp"
android:paddingLeft="16dp"
android:paddingRight="48dp"
android:paddingStart="16dp"
android:paddingTop="4dp"
android:text="My device"
android:textColor="#fff" />
</LinearLayout>

View File

@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2006 The Android Open Source Project
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2006 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -17,19 +16,22 @@
<!-- Layout for a Preference in a PreferenceActivity. The
Preference is able to place a specific widget for its particular
type in the "widget_frame" layout. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:background="?attr/selectableItemBackground"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeight"
android:paddingEnd="?android:attr/scrollbarSize"
android:paddingRight="?android:attr/scrollbarSize"
android:paddingStart="12dip"
android:paddingLeft="12dip"
android:background="?attr/selectableItemBackground">
android:paddingRight="?android:attr/scrollbarSize"
android:paddingStart="12dip">
<!-- Preference will place its actual preference widget here. -->
<LinearLayout android:id="@android:id/widget_frame"
<LinearLayout
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_vertical"
@@ -38,40 +40,44 @@
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dip"
android:layout_marginLeft="12dip"
android:layout_marginEnd="4dip"
android:layout_marginRight="4dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_marginEnd="4dip"
android:layout_marginLeft="12dip"
android:layout_marginRight="4dip"
android:layout_marginStart="12dip"
android:layout_marginTop="6dip"
android:layout_weight="1">
<TextView android:id="@+android:id/title"
<TextView
android:id="@+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
android:fadingEdge="horizontal"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView android:id="@android:id/summary"
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@android:id/title"
android:layout_alignStart="@android:id/title"
android:layout_alignLeft="@android:id/title"
android:layout_alignStart="@android:id/title"
android:layout_below="@android:id/title"
android:maxLines="3"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="3" />
android:textColor="?android:attr/textColorSecondary" />
</RelativeLayout>
<ImageButton
<android.support.v7.widget.AppCompatImageButton
android:id="@+id/settingsButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/settingsButton"
android:padding="8dip"
android:background="@drawable/abc_btn_borderless_material"
android:src="@drawable/ic_action_settings_inverted"/>
android:contentDescription="@string/settings_icon_description"
android:padding="8dip"
app:tint="?attr/colorControlNormal"
android:src="@drawable/ic_action_settings_inverted" />
</LinearLayout>

View File

@@ -1,17 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:kdeconnect="http://schemas.android.com/apk/res-auto/android">
xmlns:kdeconnect="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/menu_show_keyboard"
android:title="@string/show_keyboard"
<item
android:id="@+id/menu_show_keyboard"
android:icon="@drawable/ic_action_keyboard"
android:title="@string/show_keyboard"
kdeconnect:showAsAction="ifRoom" />
<item android:id="@+id/menu_right_click"
<item
android:id="@+id/menu_right_click"
android:title="@string/right_click"
kdeconnect:showAsAction="never" />
<item android:id="@+id/menu_middle_click"
<item
android:id="@+id/menu_middle_click"
android:title="@string/middle_click"
kdeconnect:showAsAction="never" />

View File

@@ -5,22 +5,19 @@
android:id="@+id/menu_refresh"
android:icon="@drawable/ic_action_refresh"
android:orderInCategory="200"
kdeconnect:showAsAction="never"
android:title="@string/refresh"
/>
kdeconnect:showAsAction="never" />
<item
android:id="@+id/menu_rename"
android:orderInCategory="300"
android:title="@string/device_rename_title"
kdeconnect:showAsAction="never"
/>
kdeconnect:showAsAction="never" />
<item
<item
android:id="@+id/menu_custom_device_list"
android:orderInCategory="900"
android:title="@string/custom_device_list"
kdeconnect:showAsAction="never"
/>
kdeconnect:showAsAction="never" />
</menu>

View File

@@ -2,11 +2,10 @@
xmlns:kdeconnect="http://schemas.android.com/apk/res-auto/android">
<item
android:id="@+id/menu_refresh"
android:icon="@drawable/ic_action_refresh"
android:orderInCategory="200"
kdeconnect:showAsAction="never"
android:title="@string/refresh"
/>
android:id="@+id/menu_refresh"
android:icon="@drawable/ic_action_refresh"
android:orderInCategory="200"
android:title="@string/refresh"
kdeconnect:showAsAction="never" />
</menu>

View File

@@ -31,7 +31,6 @@
<string name="send_ping">أرسل وخزة</string>
<string name="open_mpris_controls">تحكّمات الوسائط المتعدّدة</string>
<string name="open_mousepad">الدّخل البعيد</string>
<string name="mousepad_info">حرّك اصبعًا على الشّاشة لتحريك مؤشّر الفأرة. المس للنّقر واستخدم إصبعين أو ثلاث للزّرّين الأيمن والأوسط. انقر مطوّلًا للسّحب والإفلات.</string>
<string name="mousepad_double_tap_settings_title">اضبط إجراء اللمس بإصبعين</string>
<string name="mousepad_triple_tap_settings_title">اضبط إجراء اللمس بثلاث أصابع</string>
<string name="mousepad_sensitivity_settings_title">اضبط حساسيّة لوحة اللمس</string>
@@ -76,7 +75,6 @@
<string name="incoming_file_title">ملفّ وارد من %1s</string>
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">يرسل ملفًّا إلى %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="received_file_title">استُقبل ملفّ من %1s</string>
<string name="received_file_fail_title">فشل استقبال الملفّ من %1s</string>
<string name="received_file_text">المس لفتح \'%1s\'</string>

View File

@@ -19,7 +19,6 @@
<string name="open_settings">Otvori postavke</string>
<string name="no_permissions">Morate odobriti dopuštenje da pristupite notifikacijama</string>
<string name="send_ping">Pošalji ping</string>
<string name="mousepad_info">Pomjerite prst na ekranu da opmjerite kursor miša. Tapnite za klik i koristite dva ili tri prsta za srednje i desno dugme. Koristite dugi pritisak za prevlačenje.</string>
<string name="mousepad_double_tap_settings_title">Postavite akciju tapa sa dva prsta</string>
<string name="mousepad_triple_tap_settings_title">Postavite akciju tapa sa tri prsta</string>
<string-array name="mousepad_tap_entries">
@@ -57,7 +56,6 @@
<string name="incoming_file_title">Dolazna datoteka od %1s</string>
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Slanje datoteke na %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="received_file_title">Primljena datoteka od %1s</string>
<string name="received_file_text">Kucni za otvaranje \'%1s\'</string>
<string name="sent_file_title">Poslana datoteka na %1s</string>

View File

@@ -30,6 +30,7 @@
<string name="cancel">Cancel·la</string>
<string name="open_settings">Obre l\'arranjament</string>
<string name="no_permissions">Us caldrà concedir permís per accedir a les notificacions</string>
<string name="no_permission_mprisreceiver">Per a poder controlar els reproductors multimèdia cal atorgar accés a les notificacions</string>
<string name="send_ping">Envia un ping</string>
<string name="open_mpris_controls">Control multimèdia</string>
<string name="remotekeyboard_editing_only_title">Fes servir les tecles remotes només en editar</string>
@@ -37,7 +38,7 @@
<string name="remotekeyboard_connected">La connexió amb el teclat remot està activa</string>
<string name="remotekeyboard_multiple_connections">Hi ha més d\'una connexió amb un teclat remot, seleccioneu el dispositiu per configurar-lo</string>
<string name="open_mousepad">Entrada remota</string>
<string name="mousepad_info">Moveu un dit per la pantalla per a moure el cursor del ratolí. Toqueu per un clic, i empreu dos/tres dits pels botons dret i mig. Empreu un toc llarg per arrossegar i deixar anar.</string>
<string name="mousepad_info">Moveu un dit per la pantalla per a moure el cursor del ratolí. Toqueu per un clic, i empreu dos/tres dits pels botons dret i mig. Useu 2 dits per desplaçar. Empreu un toc llarg per arrossegar i deixar anar.</string>
<string name="mousepad_double_tap_settings_title">Estableix l\'acció de tocar amb dos dits</string>
<string name="mousepad_triple_tap_settings_title">Estableix l\'acció de tocar amb tres dits</string>
<string name="mousepad_sensitivity_settings_title">Estableix la sensibilitat del ratolí tàctil</string>
@@ -83,8 +84,10 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">S\'està enviant el fitxer a %1s</string>
<string name="outgoing_files_title">S\'estan enviant fitxers a %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">S\'ha enviat %1$d de %2$d fitxers</string>
<plurals name="outgoing_files_text">
<item quantity="one">S\'ha enviat %1$d fitxer</item>
<item quantity="other">S\'ha enviat %1$d de %2$d fitxers</item>
</plurals>
<string name="received_file_title">Fitxer rebut des de %1s</string>
<string name="received_file_fail_title">Ha fallat en rebre el fitxer des de %1s</string>
<string name="received_file_text">Puntegeu per obrir «%1s»</string>
@@ -106,6 +109,7 @@
<string name="remote_control">Comandament a distància</string>
<string name="settings">Arranjament del KDE Connect</string>
<string name="mpris_play">Reprodueix</string>
<string name="mpris_pause">Pausa</string>
<string name="mpris_previous">Anterior</string>
<string name="mpris_rew">Rebobina</string>
<string name="mpris_ff">Avanç ràpid</string>
@@ -121,6 +125,8 @@
<item>1 minut</item>
<item>2 minuts</item>
</string-array>
<string name="mpris_notification_settings_title">Mostra les notificacions dels reproductors</string>
<string name="mpris_notification_settings_summary">Permet controlar els reproductors multimèdia sense obrir el KDE Connect.</string>
<string name="share_to">Comparteix amb...</string>
<string name="protocol_version_older">Aquest dispositiu usa una versió antiga del protocol</string>
<string name="protocol_version_newer">Aquest dispositiu usa una versió nova del protocol</string>
@@ -141,6 +147,8 @@
<string name="share_destination_customize_summary_disabled">Els fitxers rebuts apareixeran a Baixades</string>
<string name="share_destination_customize_summary_enabled">Els fitxers seran emmagatzemats al directori de sota</string>
<string name="share_destination_folder_preference">Directori de destinació</string>
<string name="share">Comparteix</string>
<string name="share_received_file">Comparteix «%s»</string>
<string name="title_activity_notification_filter">Filtre per a les notificacions</string>
<string name="filter_apps_info">Les notificacions se sincronitzaran per a les aplicacions seleccionades.</string>
<string name="sftp_internal_storage">Emmagatzematge intern</string>
@@ -167,8 +175,9 @@
<string name="pref_plugin_telepathy">Envia un SMS</string>
<string name="pref_plugin_telepathy_desc">Envia missatges de text des de l\'escriptori</string>
<string name="plugin_not_supported">Aquest connector no és admès pel dispositiu</string>
<string name="findmyphone_title">Cerca el meu telèfon</string>
<string name="findmyphone_title_tablet">Cerca la meva tauleta</string>
<string name="findmyphone_title">Troba el meu telèfon</string>
<string name="findmyphone_title_tablet">Troba la meva tauleta</string>
<string name="findmyphone_title_tv">Troba la meva TV</string>
<string name="findmyphone_description">Fa sonar aquest dispositiu perquè el pugueu trobar.</string>
<string name="findmyphone_found">L\'he trobat</string>
<string name="open">Obre</string>
@@ -183,4 +192,17 @@
<string name="telepathy_permission_explanation">Per a llegir i escriure SMS des de l\'escriptori, haureu de donar permís als SMS</string>
<string name="telephony_permission_explanation">Per a veure les trucades telefòniques i SMS des de l\'escriptori, haureu de donar permís a les trucades telefòniques i SMS</string>
<string name="telephony_optional_permission_explanation">Per a veure un nom de contacte en comptes d\'un número de telèfon, haureu de donar permís als contactes del telèfon</string>
<string name="select_ringtone">Seleccioneu un to de la trucada</string>
<string name="telephony_pref_blocked_title">Nombres blocats</string>
<string name="telephony_pref_blocked_dialog_desc">No es mostren ni les trucades ni els SMS d\'aquests números. Especifiqueu un número per línia</string>
<string name="mpris_coverart_description">Caràtula del suport actual</string>
<string name="device_icon_description">Icona del dispositiu</string>
<string name="settings_icon_description">Icona d\'arranjament</string>
<string name="add_command">Afegeix una ordre</string>
<string name="addcommand_explanation">No hi ha cap ordre registrada</string>
<string name="addcommand_explanation2">Podeu afegir ordres noves a l\'Arranjament del sistema del KDE Connect</string>
<string name="add_command_description">Podeu afegir ordres per a l\'escriptori</string>
<string name="pref_plugin_mprisreceiver">Control del reproductor multimèdia</string>
<string name="pref_plugin_mprisreceiver_desc">Controla els reproductors multimèdia dels telèfons des d\'un altre dispositiu</string>
<string name="dark_theme">Tema fosc</string>
</resources>

View File

@@ -37,7 +37,7 @@
<string name="remotekeyboard_connected">Vzdálené připojení klávesnice je aktivní</string>
<string name="remotekeyboard_multiple_connections">Je k dispozici více než jedno připojení klávesnice. Vyberte zařízení pro jeho nastavení.</string>
<string name="open_mousepad">Vzdálený vstup</string>
<string name="mousepad_info">Pohybujte prstem po obrazovce pro pohybování kurzorem myši. Ťukněte pro kliknutí a použijte dva/tři prsty jako pravé a prostřední tlačítko. Pro přetažení dlouze podržte.</string>
<string name="mousepad_info">Pohybujte prstem po obrazovce pro pohybování kurzorem myši. Ťukněte pro kliknutí a použijte dva/tři prsty jako pravé a prostřední tlačítko. Použijte 2 prsty pro posunování. Pro přetažení dlouze podržte.</string>
<string name="mousepad_double_tap_settings_title">Nastavit činnost pro ťuknutí dvěma prsty</string>
<string name="mousepad_triple_tap_settings_title">Nastavit činnost pro ťuknutí třemi prsty</string>
<string name="mousepad_sensitivity_settings_title">Nastavit citlivost touchpadu</string>
@@ -83,8 +83,12 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Odesílám soubor do %1s</string>
<string name="outgoing_files_title">Odesílám soubory do %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Odesláno %1$d ze %2$d souborů</string>
<plurals name="outgoing_files_text">
<item quantity="one">Odeslán %1$d soubor</item>
<item quantity="few">Odeslány %1$d ze %2$d souborů</item>
<item quantity="many">Odesláno %1$d ze %2$d souborů</item>
<item quantity="other"/>
</plurals>
<string name="received_file_title">Přijat soubor od %1s</string>
<string name="received_file_fail_title">Selhalo přijímání souboru od %1s</string>
<string name="received_file_text">Ťukněte pro otevření \'%1s\'</string>
@@ -106,6 +110,7 @@
<string name="remote_control">Vzdálené ovládání</string>
<string name="settings">Nastavení KDE Connect</string>
<string name="mpris_play">Přehrát</string>
<string name="mpris_pause">Pozastavit</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>
@@ -121,6 +126,8 @@
<item>1 minuta</item>
<item>2 minuty</item>
</string-array>
<string name="mpris_notification_settings_title">Obrazit upozornění pro ovládání médií</string>
<string name="mpris_notification_settings_summary">Umožní ovládat přehrávače médií bez otevření KDE Connect.</string>
<string name="share_to">Sdílet s...</string>
<string name="protocol_version_older">Toto zařízení používá starou verzi protokolu</string>
<string name="protocol_version_newer">Toto zařízení používá novější verzi protokolu</string>
@@ -141,6 +148,8 @@
<string name="share_destination_customize_summary_disabled">Přijaté soubory se objeví v Downloads</string>
<string name="share_destination_customize_summary_enabled">Soubory budou ukládány v adresáři níže</string>
<string name="share_destination_folder_preference">Cílový adresář</string>
<string name="share">Sdílet</string>
<string name="share_received_file">Sdílet \"%s\"</string>
<string name="title_activity_notification_filter">Filtr upozornění</string>
<string name="filter_apps_info">Upozorňování mezi vybranými aplikacemi bude synchronizováno.</string>
<string name="sftp_internal_storage">Interní úložiště</string>
@@ -183,4 +192,13 @@
<string name="telepathy_permission_explanation">Pro čtení a psaní SMS z počítače musíte udělit oprávnění k SMS</string>
<string name="telephony_permission_explanation">Pro zobrazení telefonátů a SMS v počítači musíte udělit oprávnění k telefonování a SMS</string>
<string name="telephony_optional_permission_explanation">Pro zobrazení jména kontaktu u telefonního čísla je potřeba udělit oprávnění ke kontaktům v telefonu</string>
<string name="select_ringtone">Vybrat vyzváněcí tón</string>
<string name="telephony_pref_blocked_title">Blokovaná čísla</string>
<string name="telephony_pref_blocked_dialog_desc">Nezobrazovat volnání a SMS z těchto čísel. Prosím, zadejte pouze jedno slovo na řádek.</string>
<string name="mpris_coverart_description">Obal současného média</string>
<string name="device_icon_description">Ikona zařízení</string>
<string name="settings_icon_description">Ikona nastavení</string>
<string name="add_command">Přidat příkaz</string>
<string name="addcommand_explanation">Nejsou registrovány žádné příkazy</string>
<string name="addcommand_explanation2">Nové příkazy můžete přidat v nastavení systému KDE Connect</string>
</resources>

View File

@@ -37,7 +37,6 @@
<string name="remotekeyboard_connected">Ekstern tastaturforbindelse er aktiv</string>
<string name="remotekeyboard_multiple_connections">Der er mere end en ekstern tastaturforbindelse, vælg den enhed der skal konfigureres</string>
<string name="open_mousepad">Eksternt input</string>
<string name="mousepad_info">Bevæg en finger på skærmen for at flytte musemarkøren. Tap for at klikke og brug to/tre-fingre for højre og midterste museknap. Brug et langt tryk til at trække og slippe.</string>
<string name="mousepad_double_tap_settings_title">Angiv handling for tap med to fingre</string>
<string name="mousepad_triple_tap_settings_title">Angiv handling for tap med tre fingre</string>
<string name="mousepad_sensitivity_settings_title">Angiv følsomhed for touchpad</string>
@@ -83,8 +82,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Sender fil til %1s</string>
<string name="outgoing_files_title">Sender filer til %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Sendte %1$d ud af %2$d filer</string>
<string name="received_file_title">Modtog fil fra %1s</string>
<string name="received_file_fail_title">Kunne ikke modtage fil fra %1s</string>
<string name="received_file_text">Tap for at åbne \"%1s\"</string>

View File

@@ -31,7 +31,6 @@
<string name="send_ping">Ping senden</string>
<string name="open_mpris_controls">Multimedia-Bedienung</string>
<string name="open_mousepad">Ferneingabe</string>
<string name="mousepad_info">Bewegen Sie einen Finger auf dem Bildschirm um den Maus-Zeiger zu verschieben. Tippen zum Klicken, mit zwei oder drei Fingern für rechten bzw. mittleren Mausknopf. Tippen und Halten für Ziehen und Ablegen.</string>
<string name="mousepad_double_tap_settings_title">Aktionsausführung bei Berührung mit zwei Fingern einstellen</string>
<string name="mousepad_triple_tap_settings_title">Aktionsausführung bei Berührung mit drei Fingern einstellen</string>
<string name="mousepad_sensitivity_settings_title">Empfindlichkeit des Touchpads einstellen</string>
@@ -77,8 +76,10 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Datei wird an %1s gesendet</string>
<string name="outgoing_files_title">Datei wird an %1s gesendet</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">%1$d von %2$d Dateien gesendet</string>
<plurals name="outgoing_files_text">
<item quantity="one">%1$d Datei gesendet</item>
<item quantity="other">%1$d von %2$d Dateien gesendet</item>
</plurals>
<string name="received_file_title">Datei von %1s erhalten</string>
<string name="received_file_fail_title">Der Empfang der Datei %1s ist fehlgeschlagen</string>
<string name="received_file_text">Tippen um „%1s“ zu öffnen</string>
@@ -100,6 +101,7 @@
<string name="remote_control">Fernbedienung</string>
<string name="settings">KDE-Connect-Einstellungen</string>
<string name="mpris_play">Wiedergabe</string>
<string name="mpris_pause">Anhalten</string>
<string name="mpris_previous">Zurück</string>
<string name="mpris_rew">Schneller Rücklauf</string>
<string name="mpris_ff">Vorlauf</string>
@@ -167,4 +169,23 @@
<string name="findmyphone_found">Gefunden</string>
<string name="open">Öffnen</string>
<string name="close">Schließen</string>
<string name="no_permissions_storage">Sie müssen die Berechtigung zum Zugriff auf Speicher erteilen</string>
<string name="plugins_need_permission">Einige Module benötigen zusätzliche Berechtigungen, tippen Sie für weitere Details:</string>
<string name="permission_explanation">Dieses Modul benötigt zusätzliche Berechtigungen</string>
<string name="optional_permission_explanation">Es müssen weitere Berechtigungen erteilt werden, um alle Funktionen nutzen zu können</string>
<string name="plugins_need_optional_permission">Einige Module haben eingeschränkte Funktionen wegen fehlender Berechtigungen, tippen Sie für weitere Informationen:</string>
<string name="sftp_permission_explanation">Um vom Rechner auf den Telefonspeicher zuzugreifen, werden weitere Berechtigungen benötigt</string>
<string name="share_optional_permission_explanation">m Dateien zwischen Rechner und Telefon auszutauschen, muss der Zugriff auf den Telefonspeicher gewährt werden</string>
<string name="telepathy_permission_explanation">Um SMS vom Rechner aus zu lesen und zu versenden, muss der Zugriff auf die SMS-Funktion gewährt werden</string>
<string name="telephony_permission_explanation">Um Telefonate und SMS auf dem Rechner zu sehen, müssen Berechtigungen für Anrufe und SMS erteilt werden</string>
<string name="telephony_optional_permission_explanation">Um einen Namen anstelle einer Telefonnummer zu sehen, muss der Zugriff auf das Adressbuch gewährt werden</string>
<string name="select_ringtone">Einen Klingelton auswählen</string>
<string name="telephony_pref_blocked_title">Unterdrückte Nummern</string>
<string name="telephony_pref_blocked_dialog_desc">keine Anrufe und SMS von diesen Telefonnummern anzeigen. Geben Sie eine Nummer pro Zeile ein</string>
<string name="mpris_coverart_description">Cover des aktuellen Mediums</string>
<string name="device_icon_description">Gerätesymbol</string>
<string name="settings_icon_description">Einstellungssymbol</string>
<string name="add_command">Einen Befehl hinzufügen</string>
<string name="addcommand_explanation">Es sind keine Befehle registriert.</string>
<string name="addcommand_explanation2">Sie können neue Befehle in den Systemeinstellungen für KDE-Connect hinzufügen.</string>
</resources>

View File

@@ -37,7 +37,6 @@
<string name="remotekeyboard_connected">Η σύνδεση με απομακρυσμένο πληκτρολόγιο είναι ενεργή</string>
<string name="remotekeyboard_multiple_connections">Υπάρχουν περισσότερες της μίας συνδέσεις με απομακρυσμένο πληκτρολόγιο, επιλέξτε ποια συσκευή θα διαμορφώσετε</string>
<string name="open_mousepad">Απομακρυσμένη είσοδος στοιχείων</string>
<string name="mousepad_info">Μετακινείστε το δάκτυλο στην οθόνη για να μετακινηθεί ο δρομέας του ποντικιού. Χτυπήστε για κλικ και χρησιμοποιήστε δύο/τρία δάκτυλα για δεξί και μεσαίο κλικ. Πιέστε με διάρκεια για μετακίνηση και απόθεση.</string>
<string name="mousepad_double_tap_settings_title">Ρύθμιση δύο δακτύλων για την ενέργεια χτυπήματος</string>
<string name="mousepad_triple_tap_settings_title">Ρύθμιση τριών δακτύλων για την ενέργεια χτυπήματος</string>
<string name="mousepad_sensitivity_settings_title">Ρύθμιση ευαισθησίας της οθόνης αφής</string>
@@ -83,8 +82,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Αποστολή αρχείου σε %1s</string>
<string name="outgoing_files_title">Αποστολή αρχείων σε %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Εστάλησαν %1$d από %2$d αρχεία</string>
<string name="received_file_title">Ελήφθη αρχείο από %1s</string>
<string name="received_file_fail_title">Αποτυχία λήψης αρχείου από %1s</string>
<string name="received_file_text">Χτυπήστε για άνοιγμα \'%1s\'</string>

View File

@@ -30,6 +30,7 @@
<string name="cancel">Cancel</string>
<string name="open_settings">Open settings</string>
<string name="no_permissions">You need to grant permission to access notifications</string>
<string name="no_permission_mprisreceiver">To be able to control your media players you need to grant access to the notifications</string>
<string name="send_ping">Send ping</string>
<string name="open_mpris_controls">Multimedia control</string>
<string name="remotekeyboard_editing_only_title">Handle remote keys only when editing</string>
@@ -37,7 +38,7 @@
<string name="remotekeyboard_connected">Remote keyboard connection is active</string>
<string name="remotekeyboard_multiple_connections">There is more than one remote keyboard connection, select the device to configure</string>
<string name="open_mousepad">Remote input</string>
<string name="mousepad_info">Move a finger on the screen to move the mouse cursor. Tap for a click, and use two/three fingers for right and middle buttons. Use a long press to drag\'n drop.</string>
<string name="mousepad_info">Move a finger on the screen to move the mouse cursor. Tap for a click, and use two/three fingers for right and middle buttons. Use 2 fingers to scroll. Use a long press to drag\'n drop.</string>
<string name="mousepad_double_tap_settings_title">Set two finger tap action</string>
<string name="mousepad_triple_tap_settings_title">Set three finger tap action</string>
<string name="mousepad_sensitivity_settings_title">Set touchpad sensitivity</string>
@@ -83,8 +84,10 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Sending file to %1s</string>
<string name="outgoing_files_title">Sending files to %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Sent %1$d out of %2$d files</string>
<plurals name="outgoing_files_text">
<item quantity="one">Send files</item>
<item quantity="other">Sent %1$d out of %2$d files</item>
</plurals>
<string name="received_file_title">Received file from %1s</string>
<string name="received_file_fail_title">Failed receiving file from %1s</string>
<string name="received_file_text">Tap to open \'%1s\'</string>
@@ -106,6 +109,7 @@
<string name="remote_control">Remote control</string>
<string name="settings">KDE Connect Settings</string>
<string name="mpris_play">Play</string>
<string name="mpris_pause">Pause</string>
<string name="mpris_previous">Previous</string>
<string name="mpris_rew">Rewind</string>
<string name="mpris_ff">Fast-forward</string>
@@ -121,6 +125,8 @@
<item>1 minute</item>
<item>2 minutes</item>
</string-array>
<string name="mpris_notification_settings_title">Show media control notification</string>
<string name="mpris_notification_settings_summary">Allows controlling your media players without opening KDE Connect.</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>
@@ -141,6 +147,8 @@
<string name="share_destination_customize_summary_disabled">Received files will appear in Downloads</string>
<string name="share_destination_customize_summary_enabled">Files will be stored in the directory below</string>
<string name="share_destination_folder_preference">Destination directory</string>
<string name="share">Share</string>
<string name="share_received_file">Share \"%s\"</string>
<string name="title_activity_notification_filter">Notification filter</string>
<string name="filter_apps_info">Notifications will be synchronised for the selected apps.</string>
<string name="sftp_internal_storage">Internal storage</string>
@@ -169,6 +177,7 @@
<string name="plugin_not_supported">This plugin is not supported by the device</string>
<string name="findmyphone_title">Find my phone</string>
<string name="findmyphone_title_tablet">Find my tablet</string>
<string name="findmyphone_title_tv">Find my TV</string>
<string name="findmyphone_description">Rings this device so you can find it</string>
<string name="findmyphone_found">Found</string>
<string name="open">Open</string>
@@ -183,4 +192,17 @@
<string name="telepathy_permission_explanation">To read and write SMS from your desktop you need to give permission to SMS</string>
<string name="telephony_permission_explanation">To see phone calls and SMS from the desktop you need to give permission to phone calls and SMS</string>
<string name="telephony_optional_permission_explanation">To see a contact name instead of a phone number you need to give access to the phone\'s contacts</string>
<string name="select_ringtone">Select a ringtone</string>
<string name="telephony_pref_blocked_title">Blocked numbers</string>
<string name="telephony_pref_blocked_dialog_desc">Don\'t show calls and SMS from these numbers. Please specify one number per line</string>
<string name="mpris_coverart_description">Cover art of current media</string>
<string name="device_icon_description">Device icon</string>
<string name="settings_icon_description">Settings icon</string>
<string name="add_command">Add a command</string>
<string name="addcommand_explanation">There are no commands registered</string>
<string name="addcommand_explanation2">You can add new commands in the KDE Connect System Settings</string>
<string name="add_command_description">You can add commands on the desktop</string>
<string name="pref_plugin_mprisreceiver">Media Player Control</string>
<string name="pref_plugin_mprisreceiver_desc">Control your phones media players from another device</string>
<string name="dark_theme">Dark theme</string>
</resources>

View File

@@ -37,7 +37,7 @@
<string name="remotekeyboard_connected">La conexión remota de teclado está activa</string>
<string name="remotekeyboard_multiple_connections">Hay más de una conexión remota de teclado, seleccione el dispositivo a configurar</string>
<string name="open_mousepad">Entrada remota</string>
<string name="mousepad_info">Mueva un dedo sobre la pantalla para mover el cursor del ratón. Pulse para ejecutar un clic y use dos/tres dedos para emular los botones derecho y central. Use una pulsación larga para arrastrar y soltar.</string>
<string name="mousepad_info">Mueva un dedo sobre la pantalla para mover el cursor del ratón. Pulse para ejecutar un clic y use dos/tres dedos para emular los botones derecho y central. Use 2 dedos para desplazar las pantalla. Use una pulsación larga para arrastrar y soltar.</string>
<string name="mousepad_double_tap_settings_title">Establecer la acción al pulsar con dos dedos</string>
<string name="mousepad_triple_tap_settings_title">Establecer la acción al pulsar con tres dedos</string>
<string name="mousepad_sensitivity_settings_title">Establecer sensibilidad del panel táctil</string>
@@ -83,8 +83,10 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Enviando archivo a %1s</string>
<string name="outgoing_files_title">Enviando archivos a %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Enviados %1$d de %2$d archivos</string>
<plurals name="outgoing_files_text">
<item quantity="one">Enviado %1$d archivo</item>
<item quantity="other">Enviados %1$d de %2$d archivos</item>
</plurals>
<string name="received_file_title">Archivo recibido desde %1s</string>
<string name="received_file_fail_title">Fallo recibiendo archivo desde %1s</string>
<string name="received_file_text">Pulse para abrir «%1s»</string>
@@ -106,6 +108,7 @@
<string name="remote_control">Control remoto</string>
<string name="settings">Preferencias de KDE Connect</string>
<string name="mpris_play">Reproducir</string>
<string name="mpris_pause">Pausar</string>
<string name="mpris_previous">Anterior</string>
<string name="mpris_rew">Rebobinar</string>
<string name="mpris_ff">Avance rápido</string>
@@ -121,6 +124,8 @@
<item>1 minuto</item>
<item>2 minutos</item>
</string-array>
<string name="mpris_notification_settings_title">Mostrar notificación del control de medios</string>
<string name="mpris_notification_settings_summary">Permite controlar sus reproductores de medios sin abrir KDE Connect.</string>
<string name="share_to">Compartir con...</string>
<string name="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>
@@ -141,6 +146,8 @@
<string name="share_destination_customize_summary_disabled">Los archivos recibidos aparecerán en Descargas</string>
<string name="share_destination_customize_summary_enabled">Los archivos se almacenarán en el directorio indicado más abajo</string>
<string name="share_destination_folder_preference">Directorio destino</string>
<string name="share">Compartir</string>
<string name="share_received_file">Compartir «%s»</string>
<string name="title_activity_notification_filter">Filtro de notificaciones</string>
<string name="filter_apps_info">Las notificaciones se sincronizarán en las aplicaciones seleccionadas.</string>
<string name="sftp_internal_storage">Almacenamiento interno</string>
@@ -183,4 +190,14 @@
<string name="telepathy_permission_explanation">Para leer y escribir SMS desde su escritorio, necesita dar permisos para SMS</string>
<string name="telephony_permission_explanation">Para ver las llamadas telefónicas y SMS desde su escritorio, necesita dar permisos para llamadas telefónicas y SMS</string>
<string name="telephony_optional_permission_explanation">Para ver el nombre de un contacto en lugar de un número telefónico, necesita dar acceso a los contactos de su teléfono</string>
<string name="select_ringtone">Seleccionar tono</string>
<string name="telephony_pref_blocked_title">Números bloqueados</string>
<string name="telephony_pref_blocked_dialog_desc">No mostrar llamadas y SMS de estos números. Por favor, especifique solo un número por línea</string>
<string name="mpris_coverart_description">Carátula del medio actual</string>
<string name="device_icon_description">Icono del dispositivo</string>
<string name="settings_icon_description">Icono de preferencias</string>
<string name="add_command">Añadir una orden</string>
<string name="addcommand_explanation">No hay ninguna orden registrada</string>
<string name="addcommand_explanation2">Puede añadir nuevas órdenes en las preferencias del sistema de KDE Connect</string>
<string name="dark_theme">Tema oscuro</string>
</resources>

View File

@@ -31,7 +31,6 @@
<string name="send_ping">Saada ping</string>
<string name="open_mpris_controls">Multimeedia juhtimine</string>
<string name="open_mousepad">Kaugsisestus</string>
<string name="mousepad_info">Hiirekursori liigutamiseks liiguta sõrme ekraanil. Koputa klõpsamiseks ja kasuta kaht või kolme sõrme parema ja keskmise nupu jaoks. Pika vajutusega saab lohistada.</string>
<string name="mousepad_double_tap_settings_title">Kahe sõrmega koputamise toimingu määramine</string>
<string name="mousepad_triple_tap_settings_title">Kolme sõrmega koputamise toimingu määramine</string>
<string name="mousepad_sensitivity_settings_title">Puutepadja tundlikkuse määramine</string>
@@ -77,8 +76,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Faili saatmine seadmesse %1s</string>
<string name="outgoing_files_title">Failide saatmine seadmesse %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Saadetud %1$d / %2$d faili</string>
<string name="received_file_title">Faili saamine seadmest %1s</string>
<string name="received_file_fail_title">Faili saamine seadmest %1s nurjus</string>
<string name="received_file_text">Koputa \"%1s\" avamiseks</string>

View File

@@ -37,7 +37,6 @@
<string name="remotekeyboard_connected">Urruneko teklatuarekin konexioa aktibo dago</string>
<string name="remotekeyboard_multiple_connections">Urruneko teklatuekin konexio bat baino gehiago dago, hautatu konfiguratu beharreko gailua</string>
<string name="open_mousepad">Urruneko sarrera</string>
<string name="mousepad_info">Mugitu atzamarra pantailan saguaren erakuslea mugitzeko. Ukitu klik baterako, erabili bi/hiru atzamar eskuma eta erdiko botoientzat. Erabili presio luzea arrastatu eta jaregiteko.</string>
<string name="mousepad_double_tap_settings_title">Ezarri bi atzamarren ekintza</string>
<string name="mousepad_triple_tap_settings_title">Ezarri hiru atzamarren ekintza</string>
<string name="mousepad_sensitivity_settings_title">Ezarri ukimen-saguaren sentikortasuna</string>
@@ -83,8 +82,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Fitxategia bidaltzen %1s-ra</string>
<string name="outgoing_files_title">Fitxategiak bidaltzen %1s-ra</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">%1$d / %2$d fitxategi bidalita</string>
<string name="received_file_title">Fitxategia jaso da %1s-tik</string>
<string name="received_file_fail_title">Huts egin du fitxategia jasotzea %1s-tik</string>
<string name="received_file_text">Sakatu \'%1s\' irekitzeko</string>

View File

@@ -31,7 +31,6 @@
<string name="send_ping">Lähetä tiedustelupaketti</string>
<string name="open_mpris_controls">Multimedian ohjaus</string>
<string name="open_mousepad">Kauko-ohjaus</string>
<string name="mousepad_info">Liikuta hiiren osoitinta liikuttamalla sormeasi näytöllä. Napsauta napauttamalla yhdellä sormella, käytä oikeaa painiketta kahdella sormella ja keskipainiketta kolmella. Vedä ja pudota painamalla pitkään.</string>
<string name="mousepad_double_tap_settings_title">Aseta kahden sormen napautuksen toiminto</string>
<string name="mousepad_triple_tap_settings_title">Aseta kolmen sormen napautuksen toiminto</string>
<string name="mousepad_sensitivity_settings_title">Aseta kosketuslevyn herkkyys</string>
@@ -76,7 +75,6 @@
<string name="incoming_file_title">Saapuva tiedosto lähettäjältä %1s</string>
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Lähetetään tiedostoa laitteeseen %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="received_file_title">Vastaanotettiin tiedosto lähettäjältä %1s</string>
<string name="received_file_fail_title">Ei voitu vastaanottaa tiedostoa lähettäjältä %1s</string>
<string name="received_file_text">Avaa ”%1s” napauttamalla</string>

View File

@@ -37,7 +37,6 @@
<string name="remotekeyboard_connected">La connexion au clavier sans fil est active</string>
<string name="remotekeyboard_multiple_connections">Plusieurs connexions à des claviers sans fil sont disponibles, sélectionnez le périphérique à configurer</string>
<string name="open_mousepad">Contrôle distant</string>
<string name="mousepad_info">Déplacer le doigt sur l\'écran pour bouger le pointeur de la souris. Appuyez pour cliquer et utiliser deux/trois doigts pour les clic droit et centre. Appuyez longtemps pour faire un glisser déplacer.</string>
<string name="mousepad_double_tap_settings_title">Action pour l\'appui à deux doigts</string>
<string name="mousepad_triple_tap_settings_title">Action pour l\'appui à trois doigts</string>
<string name="mousepad_sensitivity_settings_title">Définir la sensibilité du pavé tactile</string>
@@ -83,8 +82,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Envoi d\'un fichier à %1s</string>
<string name="outgoing_files_title">Envoi de fichiers à %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Envoi de %1$d sur %2$d fichiers</string>
<string name="received_file_title">Fichier reçu de %1s</string>
<string name="received_file_fail_title">Impossible de recevoir le fichier depuis : %1s</string>
<string name="received_file_text">Appuyez pour ouvrir %1s</string>

View File

@@ -30,6 +30,7 @@
<string name="cancel">Cancelar</string>
<string name="open_settings">Abrir a configuración</string>
<string name="no_permissions">Debe conceder permisos para acceder ás notificacións.</string>
<string name="no_permission_mprisreceiver">Para poder controlar os seus reprodutores de son e vídeo ten que garantir acceso ás notificacións.</string>
<string name="send_ping">Enviar un ping</string>
<string name="open_mpris_controls">Control multimedia</string>
<string name="remotekeyboard_editing_only_title">Xestionar teclas remotas só ao editar.</string>
@@ -37,7 +38,7 @@
<string name="remotekeyboard_connected">A conexión de teclado remoto está activa.</string>
<string name="remotekeyboard_multiple_connections">Hai máis dunha conexión de teclado remoto, seleccione o dispositivo para configurar.</string>
<string name="open_mousepad">Entrada remota</string>
<string name="mousepad_info">Mova un dedo na pantalla para mover o cursor do rato. Toque para facer clic, e use dous ou tres dedos para os botóns secundario e central. Prema durante un tempo para arrastrar e soltar.</string>
<string name="mousepad_info">Mova un dedo na pantalla para mover o cursor do rato. Toque para facer clic, e use dous ou tres dedos para os botóns secundario e central. Use dous dedos para desprazar. Prema durante un tempo para arrastrar e soltar.</string>
<string name="mousepad_double_tap_settings_title">Definir a acción de tocar con dous dedos</string>
<string name="mousepad_triple_tap_settings_title">Definir a acción de tocar con tres dedos</string>
<string name="mousepad_sensitivity_settings_title">Definir a sensibilidade do punteiro táctil</string>
@@ -51,7 +52,7 @@
<item>O máis lento</item>
<item>Lento</item>
<item>Predeterminado</item>
<item>Rápido</item>
<item>Por riba do predeterminado</item>
<item>O máis rápido</item>
</string-array>
<string name="category_connected_devices">Dispositivos conectados</string>
@@ -83,8 +84,10 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Enviando un ficheiro a %1s</string>
<string name="outgoing_files_title">Enviando os ficheiros a %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Enviáronse %1$d de %2$d ficheiros.</string>
<plurals name="outgoing_files_text">
<item quantity="one">Enviouse %1$d ficheiro.</item>
<item quantity="other">Enviáronse %1$d de %2$d ficheiros.</item>
</plurals>
<string name="received_file_title">Recibiuse un ficheiro de %1s</string>
<string name="received_file_fail_title">A recepción do ficheiro de %1s fallou</string>
<string name="received_file_text">Toque para abrir «%1s».</string>
@@ -106,6 +109,7 @@
<string name="remote_control">Control remoto</string>
<string name="settings">Configuración de KDE Connect</string>
<string name="mpris_play">Reproducir</string>
<string name="mpris_pause">Deter</string>
<string name="mpris_previous">Anterior</string>
<string name="mpris_rew">Retroceder</string>
<string name="mpris_ff">Cara a adiante</string>
@@ -121,6 +125,8 @@
<item>1 minuto</item>
<item>2 minutos</item>
</string-array>
<string name="mpris_notification_settings_title">Mostrar a notificación de control de reprodución.</string>
<string name="mpris_notification_settings_summary">Permite controlar os reprodutores de son e vídeo sen abrir KDE Connect.</string>
<string name="share_to">Compartir con…</string>
<string name="protocol_version_older">Este dispositivo usa unha versión vella do protocolo.</string>
<string name="protocol_version_newer">Este dispositivo usa unha versión máis nova do protocolo.</string>
@@ -141,6 +147,8 @@
<string name="share_destination_customize_summary_disabled">Os ficheiros recibidos aparecerán en «Descargas».</string>
<string name="share_destination_customize_summary_enabled">Os ficheiros almacenaranse no directorio de abaixo.</string>
<string name="share_destination_folder_preference">Directorio de destino</string>
<string name="share">Compartir</string>
<string name="share_received_file">Compartir «%s»</string>
<string name="title_activity_notification_filter">Filtro de notificacións</string>
<string name="filter_apps_info">As notificacións sincronizaranse para os seguintes aplicativos.</string>
<string name="sftp_internal_storage">Almacenamento interno</string>
@@ -169,6 +177,7 @@
<string name="plugin_not_supported">O dispositivo non é compatíbel con este complemento.</string>
<string name="findmyphone_title">Atopar o móbil</string>
<string name="findmyphone_title_tablet">Atopar a tableta</string>
<string name="findmyphone_title_tv">Atopar o meu televisor</string>
<string name="findmyphone_description">Reproduce un son de chamada no dispositivo para que poida atopalo.</string>
<string name="findmyphone_found">Atopado</string>
<string name="open">Abrir</string>
@@ -183,4 +192,17 @@
<string name="telepathy_permission_explanation">Para ler e escribir SMS desde o escritorio ten que dar permiso de SMS.</string>
<string name="telephony_permission_explanation">Para ver as chamadas de teléfono e os SMS desde o escritorio ten que dar permiso a chamadas de teléfono e a SMS.</string>
<string name="telephony_optional_permission_explanation">Para ver o nome dun contacto en vez dun número de teléfono ten que dar acceso aos contactos do teléfono.</string>
<string name="select_ringtone">Seleccione un son de chamada</string>
<string name="telephony_pref_blocked_title">Números bloqueados</string>
<string name="telephony_pref_blocked_dialog_desc">Non mostrar chamadas nin SMS destes números. Indique un número por liña.</string>
<string name="mpris_coverart_description">Portada da obra actual.</string>
<string name="device_icon_description">Icona do dispositivo.</string>
<string name="settings_icon_description">Icona da configuración.</string>
<string name="add_command">Engadir unha orde</string>
<string name="addcommand_explanation">Non hai ordes rexistradas.</string>
<string name="addcommand_explanation2">Pode engadir novas ordes desde a configuración do sistema de KDE Connect.</string>
<string name="add_command_description">Pode engadir ordes no escritorio.</string>
<string name="pref_plugin_mprisreceiver">Control do reprodutor de multimedia</string>
<string name="pref_plugin_mprisreceiver_desc">Controlar os reprodutores do seu móbil desde outro dispositivo.</string>
<string name="dark_theme">Tema escuro</string>
</resources>

View File

@@ -37,7 +37,6 @@
<string name="remotekeyboard_connected">חיבור המקדלת המרוחקת פעיל</string>
<string name="remotekeyboard_multiple_connections">ישנם כמה מקלדות מרוחקות מחוברות, בחר את ההתקן להגדרה</string>
<string name="open_mousepad">שליטה מרחוק</string>
<string name="mousepad_info">הזז את האצבע על המסך כדי להזיז את סמן העכבר במחשב. לחץ כדי ללחוץ במחשב, השתמש בשנים או שלוש אצבעות כדי ללחוץ על המקש הימני או האמצעי. השתמש בליחצה ארוכה לגרירה ושחרור.</string>
<string name="mousepad_double_tap_settings_title">הגדר פעולה ללחיצת שתי אצבעות</string>
<string name="mousepad_triple_tap_settings_title">הגדר פעולה ללחיצת שלוש אצבעות</string>
<string name="mousepad_sensitivity_settings_title">הגדר רגישות משטח המגע</string>
@@ -83,8 +82,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">שולח קובץ אל %1s</string>
<string name="outgoing_files_title">שולח קובצים אל %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">"שולח %1$d מתוך %2$d קבצים "</string>
<string name="received_file_title">התקבל קובץ מאת %1s</string>
<string name="received_file_fail_title">נכשל בקבלת קובץ מאת %1s</string>
<string name="received_file_text">לחץ כדי לפתוח את \"%1s\"</string>

View File

@@ -30,6 +30,7 @@
<string name="cancel">Annulla</string>
<string name="open_settings">Apri impostazioni</string>
<string name="no_permissions">Devi concedere i permessi per l\'accesso alle notifiche</string>
<string name="no_permission_mprisreceiver">Per poter controllare i tuoi lettori multimediali devi accordare l\'accesso alle notifiche</string>
<string name="send_ping">Invia ping</string>
<string name="open_mpris_controls">Controllo multimediale</string>
<string name="remotekeyboard_editing_only_title">Gestisci i tasti remoti solo durante la modifica</string>
@@ -37,7 +38,7 @@
<string name="remotekeyboard_connected">La connessione della tastiera remota è attiva</string>
<string name="remotekeyboard_multiple_connections">Ci sono più connessioni di tastiere remote, seleziona il dispositivo da configurare</string>
<string name="open_mousepad">Impulso remoto</string>
<string name="mousepad_info">Muovi un dito sullo schermo per spostare il puntatore del mouse. Tocca per un clic e usa due/tre dita per i pulsanti destro e centrale. Utilizza una pressione lunga per trascinare e rilasciare.</string>
<string name="mousepad_info">Muovi un dito sullo schermo per spostare il puntatore del mouse. Tocca per un clic e usa due/tre dita per i pulsanti destro e centrale. Utilizza 2 dita per scorrere. Utilizza una pressione lunga per trascinare e rilasciare.</string>
<string name="mousepad_double_tap_settings_title">Imposta azione per il tocco a due dita</string>
<string name="mousepad_triple_tap_settings_title">Imposta azione per il tocco a tre dita</string>
<string name="mousepad_sensitivity_settings_title">Imposta la sensibilità del touchpad</string>
@@ -83,8 +84,10 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Invio file a %1s</string>
<string name="outgoing_files_title">Invio file a %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Inviati %1$d di %2$d file</string>
<plurals name="outgoing_files_text">
<item quantity="one">Inviato %1$d file</item>
<item quantity="other">Inviati %1$d di %2$d file</item>
</plurals>
<string name="received_file_title">File ricevuto da %1s</string>
<string name="received_file_fail_title">Ricezione file da %1s non riuscita</string>
<string name="received_file_text">Tocca per aprire «%1s»</string>
@@ -106,6 +109,7 @@
<string name="remote_control">Telecomando</string>
<string name="settings">Impostazioni</string>
<string name="mpris_play">Riproduci</string>
<string name="mpris_pause">Pausa</string>
<string name="mpris_previous">Precedente</string>
<string name="mpris_rew">Riavvolgi</string>
<string name="mpris_ff">Avanti veloce</string>
@@ -121,6 +125,8 @@
<item>1 minuto</item>
<item>2 minuti</item>
</string-array>
<string name="mpris_notification_settings_title">Mostra la notifica del controllo multimediale</string>
<string name="mpris_notification_settings_summary">Consente di controllare i lettori multimediali senza aprire KDE Connect.</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>
@@ -141,6 +147,8 @@
<string name="share_destination_customize_summary_disabled">I file ricevuti saranno visualizzati in Downloads</string>
<string name="share_destination_customize_summary_enabled">I file saranno memorizzati nella cartella seguente</string>
<string name="share_destination_folder_preference">Cartella di destinazione</string>
<string name="share">Condividi</string>
<string name="share_received_file">Condividi «%s»</string>
<string name="title_activity_notification_filter">Filtro delle notifiche</string>
<string name="filter_apps_info">Le notifiche saranno sincronizzate per le applicazioni selezionate.</string>
<string name="sftp_internal_storage">Archiviazione interna</string>
@@ -183,4 +191,16 @@
<string name="telepathy_permission_explanation">Per leggere e scrivere SMS dal tuo desktop, devi concedere l\'autorizzazione per SMS</string>
<string name="telephony_permission_explanation">Per vedere le chiamate telefoniche e gli SMS dal desktop devi dare l\'autorizzazione per telefonate e SMS</string>
<string name="telephony_optional_permission_explanation">Per vedere il nome di un contatto invece del numero di telefono devi dare accesso alla rubrica del telefono</string>
<string name="select_ringtone">Seleziona una suoneria</string>
<string name="telephony_pref_blocked_title">Numeri bloccati</string>
<string name="telephony_pref_blocked_dialog_desc">Non mostrare le chiamate e gli SMS da questi numeri. Specifica un numero per riga</string>
<string name="mpris_coverart_description">Copertina del media attuale</string>
<string name="device_icon_description">Icona dispositivo</string>
<string name="settings_icon_description">Icona impostazioni</string>
<string name="add_command">Aggiungi un comando</string>
<string name="addcommand_explanation">Non ci sono comandi registrati</string>
<string name="addcommand_explanation2">Puoi aggiungere nuovi comandi nelle impostazioni di sistema di KDE Connect</string>
<string name="pref_plugin_mprisreceiver">Controllo lettore multimediale</string>
<string name="pref_plugin_mprisreceiver_desc">Controlla i lettori multimediali del tuo telefono da un altro dispositivo</string>
<string name="dark_theme">Tema scuro</string>
</resources>

View File

@@ -31,7 +31,6 @@
<string name="send_ping">핑 보내기</string>
<string name="open_mpris_controls">멀티미디어 제어</string>
<string name="open_mousepad">원격 입력</string>
<string name="mousepad_info">화면에서 손가락을 움직이면 마우스 커서를 움직입니다. 화면을 누르면 왼쪽 단추를 누르고, 두 손가락과 세 손가락으로 누르면 오른쪽/가운데 단추를 누릅니다. 드래그 앤 드롭을 사용하려면 길게 누르십시오.</string>
<string name="mousepad_double_tap_settings_title">두 손가락으로 눌렀을 때 동작 설정</string>
<string name="mousepad_triple_tap_settings_title">세 손가락으로 눌렀을 때 동작 설정</string>
<string name="mousepad_sensitivity_settings_title">터치패드 감도 설정</string>
@@ -77,8 +76,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">%1s(으)로 파일 보내는 중</string>
<string name="outgoing_files_title">%1s(으)로 파일 보내는 중</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">파일 %2$d개 중 %1$d개 보냄</string>
<string name="received_file_title">%1s에서 파일 받음</string>
<string name="received_file_fail_title">%1s에서 파일 받기 실패</string>
<string name="received_file_text">\'%1s\'을(를) 열려면 누르십시오</string>

View File

@@ -30,6 +30,7 @@
<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="no_permission_mprisreceiver">Om in staat te zijn uw mediaspelers te besturen moet u toegan geven tot de meldingen</string>
<string name="send_ping">Ping verzenden</string>
<string name="open_mpris_controls">Bediening van multimedia</string>
<string name="remotekeyboard_editing_only_title">Behandel toetsen op afstand alleen bij bewerken</string>
@@ -37,7 +38,7 @@
<string name="remotekeyboard_connected">Verbinding met toetsenbord op afstand is actief</string>
<string name="remotekeyboard_multiple_connections">Er is meer dan een verbinding met een toetsenbord op afstand, selecteer het te configureren apparaat</string>
<string name="open_mousepad">Invoer op afstand</string>
<string name="mousepad_info">Veeg met een vinger op het scherm om de muiscursor te verplaatsen. Tik om te klikken en gebruik twee/drie vingers voor rechter en middelste knop. Druk lang voor slepen en loslaten.</string>
<string name="mousepad_info">Veeg met een vinger op het scherm om de muiscursor te verplaatsen. Tik om te klikken en gebruik twee/drie vingers voor rechter en middelste knop. Twee vingers gebruiken voor schuiven. Druk lang voor slepen en loslaten.</string>
<string name="mousepad_double_tap_settings_title">Tikactie met twee vingers instellen</string>
<string name="mousepad_triple_tap_settings_title">Tikactie met drie vingers instellen</string>
<string name="mousepad_sensitivity_settings_title">Gevoeligheid van touchpad instellen</string>
@@ -83,8 +84,10 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Bezig bestand te verzenden naar %1s</string>
<string name="outgoing_files_title">Bezig bestanden te verzenden naar %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Verzonden %1$d uit %2$d bestanden</string>
<plurals name="outgoing_files_text">
<item quantity="one">Bestand %1$d verzenden</item>
<item quantity="other">%1$d bestanden uit %2$d verzenden</item>
</plurals>
<string name="received_file_title">Bestand ontvangen van %1s</string>
<string name="received_file_fail_title">Bestand ontvangen van %1s is mislukt</string>
<string name="received_file_text">Tap om \'%1s\' te openen</string>
@@ -106,6 +109,7 @@
<string name="remote_control">Afstandsbediening</string>
<string name="settings">Instellingen van KDE Connect</string>
<string name="mpris_play">Afspelen</string>
<string name="mpris_pause">Pauzeren</string>
<string name="mpris_previous">Vorige</string>
<string name="mpris_rew">Terugspoelen</string>
<string name="mpris_ff">Snel vooruit</string>
@@ -121,6 +125,8 @@
<item>1 minuut</item>
<item>2 minuten</item>
</string-array>
<string name="mpris_notification_settings_title">Mediabesturingsmelding tonen</string>
<string name="mpris_notification_settings_summary">Staat besturing van uw mediaspelers toe zonder KDE Connect te openen.</string>
<string name="share_to">Delen met...</string>
<string name="protocol_version_older">Dit apparaat gebruikt een oude protocolversie</string>
<string name="protocol_version_newer">Dit apparaat gebruikt een nieuwere protocolversie</string>
@@ -141,6 +147,8 @@
<string name="share_destination_customize_summary_disabled">Ontvangen bestanden zullen in Downloads verschijnen</string>
<string name="share_destination_customize_summary_enabled">Bestanden zullen opgeslagen worden in de onderstaande map</string>
<string name="share_destination_folder_preference">Bestemmingsmap</string>
<string name="share">Delen</string>
<string name="share_received_file">\"%s\" delen</string>
<string name="title_activity_notification_filter">Filter voor meldingen</string>
<string name="filter_apps_info">Meldingen zullen gesynchroniseerd worden voor de geselecteerde apps.</string>
<string name="sftp_internal_storage">Interne opslag</string>
@@ -169,6 +177,7 @@
<string name="plugin_not_supported">Deze plug-in wordt niet ondersteund door het apparaat</string>
<string name="findmyphone_title">Zoek mijn telefoon</string>
<string name="findmyphone_title_tablet">Zoek mijn tablet</string>
<string name="findmyphone_title_tv">Zoek mijn tv</string>
<string name="findmyphone_description">Laat dit apparaat bellen zodat u het kunt vinden</string>
<string name="findmyphone_found">Gevonden</string>
<string name="open">Openen</string>
@@ -183,4 +192,17 @@
<string name="telepathy_permission_explanation">Om een SMS te lezen of te schrijven vanaf uw bureaublad moet u toestemming geven tot SMS</string>
<string name="telephony_permission_explanation">Om telefoonoproepen en SMS te zien vanaf het bureaublad moet u toestemming geven tot telefoonoproepen en SMS</string>
<string name="telephony_optional_permission_explanation">Om een naam van een contactpersoon te zien in plaats van een telefoonnummer moet u toegang geven tot de contacten in uw telefoon</string>
<string name="select_ringtone">Selecteer een ringtone</string>
<string name="telephony_pref_blocked_title">Geblokkeerde nummers</string>
<string name="telephony_pref_blocked_dialog_desc">Geen oproepen en SMSen vanaf deze nummers tonen. Specificeer één nummer per regel</string>
<string name="mpris_coverart_description">Cover-illustratie van huidige media</string>
<string name="device_icon_description">Apparaatpictogram</string>
<string name="settings_icon_description">Pictogram voor instellingen</string>
<string name="add_command">Een commando toevoegen</string>
<string name="addcommand_explanation">Er zijn geen commando\'s geregistreerd</string>
<string name="addcommand_explanation2">U kunt nieuwe commando\'s in de instellingen voor het KDE connect-systeem toevoegen</string>
<string name="add_command_description">U kunt commando\'s toevoegen op het bureaublad</string>
<string name="pref_plugin_mprisreceiver">Besturing van mediaspeler</string>
<string name="pref_plugin_mprisreceiver_desc">Uw mediaspelers op uw telefoon besturen vanaf een andere apparaat</string>
<string name="dark_theme">Donker themea</string>
</resources>

View File

@@ -9,15 +9,15 @@
<string name="pref_plugin_clipboard">Synkroniser utklippstavle</string>
<string name="pref_plugin_clipboard_desc">Del innhaldet på utklippstavla</string>
<string name="pref_plugin_mousepad">Fjernstyring</string>
<string name="pref_plugin_mousepad_desc">Bruk telefonen eller nettbrettet som styrepute og tastatur</string>
<string name="pref_plugin_mousepad_desc">Bruk telefonen eller nettbrettet som styreplate og tastatur</string>
<string name="pref_plugin_remotekeyboard">Ta imot eksterne tastetrykk</string>
<string name="pref_plugin_remotekeyboard_desc">Ta imot tastetrykk frå eksterne einingar</string>
<string name="pref_plugin_mpris">Mediekontrollar</string>
<string name="pref_plugin_mpris_desc">Gjev fjernkontroll til mediespelarar</string>
<string name="pref_plugin_mpris_desc">Gje fjernkontroll til mediespelarar</string>
<string name="pref_plugin_runcommand">Køyr kommando</string>
<string name="pref_plugin_runcommand_desc">Utløys fjernkommandoar frå telefonen eller nettbrettet</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Send og ta imot ping-signal</string>
<string name="pref_plugin_ping_desc">Send og ta imot pingsignal</string>
<string name="pref_plugin_notifications">Varslingssynkronisering</string>
<string name="pref_plugin_notifications_desc">Få tilgang til varslingar frå andre einingar</string>
<string name="pref_plugin_receive_notifications">Få varslingar</string>
@@ -37,10 +37,10 @@
<string name="remotekeyboard_connected">Eksternt tastatursamband er verksamt</string>
<string name="remotekeyboard_multiple_connections">Det finst meir enn eitt eksternt tastatursamband (vel eining å setja opp)</string>
<string name="open_mousepad">Fjernstyring</string>
<string name="mousepad_info">Dra ein finger over skjermen for å flytta peikaren på datamaskina. Trykk for å klikka, og bruk to eller tre fingrar for høvesvis høgre- og midtknappen. Trykk og hald for å dra og sleppa.</string>
<string name="mousepad_info">Dra ein finger over skjermen for å flytta peikaren på datamaskina. Trykk for å klikka, og bruk to eller tre fingrar for høvesvis høgre- og midtknappen. Bruk to fingrar for å rulla. Trykk lenge for å dra og sleppa.</string>
<string name="mousepad_double_tap_settings_title">Vel handling for tofingertrykk</string>
<string name="mousepad_triple_tap_settings_title">Vel handling for trefingertrykk</string>
<string name="mousepad_sensitivity_settings_title">Vel følsemd for styrepute</string>
<string name="mousepad_sensitivity_settings_title">Vel følsemd for styreplate</string>
<string name="mousepad_scroll_direction_title">Omvend rulleretning</string>
<string-array name="mousepad_tap_entries">
<item>Høgreklikk</item>
@@ -58,7 +58,7 @@
<string name="category_not_paired_devices">Tilgjengelege einingar</string>
<string name="category_remembered_devices">Hugs einingar</string>
<string name="plugins_failed_to_load">Klarte ikkje lasta programtillegg (trykk for meir informasjon):</string>
<string name="device_menu_plugins">Innstillingar for programtillegg</string>
<string name="device_menu_plugins">Programtillegg-oppsett</string>
<string name="device_menu_unpair">Løys paring</string>
<string name="device_not_reachable">Får ikkje kontakt med para eining</string>
<string name="pair_new_device">Par ny eining</string>
@@ -73,8 +73,8 @@
<string name="error_invalid_key">Fekk ugyldig nøkkel</string>
<string name="encryption_info_title">Krypteringsinfo</string>
<string name="encryption_info_msg_no_ssl">Den andre eininga brukar ein gammal versjon av KDE Connect, med ein utdatert krypteringsmetode.</string>
<string name="my_device_fingerprint">SHA-fingeravtrykk av einingssertifikatet er:</string>
<string name="remote_device_fingerprint">SHA-fingeravtrykk av fjerneiningssertifikatet er:</string>
<string name="my_device_fingerprint">SHA-fingeravtrykket til einingssertifikatet er:</string>
<string name="remote_device_fingerprint">SHA-fingeravtrykket fjerneiningssertifikatet er:</string>
<string name="pair_requested">Paringsførespurnad</string>
<string name="pairing_request_from">Paringsførespurnad frå %1s</string>
<string name="received_url_title">Fekk lenkje frå %1s</string>
@@ -83,8 +83,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Sender fil til %1s</string>
<string name="outgoing_files_title">Sender filer til %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Sende %1$d av %2$d filer</string>
<string name="received_file_title">Fekk fil frå %1s</string>
<string name="received_file_fail_title">Klarte ikkje ta imot fil frå %1s</string>
<string name="received_file_text">Trykk for å opna «%1s»</string>
@@ -113,7 +111,7 @@
<string name="mpris_volume">Lydstyrke</string>
<string name="mpris_settings">Medieinnstillingar</string>
<string name="mpris_time_settings_title">Spoleknappar</string>
<string name="mpris_time_settings_summary">Juster tida for spoling ved trykking.</string>
<string name="mpris_time_settings_summary">Juster tida for spoling ved trykking</string>
<string-array name="mpris_time_entries">
<item>10 sekund</item>
<item>20 sekund</item>
@@ -137,9 +135,9 @@
<string name="custom_device_list">Legg til eining basert på IP</string>
<string name="share_notification_preference">Lydvarsling</string>
<string name="share_notification_preference_summary">Vibrer og spel ein lyd ved mottak av fil</string>
<string name="share_destination_customize">Tilpassa målmappe</string>
<string name="share_destination_customize">Sjølvvald målmappe</string>
<string name="share_destination_customize_summary_disabled">Mottekne filer vert lagra i nedlastingsmappa</string>
<string name="share_destination_customize_summary_enabled">Filer vert lagra i mappa nedanfor</string>
<string name="share_destination_customize_summary_enabled">Mottekne filer vert lagra i mappa nedanfor</string>
<string name="share_destination_folder_preference">Målmappe</string>
<string name="title_activity_notification_filter">Varslingsfilter</string>
<string name="filter_apps_info">Varslingar vert synkroniserte for dei valde appane.</string>
@@ -169,7 +167,7 @@
<string name="plugin_not_supported">Dette tillegget er ikkje støtta av eininga</string>
<string name="findmyphone_title">Finn telefonen min</string>
<string name="findmyphone_title_tablet">Finn nettbrettet mitt</string>
<string name="findmyphone_description">Ring til eininga, slik at du kan finna ho</string>
<string name="findmyphone_description">Spel av lydsignal på eininga, slik at du lett kan finna ho</string>
<string name="findmyphone_found">Fann</string>
<string name="open">Opna</string>
<string name="close">Lukk</string>

View File

@@ -37,7 +37,7 @@
<string name="remotekeyboard_connected">Połączenie zdalnej klawiatury jest nawiązane</string>
<string name="remotekeyboard_multiple_connections">Nawiązano więcej niż jedno połączenie zdalnej klawiatury, wybierz urządzenie do ustawienia</string>
<string name="open_mousepad">Zdalne sterowanie</string>
<string name="mousepad_info">Przesuń palcem po ekranie, aby przesunąć wskaźnik myszy. Stuknij, aby wywołać naciśniecie lewym przyciskiem myszy i użyj dwóch/trzech palców, aby wywołać naciśniecie prawym i środkowym przyciskiem myszy. Przyciśnij na dłużej, aby przeciągnąć i upuścić.</string>
<string name="mousepad_info">Przesuń palcem po ekranie, aby przesunąć wskaźnik myszy. Stuknij, aby wywołać naciśniecie lewym przyciskiem myszy i użyj dwóch/trzech palców, aby wywołać naciśniecie prawym i środkowym przyciskiem myszy. Przewijaj przy użyciu dwóch palców. Przyciśnij na dłużej, aby przeciągnąć i upuścić.</string>
<string name="mousepad_double_tap_settings_title">Ustaw działanie po dwukrotnym stuknięciu palcem</string>
<string name="mousepad_triple_tap_settings_title">Ustaw działanie po trzykrotnym stuknięciu palcem</string>
<string name="mousepad_sensitivity_settings_title">Ustaw czułość gładzika</string>
@@ -83,8 +83,12 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Wysyłanie pliku do %1s</string>
<string name="outgoing_files_title">Wysyłanie pliku do %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Wysłano %1$d z %2$d plików</string>
<plurals name="outgoing_files_text">
<item quantity="one">Wysłano %1$d plik</item>
<item quantity="few">Wysłano %1$d z %2$d plików</item>
<item quantity="many">Wysłano %1$d z %2$d plików</item>
<item quantity="other"/>
</plurals>
<string name="received_file_title">Odebrano plik od %1s</string>
<string name="received_file_fail_title">Nieudane odbieranie pliku z %1s</string>
<string name="received_file_text">Znacznik do otwarcia \'%1s\'</string>
@@ -106,6 +110,7 @@
<string name="remote_control">Zdalne sterowanie</string>
<string name="settings">Ustawienia KDE Connect</string>
<string name="mpris_play">Odtwórz</string>
<string name="mpris_pause">Wstrzymaj</string>
<string name="mpris_previous">Poprzedni</string>
<string name="mpris_rew">Przewiń</string>
<string name="mpris_ff">Przewiń do przodu</string>
@@ -121,6 +126,8 @@
<item>1 minuta</item>
<item>2 minuty</item>
</string-array>
<string name="mpris_notification_settings_title">Pokaż powiadomienia sterowania mediami</string>
<string name="mpris_notification_settings_summary">Umożliwia sterowanie odtwarzaczami bez otwierania KDE Connect.</string>
<string name="share_to">Współdziel z...</string>
<string name="protocol_version_older">Urządzenie to używa starej wersji protokołu</string>
<string name="protocol_version_newer">Urządzenie to używa nowszej wersji protokołu</string>
@@ -163,7 +170,7 @@
<string name="refresh">Odśwież</string>
<string name="unreachable_description">To sparowane urządzenie jest nieosiągalne. Upewnij się, że jest podłączone do tej samej sieci.</string>
<string name="on_data_message">Wygląda na to, że korzystasz z internetu mobilnego. KDE Connect działa tylko na lokalnych sieciach.</string>
<string name="no_file_browser">Nie wgrano żadanych przeglądarek plików.</string>
<string name="no_file_browser">Nie wgrano żadnych przeglądarek plików.</string>
<string name="pref_plugin_telepathy">Wyślij SMS-a</string>
<string name="pref_plugin_telepathy_desc">Wyślij wiadomość tekstową z komputera</string>
<string name="plugin_not_supported">Ta wtyczka nie jest obsługiwana przez to urządzenie</string>
@@ -183,4 +190,13 @@
<string name="telepathy_permission_explanation">Aby odczytywać i pisać SMSy z twojego komputera musisz nadać uprawnienia do SMSów</string>
<string name="telephony_permission_explanation">Aby widzieć rozmowy telefoniczne i SMSy z twojego komputera musisz nadać uprawnienia na rozmowy telefoniczne i SMSy</string>
<string name="telephony_optional_permission_explanation">Aby widzieć nazwę kontaktu zamiast numeru telefonu musisz pozwolić na dostęp do kontaktów telefonu</string>
<string name="select_ringtone">Wybierz dzwonek</string>
<string name="telephony_pref_blocked_title">Zablokowane numery</string>
<string name="telephony_pref_blocked_dialog_desc">Nie pokazuj rozmów, ani SMSów z tych numerów. Podawaj jeden numer na wiersz</string>
<string name="mpris_coverart_description">Okładka dla bieżących multimediów</string>
<string name="device_icon_description">Ikona urządzenia</string>
<string name="settings_icon_description">Ikona ustawień</string>
<string name="add_command">Dodaj polecenie</string>
<string name="addcommand_explanation">Nie zarejestrowano żadnych poleceń</string>
<string name="addcommand_explanation2">Nowe polecenia można dodawać w ustawieniach systemowych KDE Connect</string>
</resources>

View File

@@ -29,7 +29,6 @@
<string name="send_ping">Enviar ping</string>
<string name="open_mpris_controls">Controle multimídia</string>
<string name="open_mousepad">Introdução de dados remota</string>
<string name="mousepad_info">Mova um dedo pela tela para mover o ponteiro do mouse. Dê um toque para clicar e use dois/três dedos para os botões da direita e do meio. Use uma pressão longa para arrastar e soltar.</string>
<string name="mousepad_double_tap_settings_title">Definir a ação do toque com dois dedos</string>
<string name="mousepad_triple_tap_settings_title">Definir a ação do toque com três dedos</string>
<string name="mousepad_sensitivity_settings_title">Definir a sensibilidade do touchpad</string>
@@ -71,7 +70,6 @@
<string name="incoming_file_title">Arquivo recebido de %1s</string>
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Enviando arquivo para %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="received_file_title">Arquivo recebido de %1s</string>
<string name="received_file_fail_title">Falha ao receber o arquivo de %1s</string>
<string name="received_file_text">Toque para abrir o \'%1s\'</string>

View File

@@ -30,6 +30,7 @@
<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="no_permission_mprisreceiver">Para poder controlar os seus leitores multimédia, terá de dar acesso às notificações</string>
<string name="send_ping">Enviar um pedido de contacto</string>
<string name="open_mpris_controls">Comando multimédia</string>
<string name="remotekeyboard_editing_only_title">Lidar com as teclas remotas apenas na edição</string>
@@ -83,8 +84,10 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">A enviar o ficheiro para o %1s</string>
<string name="outgoing_files_title">A enviar os ficheiros para o %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Foram enviados %1$d de %2$d ficheiros</string>
<plurals name="outgoing_files_text">
<item quantity="one">Foi enviado %1$d ficheiro</item>
<item quantity="other">Foram enviados %1$d de %2$d ficheiros</item>
</plurals>
<string name="received_file_title">Ficheiro recebido de %1s</string>
<string name="received_file_fail_title">Falhou a recepção do ficheiro de %1s</string>
<string name="received_file_text">Toque para abrir o \'%1s\'</string>
@@ -106,6 +109,7 @@
<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_pause">Pausa</string>
<string name="mpris_previous">Anterior</string>
<string name="mpris_rew">Recuar</string>
<string name="mpris_ff">Avançar</string>
@@ -121,6 +125,8 @@
<item>1 minuto</item>
<item>2 minutos</item>
</string-array>
<string name="mpris_notification_settings_title">Mostrar a notificação do controlo multimédia</string>
<string name="mpris_notification_settings_summary">Permite controlar os seus leitores multimédia sem abrir o KDE Connect.</string>
<string name="share_to">Partilhar Com...</string>
<string name="protocol_version_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>
@@ -141,6 +147,8 @@
<string name="share_destination_customize_summary_disabled">Os ficheiros recebidos irão aparecer em \'Transferências\'</string>
<string name="share_destination_customize_summary_enabled">Os ficheiros serão guardados na pasta abaixo</string>
<string name="share_destination_folder_preference">Pasta de destino</string>
<string name="share">Partilhar</string>
<string name="share_received_file">Partilhar o \"%s\"</string>
<string name="title_activity_notification_filter">Filtro de notificações</string>
<string name="filter_apps_info">As notificações serão sincronizadas para as aplicações seleccionadas.</string>
<string name="sftp_internal_storage">Armazenamento interno</string>
@@ -169,6 +177,7 @@
<string name="plugin_not_supported">Este \'plugin\' não é suportado pelo dispositivo</string>
<string name="findmyphone_title">Descobrir o meu telefone</string>
<string name="findmyphone_title_tablet">Descobrir o meu \'tablet\'</string>
<string name="findmyphone_title_tv">Descobrir a minha TV</string>
<string name="findmyphone_description">Toca este dispositivo para que o possa encontrar</string>
<string name="findmyphone_found">Encontrado</string>
<string name="open">Abrir</string>
@@ -183,4 +192,17 @@
<string name="telepathy_permission_explanation">Para ler e escrever SMS\'s a partir do seu ambiente de trabalho, precisa de dar permissões para os SMS\'s</string>
<string name="telephony_permission_explanation">Para ver as chamadas e os SMS\'s a partir do seu ambiente de trabalho, precisa de dar permissões para as chamadas telefónicas e SMS\'s</string>
<string name="telephony_optional_permission_explanation">Para ver o nome de um contacto em vez do seu número de telefone, precisa de dar acesso aos contactos do telemóvel</string>
<string name="select_ringtone">Seleccione um toque de chamada</string>
<string name="telephony_pref_blocked_title">Números bloqueados</string>
<string name="telephony_pref_blocked_dialog_desc">Não mostrar as chamadas e SMS\'s desses números. Por favor, indique um número por linha</string>
<string name="mpris_coverart_description">Capa do conteúdo actual</string>
<string name="device_icon_description">Ícone do dispositivo</string>
<string name="settings_icon_description">Ícone de configuração</string>
<string name="add_command">Adicionar um comando</string>
<string name="addcommand_explanation">Não existem comandos registados</string>
<string name="addcommand_explanation2">Poderá adicionar comandos novos na Configuração do Sistema KDE Connect</string>
<string name="add_command_description">Poderá adicionar comandos no ambiente de trabalho</string>
<string name="pref_plugin_mprisreceiver">Controlo de Leitores Multimédia</string>
<string name="pref_plugin_mprisreceiver_desc">Controle os leitores multimédia dos seus telemóveis a partir de outro dispositivo</string>
<string name="dark_theme">Tema escuro</string>
</resources>

View File

@@ -37,7 +37,6 @@
<string name="remotekeyboard_connected">Соединение с удалённой клавиатурой активно</string>
<string name="remotekeyboard_multiple_connections">Подключено более одной удалённой клавиатуры, выберите устройство для настройки</string>
<string name="open_mousepad">Удалённый ввод</string>
<string name="mousepad_info">Перемещайте палец по экрану для перемещения курсора мыши. Коснитесь для нажатия, используйте два/три пальца для правой и средней кнопок. Используйте долгое нажатие для перетаскивания.</string>
<string name="mousepad_double_tap_settings_title">Действие при нажатии двумя пальцами</string>
<string name="mousepad_triple_tap_settings_title">Действие при нажатии тремя пальцами</string>
<string name="mousepad_sensitivity_settings_title">Чувствительность сенсорной панели</string>
@@ -83,8 +82,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Отправка файла на %1s</string>
<string name="outgoing_files_title">Отправка файлов на %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Отправлено %1$d из %2$d файлов</string>
<string name="received_file_title">Получен файл с %1s</string>
<string name="received_file_fail_title">Не удалось получить файл с %1s</string>
<string name="received_file_text">Нажмите, чтобы открыть «%1s»</string>

View File

@@ -31,7 +31,6 @@
<string name="send_ping">Poslať ping</string>
<string name="open_mpris_controls">Multimediálny ovládač</string>
<string name="open_mousepad">Vzdialený vstup</string>
<string name="mousepad_info">Posúvajte prst na obrazovke na posun kurzora. Ťuknutie vyvolá klik a použite dva/tri prsty pre pravé a stredné tlačidlo. Použite dlhé stlačenie pre drag and drop.</string>
<string name="mousepad_double_tap_settings_title">Nastaviť akciu dvoch prstov</string>
<string name="mousepad_triple_tap_settings_title">Nastaviť akciu troch prstov</string>
<string name="mousepad_sensitivity_settings_title">Nastaviť citlivosť touchpadu</string>
@@ -76,7 +75,6 @@
<string name="incoming_file_title">Prichádzajúci súbor od %s</string>
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Posielam súbor pre %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="received_file_title">Prijatý súbor od %1s</string>
<string name="received_file_fail_title">Zlyhalo prijatie súboru od %1s</string>
<string name="received_file_text">Ťuknite na otvorenie \'%1s\'</string>

View File

@@ -37,7 +37,6 @@
<string name="remotekeyboard_connected">Веза даљинске тастатуре је активна</string>
<string name="remotekeyboard_multiple_connections">Постоји више од једне везе даљинске тастатуре. Изаберите уређај да бисте подесили</string>
<string name="open_mousepad">Даљински унос</string>
<string name="mousepad_info">Померајте прст по екрану да бисте померали показивач миша. Тапните за клик или користите два/три прста за десни или средњи клик. Задржите за превуци и пусти.</string>
<string name="mousepad_double_tap_settings_title">Радња за додир са два прста</string>
<string name="mousepad_triple_tap_settings_title">Радња за додир са три прста</string>
<string name="mousepad_sensitivity_settings_title">Постави осетљивост додирника</string>
@@ -83,8 +82,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Шаљем фајл на %1s</string>
<string name="outgoing_files_title">Шаљем фајлове на %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Послато %1$d од %2$d фајлова</string>
<string name="received_file_title">Примљен фајл са %1s</string>
<string name="received_file_fail_title">Неуспео пријем фајла са %1s</string>
<string name="received_file_text">Тапните да отворите „%1s“</string>

View File

@@ -30,6 +30,7 @@
<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="no_permission_mprisreceiver">För att kunna styra mediaspelare måste du ge tillgång till underrättelser</string>
<string name="send_ping">Skicka ping</string>
<string name="open_mpris_controls">Kontroll av multimedia</string>
<string name="remotekeyboard_editing_only_title">Hantera bara externa tangenter vid redigering</string>
@@ -37,7 +38,7 @@
<string name="remotekeyboard_connected">Anslutning till externt tangentbord är aktiv</string>
<string name="remotekeyboard_multiple_connections">Det finns mer än en anslutning till externt tangentbord, välj enhet att anpassa</string>
<string name="open_mousepad">Extern inmatning</string>
<string name="mousepad_info">Flytta fingret på skärmen för att röra muspekaren. Rör för att klicka, och använd två eller tre fingrar för höger- och mittenknapparna. Använd en längre beröring för drag och släpp.</string>
<string name="mousepad_info">Flytta fingret på skärmen för att röra muspekaren. Rör för att klicka, och använd två eller tre fingrar för höger- och mittenknapparna. Använd två fingrar för att panorera. Använd en längre beröring för drag och släpp.</string>
<string name="mousepad_double_tap_settings_title">Ställ in åtgärd vid två fingerberöringar</string>
<string name="mousepad_triple_tap_settings_title">Ställ in åtgärd vid tre fingerberöringar</string>
<string name="mousepad_sensitivity_settings_title">Ställ in tryckplattans känslighet</string>
@@ -83,8 +84,10 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Skickar fil till %1s</string>
<string name="outgoing_files_title">Skickar filer till %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Skickade %1$d av %2$d filer</string>
<plurals name="outgoing_files_text">
<item quantity="one">Skickade %1$d fil</item>
<item quantity="other">Skickade %1$d av %2$d filer</item>
</plurals>
<string name="received_file_title">Tog emot fil från %1s</string>
<string name="received_file_fail_title">Misslyckades ta emot fil från %1s</string>
<string name="received_file_text">Rör för att öppna \'%1s\'</string>
@@ -106,6 +109,7 @@
<string name="remote_control">Fjärrkontroll</string>
<string name="settings">KDE anslutningsinställningar</string>
<string name="mpris_play">Spela</string>
<string name="mpris_pause">Paus</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>
@@ -121,6 +125,8 @@
<item>1 minut</item>
<item>2 minuter</item>
</string-array>
<string name="mpris_notification_settings_title">Visa underrättelser om mediastyrning</string>
<string name="mpris_notification_settings_summary">Tillåter att styra mediaspelare utan att KDE-anslut öppnas.</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>
@@ -141,6 +147,8 @@
<string name="share_destination_customize_summary_disabled">Mottagna filer hamnar i Nerladdningar</string>
<string name="share_destination_customize_summary_enabled">Filer lagras i katalogen nedan</string>
<string name="share_destination_folder_preference">Målkatalog</string>
<string name="share">Dela</string>
<string name="share_received_file">Dela \"%s\"</string>
<string name="title_activity_notification_filter">Underrättelsefilter</string>
<string name="filter_apps_info">Underrättelser synkroniseras för markerade applikationer.</string>
<string name="sftp_internal_storage">Intern lagring</string>
@@ -169,6 +177,7 @@
<string name="plugin_not_supported">Insticksprogrammet stöds inte av apparaten</string>
<string name="findmyphone_title">Hitta min telefon</string>
<string name="findmyphone_title_tablet">Hitta min surfplatta</string>
<string name="findmyphone_title_tv">Hitta min tv</string>
<string name="findmyphone_description">Ringer till apparaten så att du kan hitta den</string>
<string name="findmyphone_found">Hittade den</string>
<string name="open">Öppna</string>
@@ -183,4 +192,17 @@
<string name="telepathy_permission_explanation">För att läsa och skriva SMS från skrivbordet måste du ge rättigheter för SMS</string>
<string name="telephony_permission_explanation">För att se telefonsamtal och SMS från skrivbordet måste du ge rättigheter för telefonsamtal och SMS</string>
<string name="telephony_optional_permission_explanation">För att se ett kontaktnamn istället för ett telefonnummer måste du ge tillgång till telefonens kontakter</string>
<string name="select_ringtone">Välj en ringsignal</string>
<string name="telephony_pref_blocked_title">Blockerade nummer</string>
<string name="telephony_pref_blocked_dialog_desc">Visa inte samtal och SMS från dessa nummer. Ange ett nummer per rad.</string>
<string name="mpris_coverart_description">Omslag för aktuell media</string>
<string name="device_icon_description">Enhetsikon</string>
<string name="settings_icon_description">Inställningsikon</string>
<string name="add_command">Lägg till ett kommando</string>
<string name="addcommand_explanation">Det finns inga kommandon registrerade</string>
<string name="addcommand_explanation2">Du kan lägga till nya kommandon i KDE-ansluts systeminställningar</string>
<string name="add_command_description">Du kan lägga till kommandon på skrivbordet</string>
<string name="pref_plugin_mprisreceiver">Styrning av mediaspelare</string>
<string name="pref_plugin_mprisreceiver_desc">Styr telefonens mediaspelare från en annan enhet</string>
<string name="dark_theme">Mörkt tema</string>
</resources>

View File

@@ -37,7 +37,6 @@
<string name="remotekeyboard_connected">Uzak klavye bağlantısı etkin</string>
<string name="remotekeyboard_multiple_connections">Birden çok uzak klavye bağlantısı mevcut, yapılandırmak istediğiniz aygıtı seçin</string>
<string name="open_mousepad">Girdi sil</string>
<string name="mousepad_info">Fare imlecini hareket ettirmek için ekran üzerinde parmaklarınızı hareket ettirin. Tek tıklama için dokunun, sağ ve orta düğmeler için iki/üç parmak kullanın. Sürüklemek için uzun basın.</string>
<string name="mousepad_double_tap_settings_title">İki parmak dokunma eylemini ayarla</string>
<string name="mousepad_triple_tap_settings_title">Üç parmak dokunma eylemini ayarla</string>
<string name="mousepad_sensitivity_settings_title">Dokunmatik yüzey hassasiyetini ayarla</string>
@@ -83,8 +82,6 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Dosya şuraya gönderiliyor, %1s</string>
<string name="outgoing_files_title">Dosyalar şuraya gönderiliyor, %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">%2$d dosyadan %1$d dosya gönderildi</string>
<string name="received_file_title">Şuradan dosya alındı, %1s</string>
<string name="received_file_fail_title">Şuradan dosya alma başarısız, %1s</string>
<string name="received_file_text">\'%1s\' açmak için dokunun</string>

View File

@@ -30,6 +30,7 @@
<string name="cancel">Скасувати</string>
<string name="open_settings">Відкрити вікно параметрів</string>
<string name="no_permissions">Вам слід надати доступ до сповіщень</string>
<string name="no_permission_mprisreceiver">Щоб мати змогу керувати вашими програвачами мультимедійних даних, вам слід надати доступ до сповіщень.</string>
<string name="send_ping">Надіслати сигнал підтримання зв’язку</string>
<string name="open_mpris_controls">Керування відтворенням</string>
<string name="remotekeyboard_editing_only_title">Обробляти віддалені клавіші лише під час редагування</string>
@@ -37,7 +38,7 @@
<string name="remotekeyboard_connected">З’єднання з віддаленою клавіатурою є активним</string>
<string name="remotekeyboard_multiple_connections">Існує декілька з’єднань із віддаленою клавіатурою. Виберіть пристрій для налаштовування.</string>
<string name="open_mousepad">Дистанційне введення</string>
<string name="mousepad_info">Проведіть по екрану пальцем, щоб пересунути вказівник миші. Дотик одним пальцем означатиме клацання, дотиком двома або трьома пальцями можна імітувати праву і середню кнопки. Для перетягування зі скиданням скористайтеся тривалим натисканням.</string>
<string name="mousepad_info">Проведіть по екрану пальцем, щоб пересунути вказівник миші. Дотик одним пальцем означатиме клацання, дотиком двома або трьома пальцями можна імітувати праву і середню кнопки. Гортання відбувається за допомогою двох пальців. Для перетягування зі скиданням скористайтеся тривалим натисканням.</string>
<string name="mousepad_double_tap_settings_title">Встановлення дії для торкання двома пальцями</string>
<string name="mousepad_triple_tap_settings_title">Встановлення дії для торкання трьома пальцями</string>
<string name="mousepad_sensitivity_settings_title">Встановити чутливість сенсорної панелі</string>
@@ -83,8 +84,12 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Надсилаємо файл до %1s</string>
<string name="outgoing_files_title">Надсилаємо файли на %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Надіслано %1$d з %2$d файлів</string>
<plurals name="outgoing_files_text">
<item quantity="one">Надіслано %1$d з %2$d файла</item>
<item quantity="few">Надіслано %1$d з %2$d файлів</item>
<item quantity="many">Надіслано %1$d з %2$d файлів</item>
<item quantity="other">Надіслано %1$d файл</item>
</plurals>
<string name="received_file_title">Отримано файл з %1s</string>
<string name="received_file_fail_title">Не вдалося отримати файл з %1s</string>
<string name="received_file_text">Натисніть, щоб відкрити «%1s»</string>
@@ -106,6 +111,7 @@
<string name="remote_control">Дистанційне керування</string>
<string name="settings">Параметри з’єднання з KDE</string>
<string name="mpris_play">Пуск</string>
<string name="mpris_pause">Пауза</string>
<string name="mpris_previous">Назад</string>
<string name="mpris_rew">Повний назад</string>
<string name="mpris_ff">Повний вперед</string>
@@ -121,6 +127,8 @@
<item>1 хвилина</item>
<item>2 хвилини</item>
</string-array>
<string name="mpris_notification_settings_title">Показувати сповіщення щодо керування відтворенням</string>
<string name="mpris_notification_settings_summary">Уможливлює керування відтворенням мультимедійних даних без відкриття KDE Connect.</string>
<string name="share_to">Спільно використовувати з…</string>
<string name="protocol_version_older">На цьому пристрої використовується стара версія протоколу</string>
<string name="protocol_version_newer">На цьому пристрої використовується новіша версія протоколу</string>
@@ -141,6 +149,8 @@
<string name="share_destination_customize_summary_disabled">Отримані файли зберігатимуться до каталогу «Завантаження»</string>
<string name="share_destination_customize_summary_enabled">Файли зберігатимуться у вказаному нижче каталозі</string>
<string name="share_destination_folder_preference">Каталог призначення</string>
<string name="share">Оприлюднити</string>
<string name="share_received_file">Оприлюднити «%s»</string>
<string name="title_activity_notification_filter">Фільтр сповіщень</string>
<string name="filter_apps_info">Сповіщення буде синхронізовано для позначених програм.</string>
<string name="sftp_internal_storage">Вбудоване сховище даних</string>
@@ -169,6 +179,7 @@
<string name="plugin_not_supported">Підтримки цього додатка не передбачено на пристрої</string>
<string name="findmyphone_title">Знайти телефон</string>
<string name="findmyphone_title_tablet">Знайти планшет</string>
<string name="findmyphone_title_tv">Знайти мій телевізор</string>
<string name="findmyphone_description">Відтворити дзвінок, щоб цей пристрій було простіше знайти</string>
<string name="findmyphone_found">Знайдено</string>
<string name="open">Відкрити</string>
@@ -183,4 +194,17 @@
<string name="telepathy_permission_explanation">Щоб читати і писати SMS з вашого робочого комп’ютера, вам слід надати програмі доступ до SMS</string>
<string name="telephony_permission_explanation">"Щоб переглядати дзвінки і SMS з робочого комп’ютера, вам слід надати програмі доступ до дзвінків і SMS"</string>
<string name="telephony_optional_permission_explanation">Щоб бачити ім’я контакту замість номеру телефону, вам слід надати програмі доступ до записів контактів на телефоні</string>
<string name="select_ringtone">Виберіть мелодію дзвінка</string>
<string name="telephony_pref_blocked_title">Заблоковані номери</string>
<string name="telephony_pref_blocked_dialog_desc">Не показувати виклики та SMS з цих номерів. Будь ласка, вказуйте кожен із номерів у окремому рядку.</string>
<string name="mpris_coverart_description">Зображення обкладинки відтворюваних даних</string>
<string name="device_icon_description">Піктограма пристрою</string>
<string name="settings_icon_description">Піктограма параметрів</string>
<string name="add_command">Додати команду</string>
<string name="addcommand_explanation">Жодних команд не зареєстровано</string>
<string name="addcommand_explanation2">Ви можете додавати нові команди за допомогою Системних параметрів KDE Connect</string>
<string name="add_command_description">Ви можете додавати команди на комп\'ютері</string>
<string name="pref_plugin_mprisreceiver">Керування відтворенням</string>
<string name="pref_plugin_mprisreceiver_desc">Керування вашими програвачами на телефоні з іншого пристрою</string>
<string name="dark_theme">Темна тема</string>
</resources>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="KdeConnectTheme.Dark" parent="KdeConnectThemeBase.Dark">
<item name="android:colorEdgeEffect">@color/darkGrey</item>
</style>
<style name="KdeConnectTheme.Dark.NoActionBar" parent="KdeConnectThemeBase.Dark.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
<item name="android:colorEdgeEffect">@color/darkGrey</item>
</style>
</resources>

View File

@@ -37,7 +37,7 @@
<string name="remotekeyboard_connected">远程键盘连接已启用</string>
<string name="remotekeyboard_multiple_connections">发现多个远程键盘连接,请选择设备进行配置</string>
<string name="open_mousepad">远程输入</string>
<string name="mousepad_info">在屏幕上移动手指来移动光标。轻击代表左键,双指或三指点击代表右键或中键。用长按来拖放。</string>
<string name="mousepad_info">在屏幕上移动手指来移动光标。轻击代表左键,双指或三指点击代表右键或中键。用双指滚动。用长按来拖放。</string>
<string name="mousepad_double_tap_settings_title">设置双指点击动作</string>
<string name="mousepad_triple_tap_settings_title">设置三指点击动作</string>
<string name="mousepad_sensitivity_settings_title">设置触摸板灵敏度</string>
@@ -83,8 +83,9 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">正在向%1s发送文件</string>
<string name="outgoing_files_title">正在向 %1s 发送文件</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">已发送 %2$d 个文件中的 %1$d 个</string>
<plurals name="outgoing_files_text">
<item quantity="other">已发送 %2$d 个文件中的 %1$d 个</item>
</plurals>
<string name="received_file_title">已从%1s接收文件</string>
<string name="received_file_fail_title">未能从%1s接收文件</string>
<string name="received_file_text">点击以打开“%1s”</string>
@@ -106,6 +107,7 @@
<string name="remote_control">远程控制</string>
<string name="settings">KDE Connect设置</string>
<string name="mpris_play">播放</string>
<string name="mpris_pause">暂停</string>
<string name="mpris_previous">前一个</string>
<string name="mpris_rew">后退</string>
<string name="mpris_ff">快进</string>
@@ -141,6 +143,7 @@
<string name="share_destination_customize_summary_disabled">接收的文件会出现在“Downloads”中</string>
<string name="share_destination_customize_summary_enabled">文件将会被存储在以下目录中</string>
<string name="share_destination_folder_preference">目标目录</string>
<string name="share">分享</string>
<string name="title_activity_notification_filter">通知过滤器</string>
<string name="filter_apps_info">所选软件的通知将会被同步。</string>
<string name="sftp_internal_storage">内部存储</string>

View File

@@ -10,6 +10,8 @@
<string name="pref_plugin_clipboard_desc">分享剪貼板的內容</string>
<string name="pref_plugin_mousepad">遠端輸入</string>
<string name="pref_plugin_mousepad_desc">使用您的智慧型手機或者平板來模擬觸碰板與鍵盤</string>
<string name="pref_plugin_remotekeyboard">接收遠端按鍵輸入</string>
<string name="pref_plugin_remotekeyboard_desc">從遠端裝置接收按鍵輸入活動</string>
<string name="pref_plugin_mpris">多媒體控制</string>
<string name="pref_plugin_mpris_desc">成為您多媒體播放器的遙控器</string>
<string name="pref_plugin_runcommand">執行指令</string>
@@ -30,8 +32,12 @@
<string name="no_permissions">您需要授予存取通知的權限</string>
<string name="send_ping">傳送Ping回應封包</string>
<string name="open_mpris_controls">多媒體控制</string>
<string name="remotekeyboard_editing_only_title">當編輯時只處理遠端按鍵</string>
<string name="remotekeyboard_not_connected">這裡沒有建立在 kdeconnect 之上的使用中遠端鍵盤連線。</string>
<string name="remotekeyboard_connected">遠端鍵盤連線為啟用狀態</string>
<string name="remotekeyboard_multiple_connections">這裡有兩個以上的遠端鍵盤連結,選擇一個裝置以設定。</string>
<string name="open_mousepad">遠端輸入</string>
<string name="mousepad_info">在您的智慧型手機的螢幕上移動手指頭,用來控制電腦螢幕的鼠標。點擊表示滑鼠的左鍵,使用兩隻/三隻手指頭點擊來表示滑鼠的右鍵/中鍵。長按則表示要拖拉。</string>
<string name="mousepad_info">在您的智慧型手機的螢幕上移動手指頭,用來控制電腦螢幕的鼠標。點擊表示滑鼠的左鍵,使用兩隻/三隻手指頭點擊來表示滑鼠的右鍵/中鍵。使用兩隻手指頭捲動。長按則表示要拖拉。</string>
<string name="mousepad_double_tap_settings_title">設定兩隻手指頭點擊的動作</string>
<string name="mousepad_triple_tap_settings_title">設定三隻手指頭點擊的動作</string>
<string name="mousepad_sensitivity_settings_title">設定觸碰板的靈敏度</string>
@@ -76,12 +82,16 @@
<string name="incoming_file_title">從 %1s 傳來的檔案</string>
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">正在將檔案發送到 %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_title">正在將檔案發送到 %1s</string>
<plurals name="outgoing_files_text">
<item quantity="other">傳送 %1$d 個檔案,共 %2$d 個檔案。</item>
</plurals>
<string name="received_file_title">已從 %1s 接收檔案</string>
<string name="received_file_fail_title">從 %1s 接收檔案失敗</string>
<string name="received_file_text">點擊開啟 \'%1s\'</string>
<string name="sent_file_title">將檔案傳送到 %1s</string>
<string name="sent_file_text">%1s</string>
<string name="sent_file_failed_title">傳送到 %1s 的檔案失敗</string>
<string name="sent_file_failed_text">%1s</string>
<string name="tap_to_answer">點擊即可應答</string>
<string name="reconnect">重新連線</string>
@@ -97,6 +107,7 @@
<string name="remote_control">遠端控制</string>
<string name="settings">KDE連線設定</string>
<string name="mpris_play">播放</string>
<string name="mpris_pause">暫停</string>
<string name="mpris_previous">往前</string>
<string name="mpris_rew">往後</string>
<string name="mpris_ff">快轉</string>
@@ -112,6 +123,8 @@
<item>1分鐘</item>
<item>2分鐘</item>
</string-array>
<string name="mpris_notification_settings_title">顯示媒體控制項通知</string>
<string name="mpris_notification_settings_summary">允許控制您的媒體播放器而不需要開啟 KDE 連線。</string>
<string name="share_to">分享給</string>
<string name="protocol_version_older">這個裝置使用舊版本的通訊協定</string>
<string name="protocol_version_newer">此設備使用較新的通訊協定</string>
@@ -128,6 +141,12 @@
<string name="custom_device_list">以IP來新增設備</string>
<string name="share_notification_preference">通知方式</string>
<string name="share_notification_preference_summary">當接收檔案時發出振動以及播放聲音</string>
<string name="share_destination_customize">自訂目標路徑</string>
<string name="share_destination_customize_summary_disabled">接收到的檔案將會在 Downloads 上顯示。</string>
<string name="share_destination_customize_summary_enabled">檔案將會儲存在下方所示的資料夾</string>
<string name="share_destination_folder_preference">目標路徑</string>
<string name="share">分享</string>
<string name="share_received_file">分享「%s」</string>
<string name="title_activity_notification_filter">通知過濾器</string>
<string name="filter_apps_info">將會以您選擇的App應用程式啟用同步通知</string>
<string name="sftp_internal_storage">內部儲存空間</string>
@@ -149,6 +168,7 @@
<string name="device_rename_confirm">更改名稱</string>
<string name="refresh">刷新</string>
<string name="unreachable_description">此配對的裝置無法連接。 請確保它連接到與您相同的網域。</string>
<string name="on_data_message">看起來你現在正使用行動數據連線。KDE 連線只在區域網路上運作。</string>
<string name="no_file_browser">沒有安裝此檔案的瀏覽程式</string>
<string name="pref_plugin_telepathy">傳送簡訊</string>
<string name="pref_plugin_telepathy_desc">傳送文字簡訊到您的電腦桌面</string>
@@ -159,4 +179,24 @@
<string name="findmyphone_found">找到</string>
<string name="open">開啟</string>
<string name="close">關閉</string>
<string name="no_permissions_storage">您需要授予儲存權限</string>
<string name="plugins_need_permission">部份的附加元件需要權限才能運作(點擊以取得更多資訊)</string>
<string name="permission_explanation">這附加元件需要權限以運作</string>
<string name="optional_permission_explanation">你需要授予延伸的權限以啟用所有的功能</string>
<string name="plugins_need_optional_permission">部份的附加元件因為缺乏權限,而導致功能被停用。(點擊以了解更多資訊):</string>
<string name="sftp_permission_explanation">為了要從您的個人電腦存取檔案,這個應用程式需要權限以存取您的手機儲存空間。</string>
<string name="share_optional_permission_explanation">為了要在您的手機與電腦之間分享檔案,你需要同意存取手機的儲存空間。</string>
<string name="telepathy_permission_explanation">為了要在您的個人電腦上讀取與撰寫簡訊,你需要提供簡訊的權限。</string>
<string name="telephony_permission_explanation">為了要在您的電腦上檢視手機通話與簡訊,你需要提供手機通話與簡訊的權限。</string>
<string name="telephony_optional_permission_explanation">為了要讓聯絡人名稱取代手機號碼,您需要提供手機通訊錄的權限。</string>
<string name="select_ringtone">選擇一個鈴聲</string>
<string name="telephony_pref_blocked_title">已封鎖號碼</string>
<string name="telephony_pref_blocked_dialog_desc">不顯示這些號碼的來電與簡訊。請在一行指定一個電話號碼。</string>
<string name="mpris_coverart_description">目前媒體的專輯圖像</string>
<string name="device_icon_description">裝置圖示</string>
<string name="settings_icon_description">設定圖示</string>
<string name="add_command">增加一行指令</string>
<string name="addcommand_explanation">沒有指令被註冊</string>
<string name="addcommand_explanation2">您現在可以在 KDE 連線系統設定增加新的指令</string>
<string name="dark_theme">暗色主題</string>
</resources>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MaxWidthImageButton">
<attr name="maxWidth" format="dimension" />
</declare-styleable>
<!-- The style to use on the MainActivity's NavigationView -->
<attr name="mainNavigationViewStyle" format="reference" />
<!-- A high-contrast color for important visual elements (for less important elements, use colorControlNormal instead) -->
<attr name="colorHighContrast" format="color" />
</resources>

View File

@@ -31,6 +31,7 @@
<string name="cancel">Cancel</string>
<string name="open_settings">Open settings</string>
<string name="no_permissions">You need to grant permission to access notifications</string>
<string name="no_permission_mprisreceiver">To be able to control your media players you need to grant access to the notifications</string>
<string name="send_ping">Send ping</string>
<string name="open_mpris_controls">Multimedia control</string>
<string name="remotekeyboard_editing_only" translatable="false">remotekeyboard_editing_only</string>
@@ -39,7 +40,7 @@
<string name="remotekeyboard_connected" translatable="true">Remote keyboard connection is active</string>
<string name="remotekeyboard_multiple_connections" translatable="true">There is more than one remote keyboard connection, select the device to configure</string>
<string name="open_mousepad">Remote input</string>
<string name="mousepad_info">Move a finger on the screen to move the mouse cursor. Tap for a click, and use two/three fingers for right and middle buttons. Use a long press to drag\'n drop.</string>
<string name="mousepad_info">Move a finger on the screen to move the mouse cursor. Tap for a click, and use two/three fingers for right and middle buttons. Use 2 fingers to scroll. Use a long press to drag\'n drop.</string>
<string name="mousepad_double_tap_settings_title">Set two finger tap action</string>
<string name="mousepad_triple_tap_settings_title">Set three finger tap action</string>
<string name="mousepad_sensitivity_settings_title">Set touchpad sensitivity</string>
@@ -104,8 +105,10 @@
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Sending file to %1s</string>
<string name="outgoing_files_title">Sending files to %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Sent %1$d out of %2$d files</string>
<plurals name="outgoing_files_text">
<item quantity="one">Sent %1$d file</item>
<item quantity="other">Sent %1$d out of %2$d files</item>
</plurals>
<string name="received_file_title">Received file from %1s</string>
<string name="received_file_fail_title">Failed receiving file from %1s</string>
<string name="received_file_text">Tap to open \'%1s\'</string>
@@ -127,6 +130,7 @@
<string name="remote_control">Remote control</string>
<string name="settings">KDE Connect Settings</string>
<string name="mpris_play">Play</string>
<string name="mpris_pause">Pause</string>
<string name="mpris_previous">Previous</string>
<string name="mpris_rew">Rewind</string>
<string name="mpris_ff">Fast-forward</string>
@@ -151,6 +155,9 @@
<item>60000000</item>
<item>120000000</item>
</string-array>
<string name="mpris_notification_settings_title">Show media control notification</string>
<string name="mpris_notification_settings_summary">Allows controlling your media players without opening KDE Connect.</string>
<string name="mpris_notification_key" translatable="false">mpris_notification_enabled</string>
<string name="share_to">Share To...</string>
<string name="protocol_version_older">This device uses an old protocol version</string>
<string name="protocol_version_newer">This device uses a newer protocol version</string>
@@ -171,6 +178,8 @@
<string name="share_destination_customize_summary_disabled">Received files will appear in Downloads</string>
<string name="share_destination_customize_summary_enabled">Files will be stored in the directory below</string>
<string name="share_destination_folder_preference">Destination directory</string>
<string name="share">Share</string>
<string name="share_received_file">Share \"%s\"</string>
<string name="title_activity_notification_filter">Notification filter</string>
<string name="filter_apps_info">Notifications will be synchronized for the selected apps.</string>
<string name="sftp_internal_storage">Internal storage</string>
@@ -200,6 +209,7 @@
<string name="plugin_not_supported">This plugin is not supported by the device</string>
<string name="findmyphone_title">Find my phone</string>
<string name="findmyphone_title_tablet">Find my tablet</string>
<string name="findmyphone_title_tv">Find my TV</string>
<string name="findmyphone_description">Rings this device so you can find it</string>
<string name="findmyphone_found">Found</string>
@@ -216,5 +226,20 @@
<string name="telepathy_permission_explanation">To read and write SMS from your desktop you need to give permission to SMS</string>
<string name="telephony_permission_explanation">To see phone calls and SMS from the desktop you need to give permission to phone calls and SMS</string>
<string name="telephony_optional_permission_explanation">To see a contact name instead of a phone number you need to give access to the phone\'s contacts</string>
<string name="select_ringtone">Select a ringtone</string>
<string name="telephony_pref_blocked_title">Blocked numbers</string>
<string name="telephony_pref_blocked_dialog_desc">Don\'t show calls and SMS from these numbers. Please specify one number per line</string>
<string name="mpris_coverart_description">Cover art of current media</string>
<string name="device_icon_description">Device icon</string>
<string name="settings_icon_description">Settings icon</string>
<string name="add_command">Add a command</string>
<string name="addcommand_explanation">There are no commands registered</string>
<string name="addcommand_explanation2">You can add new commands in the KDE Connect System Settings</string>
<string name="add_command_description">You can add commands on the desktop</string>
<string name="pref_plugin_mprisreceiver">Media Player Control</string>
<string name="pref_plugin_mprisreceiver_desc">Control your phones media players from another device</string>
<string name="dark_theme">Dark theme</string>
</resources>

View File

@@ -0,0 +1,40 @@
<resources>
<color name="darkGrey">#555555</color>
<color name="darkToolbarBackground">#222222</color>
<color name="darkStatusBarBackground">#333333</color>
<!-- KdeConnectThemeBase styles must only be defined in the main res/values/ folder -->
<style name="KdeConnectThemeBase.Dark" parent="Theme.AppCompat">
<item name="colorPrimary">@color/darkGrey</item>
<item name="colorPrimaryDark">@color/darkStatusBarBackground</item>
<item name="colorAccent">@color/accent</item>
<item name="android:windowBackground">@android:color/black</item>
<item name="toolbarStyle">@style/KdeConnectTheme.Toolbar.Dark</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat</item>
<item name="mainNavigationViewStyle">@style/MainNavigationView.Dark</item>
<item name="colorHighContrast">@android:color/white</item>
<item name="android:textColorPrimary">@android:color/white</item>
<item name="android:textColor">@android:color/white</item>
</style>
<style name="KdeConnectThemeBase.Dark.NoActionBar" parent="KdeConnectThemeBase.Dark">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<!-- KdeConnectTheme styles (without the 'Base' on the end) can be redefined in other 'values' folders. like res/values-v21/ -->
<style name="KdeConnectTheme.Toolbar.Dark">
<item name="android:background">@color/darkToolbarBackground</item>
</style>
<style name="KdeConnectTheme.Dark" parent="KdeConnectThemeBase.Dark" />
<style name="KdeConnectTheme.Dark.NoActionBar" parent="KdeConnectThemeBase.Dark.NoActionBar" />
<style name="MainNavigationView.Dark">
<item name="android:background">@drawable/state_list_drawer_background_dark</item>
<item name="itemBackground">@drawable/state_list_drawer_background_dark</item>
<item name="itemIconTint">@android:color/white</item>
<item name="itemTextColor">@android:color/white</item>
</style>
</resources>

View File

@@ -2,6 +2,7 @@
<color name="primary">#F67400</color>
<color name="primaryDark">#BD5900</color>
<color name="accent">#4ebffa</color>
<color name="disabled_grey">#eee</color>
<!-- NoActionBar because we use a Toolbar widget as ActionBar -->
<style name="KdeConnectThemeBase" parent="Theme.AppCompat.Light.DarkActionBar">
@@ -9,6 +10,10 @@
<item name="colorPrimary">@color/primary</item>
<item name="colorPrimaryDark">@color/primaryDark</item>
<item name="colorAccent">@color/accent</item>
<item name="toolbarStyle">@style/KdeConnectTheme.Toolbar</item>
<item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="mainNavigationViewStyle">@style/MainNavigationView</item>
<item name="colorHighContrast">@android:color/black</item>
<item name="android:textColorPrimary">@android:color/black</item>
<item name="android:textColor">@android:color/black</item>
</style>
@@ -18,10 +23,22 @@
<item name="windowNoTitle">true</item>
</style>
<style name="KdeConnectTheme" parent="KdeConnectThemeBase">
<style name="KdeConnectTheme" parent="KdeConnectThemeBase" />
<style name="KdeConnectTheme.Toolbar" parent="Widget.AppCompat.Toolbar">
<item name="android:background">?attr/colorPrimary</item>
</style>
<style name="KdeConnectTheme.NoActionBar" parent="KdeConnectThemeBase.NoActionBar" />
<style name="MainNavigationView">
<item name="android:background">@drawable/state_list_drawer_background</item>
<item name="itemBackground">@drawable/state_list_drawer_background</item>
<item name="itemIconTint">@color/state_list_drawer_text</item>
<item name="itemTextColor">@color/state_list_drawer_text</item>
</style>
<style name="KdeConnectTheme.NoActionBar" parent="KdeConnectThemeBase.NoActionBar">
<style name="DisableableButton" parent="ThemeOverlay.AppCompat">
<item name="colorButtonNormal">@drawable/disableable_button</item>
</style>
</resources>

View File

@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
<external-path
name="external_files"
path="." />
</paths>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RingtonePreference
android:key="select_ringtone"
android:showSilent="false"
android:title="@string/select_ringtone" />
</PreferenceScreen>

View File

@@ -10,7 +10,7 @@
android:entryValues="@array/mousepad_tap_values"
android:key="@string/mousepad_double_tap_key"
android:summary="%s"
android:title="@string/mousepad_double_tap_settings_title"/>
android:title="@string/mousepad_double_tap_settings_title" />
<ListPreference
android:id="@+id/mousepad_triple_tap_preference"
@@ -19,7 +19,7 @@
android:entryValues="@array/mousepad_tap_values"
android:key="@string/mousepad_triple_tap_key"
android:summary="%s"
android:title="@string/mousepad_triple_tap_settings_title"/>
android:title="@string/mousepad_triple_tap_settings_title" />
<ListPreference
android:id="@+id/mousepad_sensitivity_preference"
@@ -28,11 +28,11 @@
android:entryValues="@array/mousepad_sensitivity_values"
android:key="@string/mousepad_sensitivity_key"
android:summary="%s"
android:title="@string/mousepad_sensitivity_settings_title"/>
android:title="@string/mousepad_sensitivity_settings_title" />
<CheckBoxPreference
android:id="@+id/mousepad_scroll_preference"
android:defaultValue="false"
android:key="@string/mousepad_scroll_direction"
android:title="@string/mousepad_scroll_direction_title"
android:defaultValue="false" />
android:title="@string/mousepad_scroll_direction_title" />
</PreferenceScreen>

View File

@@ -5,11 +5,18 @@
<ListPreference
android:id="@+id/mpris_time_preference"
android:key="@string/mpris_time_key"
android:title="@string/mpris_time_settings_title"
android:summary="@string/mpris_time_settings_summary"
android:defaultValue="@string/mpris_time_default"
android:entries="@array/mpris_time_entries"
android:entryValues="@array/mpris_time_entries_values"
android:defaultValue="@string/mpris_time_default" />
android:key="@string/mpris_time_key"
android:summary="@string/mpris_time_settings_summary"
android:title="@string/mpris_time_settings_title" />
</PreferenceScreen>
<CheckBoxPreference
android:id="@+id/mpris_notification_preference"
android:defaultValue="true"
android:key="@string/mpris_notification_key"
android:summary="@string/mpris_notification_settings_summary"
android:title="@string/mpris_notification_settings_title" />
</PreferenceScreen>

View File

@@ -1,14 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Keyboard
xmlns:android="http://schemas.android.com/apk/res/android"
android:keyHeight="@dimen/key_height"
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:horizontalGap="0px"
android:verticalGap="0px" >
android:keyHeight="@dimen/key_height"
android:verticalGap="0px">
<Row android:rowEdgeFlags="bottom">
<Key android:keyIcon="@drawable/ic_keyboard_hide_white_36dp" android:codes="0" android:keyWidth="20%" />
<Key android:keyIcon="@drawable/ic_action_settings" android:codes="1" android:keyWidth="40%"/>
<Key android:keyIcon="@drawable/ic_action_keyboard" android:codes="2" android:keyWidth="40%"/>
<Key android:keyIcon="@drawable/ic_phonelink_white_36dp" android:codes="3" android:keyWidth="20%" />-->
</Row>
<Key
android:codes="0"
android:keyIcon="@drawable/ic_keyboard_hide_white_36dp"
android:keyWidth="20%" />
<Key
android:codes="1"
android:keyIcon="@drawable/ic_action_settings"
android:keyWidth="40%" />
<Key
android:codes="2"
android:keyIcon="@drawable/ic_action_keyboard"
android:keyWidth="40%" />
<Key
android:codes="3"
android:keyIcon="@drawable/ic_phonelink_white_36dp"
android:keyWidth="20%" />-->
</Row>
</Keyboard>

View File

@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
android:supportsSwitchingToNextInputMethod="true">
</input-method>
android:supportsSwitchingToNextInputMethod="true" />

View File

@@ -5,7 +5,7 @@
<CheckBoxPreference
android:id="@+id/remotekeyboard_editing_only"
android:defaultValue="true"
android:key="@string/remotekeyboard_editing_only"
android:title="@string/remotekeyboard_editing_only_title"
android:defaultValue="true" />
android:title="@string/remotekeyboard_editing_only_title" />
</PreferenceScreen>

View File

@@ -5,11 +5,11 @@
<CheckBoxPreference
android:id="@+id/share_destination_customize"
android:defaultValue="false"
android:key="share_destination_custom"
android:title="@string/share_destination_customize"
android:summaryOff="@string/share_destination_customize_summary_disabled"
android:summaryOn="@string/share_destination_customize_summary_enabled"
android:defaultValue="false" />
android:title="@string/share_destination_customize" />
<Preference
android:id="@+id/share_destination_folder_preference"
@@ -18,9 +18,9 @@
<CheckBoxPreference
android:id="@+id/share_notification_preference"
android:defaultValue="true"
android:key="share_notification_preference"
android:title="@string/share_notification_preference"
android:summary="@string/share_notification_preference_summary"
android:defaultValue="true" />
android:title="@string/share_notification_preference" />
</PreferenceScreen>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference
android:dialogMessage="@string/telephony_pref_blocked_dialog_desc"
android:key="telephony_blocked_numbers"
android:title="@string/telephony_pref_blocked_title" />
</PreferenceScreen>

View File

@@ -23,7 +23,7 @@ package org.kde.kdeconnect.Backends;
import android.content.Context;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
import java.security.PrivateKey;
import java.security.PublicKey;
@@ -34,13 +34,13 @@ public abstract class BaseLink {
protected final Context context;
public interface PackageReceiver {
void onPackageReceived(NetworkPackage np);
public interface PacketReceiver {
void onPacketReceived(NetworkPacket np);
}
private final BaseLinkProvider linkProvider;
private final String deviceId;
private final ArrayList<PackageReceiver> receivers = new ArrayList<>();
private final ArrayList<PacketReceiver> receivers = new ArrayList<>();
protected PrivateKey privateKey;
protected BaseLink(Context context, String deviceId, BaseLinkProvider linkProvider) {
@@ -70,17 +70,17 @@ public abstract class BaseLink {
return false;
}
public void addPackageReceiver(PackageReceiver pr) {
public void addPacketReceiver(PacketReceiver pr) {
receivers.add(pr);
}
public void removePackageReceiver(PackageReceiver pr) {
public void removePacketReceiver(PacketReceiver pr) {
receivers.remove(pr);
}
//Should be called from a background thread listening to packages
protected void packageReceived(NetworkPackage np) {
for(PackageReceiver pr : receivers) {
pr.onPackageReceived(np);
protected void packageReceived(NetworkPacket np) {
for(PacketReceiver pr : receivers) {
pr.onPacketReceived(np);
}
}
@@ -89,7 +89,7 @@ public abstract class BaseLink {
}
//TO OVERRIDE, should be sync
public abstract boolean sendPackage(NetworkPackage np,Device.SendPackageStatusCallback callback);
public abstract boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback);
@Deprecated
public abstract boolean sendPackageEncrypted(NetworkPackage np,Device.SendPackageStatusCallback callback, PublicKey key);
public abstract boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key);
}

View File

@@ -20,7 +20,7 @@
package org.kde.kdeconnect.Backends;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
import java.util.concurrent.CopyOnWriteArrayList;
@@ -29,7 +29,7 @@ public abstract class BaseLinkProvider {
private final CopyOnWriteArrayList<ConnectionReceiver> connectionReceivers = new CopyOnWriteArrayList<>();
public interface ConnectionReceiver {
void onConnectionReceived(NetworkPackage identityPackage, BaseLink link);
void onConnectionReceived(NetworkPacket identityPacket, BaseLink link);
void onConnectionLost(BaseLink link);
}
@@ -42,10 +42,10 @@ public abstract class BaseLinkProvider {
}
//These two should be called when the provider links to a new computer
protected void connectionAccepted(NetworkPackage identityPackage, BaseLink link) {
protected void connectionAccepted(NetworkPacket identityPacket, BaseLink link) {
//Log.i("KDE/LinkProvider", "connectionAccepted");
for(ConnectionReceiver cr : connectionReceivers) {
cr.onConnectionReceived(identityPackage, link);
cr.onConnectionReceived(identityPacket, link);
}
}
protected void connectionLost(BaseLink link) {

View File

@@ -21,7 +21,7 @@
package org.kde.kdeconnect.Backends;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
/**
* This class separates the pairing interface for each type of link.
@@ -73,7 +73,7 @@ public abstract class BasePairingHandler {
}
/* To be implemented by respective pairing handler */
public abstract void packageReceived(NetworkPackage np) throws Exception;
public abstract void packageReceived(NetworkPacket np) throws Exception;
public abstract void requestPairing();
public abstract void acceptPairing();
public abstract void rejectPairing();

View File

@@ -34,9 +34,13 @@ import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BasePairingHandler;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
import java.io.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.nio.charset.Charset;
import java.security.PublicKey;
import java.util.UUID;
@@ -77,18 +81,18 @@ public class BluetoothLink extends BaseLink {
}
private void processMessage(String message) {
NetworkPackage np;
NetworkPacket np;
try {
np = NetworkPackage.unserialize(message);
np = NetworkPacket.unserialize(message);
} catch (JSONException e) {
Log.e("BluetoothLink/receiving", "Unable to parse message.", e);
return;
}
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_ENCRYPTED)) {
if (np.getType().equals(NetworkPacket.PACKET_TYPE_ENCRYPTED)) {
try {
np = RsaHelper.decrypt(np, privateKey);
} catch(Exception e) {
} catch (Exception e) {
Log.e("BluetoothLink/receiving", "Exception decrypting the package", e);
}
}
@@ -102,7 +106,10 @@ public class BluetoothLink extends BaseLink {
np.setPayload(transferSocket.getInputStream(), np.getPayloadSize());
} catch (Exception e) {
if (transferSocket != null) {
try { transferSocket.close(); } catch(IOException ignored) { }
try {
transferSocket.close();
} catch (IOException ignored) {
}
}
Log.e("BluetoothLink/receiving", "Unable to get payload", e);
}
@@ -144,28 +151,28 @@ public class BluetoothLink extends BaseLink {
linkProvider.disconnectedLink(this, getDeviceId(), socket);
}
private void sendMessage(NetworkPackage np) throws JSONException, IOException {
private void sendMessage(NetworkPacket np) throws JSONException, IOException {
byte[] message = np.serialize().getBytes(Charset.forName("UTF-8"));
OutputStream socket = this.socket.getOutputStream();
Log.i("BluetoothLink","Beginning to send message");
Log.i("BluetoothLink", "Beginning to send message");
socket.write(message);
Log.i("BluetoothLink","Finished sending message");
Log.i("BluetoothLink", "Finished sending message");
}
@Override
public boolean sendPackage(NetworkPackage np, Device.SendPackageStatusCallback callback) {
return sendPackageInternal(np, callback, null);
public boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback) {
return sendPacketInternal(np, callback, null);
}
@Override
public boolean sendPackageEncrypted(NetworkPackage np, Device.SendPackageStatusCallback callback, PublicKey key) {
return sendPackageInternal(np, callback, key);
public boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key) {
return sendPacketInternal(np, callback, key);
}
private boolean sendPackageInternal(NetworkPackage np, final Device.SendPackageStatusCallback callback, PublicKey key) {
private boolean sendPacketInternal(NetworkPacket np, final Device.SendPacketStatusCallback callback, PublicKey key) {
/*if (!isConnected()) {
Log.e("BluetoothLink", "sendPackageEncrypted failed: not connected");
Log.e("BluetoothLink", "sendPacketEncrypted failed: not connected");
callback.sendFailure(new Exception("Not connected"));
return;
}*/
@@ -219,7 +226,10 @@ public class BluetoothLink extends BaseLink {
callback.onFailure(e);
return false;
} finally {
try { transferSocket.close(); } catch (IOException ignored) { }
try {
transferSocket.close();
} catch (IOException ignored) {
}
}
}

View File

@@ -23,8 +23,8 @@ package org.kde.kdeconnect.Backends.BluetoothBackend;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -35,13 +35,16 @@ import android.util.Log;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
import java.io.*;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.Set;
import java.util.UUID;
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class BluetoothLinkProvider extends BaseLinkProvider {
@@ -58,19 +61,19 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
private ServerRunnable serverRunnable;
private ClientRunnable clientRunnable;
private void addLink(NetworkPackage identityPackage, BluetoothLink link) {
String deviceId = identityPackage.getString("deviceId");
Log.i("BluetoothLinkProvider","addLink to "+deviceId);
private void addLink(NetworkPacket identityPacket, BluetoothLink link) {
String deviceId = identityPacket.getString("deviceId");
Log.i("BluetoothLinkProvider", "addLink to " + deviceId);
BluetoothLink oldLink = visibleComputers.get(deviceId);
if (oldLink == link) {
Log.e("BluetoothLinkProvider", "oldLink == link. This should not happen!");
return;
}
visibleComputers.put(deviceId, link);
connectionAccepted(identityPackage, link);
connectionAccepted(identityPacket, link);
link.startListening();
if (oldLink != null) {
Log.i("BluetoothLinkProvider","Removing old connection to same device");
Log.i("BluetoothLinkProvider", "Removing old connection to same device");
oldLink.disconnect();
}
}
@@ -80,7 +83,7 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Log.e("BluetoothLinkProvider","No bluetooth adapter found.");
Log.e("BluetoothLinkProvider", "No bluetooth adapter found.");
}
}
@@ -92,7 +95,7 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
Log.e("BluetoothLinkProvider","Bluetooth adapter not enabled.");
Log.e("BluetoothLinkProvider", "Bluetooth adapter not enabled.");
// TODO: next line needs to be called from an existing activity, so move it?
// startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
// TODO: Check result of the previous command, whether the user allowed bluetooth or not.
@@ -183,7 +186,7 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
Log.i("BTLinkProvider/Server", "Received connection from " + socket.getRemoteDevice().getAddress());
NetworkPackage np = NetworkPackage.createIdentityPackage(context);
NetworkPacket np = NetworkPacket.createIdentityPacket(context);
byte[] message = np.serialize().getBytes("UTF-8");
outputStream.write(message);
@@ -194,14 +197,14 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
Reader reader = new InputStreamReader(socket.getInputStream(), "UTF-8");
int charsRead;
char[] buf = new char[512];
while(sb.lastIndexOf("\n") == -1 && (charsRead = reader.read(buf)) != -1) {
while (sb.lastIndexOf("\n") == -1 && (charsRead = reader.read(buf)) != -1) {
sb.append(buf, 0, charsRead);
}
String response = sb.toString();
final NetworkPackage identityPackage = NetworkPackage.unserialize(response);
final NetworkPacket identityPacket = NetworkPacket.unserialize(response);
if (!identityPackage.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
if (!identityPacket.getType().equals(NetworkPacket.PACKET_TYPE_IDENTITY)) {
Log.e("BTLinkProvider/Server", "2 Expecting an identity package");
return;
}
@@ -209,9 +212,9 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
Log.i("BTLinkProvider/Server", "Received identity package");
BluetoothLink link = new BluetoothLink(context, socket,
identityPackage.getString("deviceId"), BluetoothLinkProvider.this);
identityPacket.getString("deviceId"), BluetoothLinkProvider.this);
addLink(identityPackage, link);
addLink(identityPacket, link);
}
}
@@ -263,7 +266,7 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
}
@Override
@TargetApi(value=Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
@TargetApi(value = Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BluetoothDevice.ACTION_UUID)) {
@@ -278,7 +281,7 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
return;
}
for (Parcelable uuid: activeUuids) {
for (Parcelable uuid : activeUuids) {
if (uuid.toString().equals(SERVICE_UUID.toString())) {
connectToDevice(device);
return;
@@ -327,14 +330,14 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
try {
int character;
StringBuilder sb = new StringBuilder();
while(sb.lastIndexOf("\n") == -1 && (character = socket.getInputStream().read()) != -1) {
sb.append((char)character);
while (sb.lastIndexOf("\n") == -1 && (character = socket.getInputStream().read()) != -1) {
sb.append((char) character);
}
String message = sb.toString();
final NetworkPackage identityPackage = NetworkPackage.unserialize(message);
final NetworkPacket identityPacket = NetworkPacket.unserialize(message);
if (!identityPackage.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
if (!identityPacket.getType().equals(NetworkPacket.PACKET_TYPE_IDENTITY)) {
Log.e("BTLinkProvider/Client", "1 Expecting an identity package");
socket.close();
return;
@@ -342,27 +345,27 @@ public class BluetoothLinkProvider extends BaseLinkProvider {
Log.i("BTLinkProvider/Client", "Received identity package");
String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId");
if (identityPackage.getString("deviceId").equals(myId)) {
String myId = NetworkPacket.createIdentityPacket(context).getString("deviceId");
if (identityPacket.getString("deviceId").equals(myId)) {
// Probably won't happen, but just to be safe
socket.close();
return;
}
if (visibleComputers.containsKey(identityPackage.getString("deviceId"))) {
if (visibleComputers.containsKey(identityPacket.getString("deviceId"))) {
return;
}
Log.i("BTLinkProvider/Client", "Identity package received, creating link");
final BluetoothLink link = new BluetoothLink(context, socket,
identityPackage.getString("deviceId"), BluetoothLinkProvider.this);
identityPacket.getString("deviceId"), BluetoothLinkProvider.this);
NetworkPackage np2 = NetworkPackage.createIdentityPackage(context);
link.sendPackage(np2,new Device.SendPackageStatusCallback() {
NetworkPacket np2 = NetworkPacket.createIdentityPacket(context);
link.sendPacket(np2, new Device.SendPacketStatusCallback() {
@Override
public void onSuccess() {
addLink(identityPackage, link);
addLink(identityPacket, link);
}
@Override

View File

@@ -21,9 +21,10 @@
package org.kde.kdeconnect.Backends.BluetoothBackend;
import android.util.Log;
import org.kde.kdeconnect.Backends.BasePairingHandler;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect_tp.R;
import java.util.Timer;
@@ -32,6 +33,7 @@ import java.util.TimerTask;
public class BluetoothPairingHandler extends BasePairingHandler {
Timer mPairingTimer;
public BluetoothPairingHandler(Device device, final PairingHandlerCallback callback) {
super(device, callback);
@@ -42,15 +44,15 @@ public class BluetoothPairingHandler extends BasePairingHandler {
}
}
// @Override
public NetworkPackage createPairPackage() {
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);
// @Override
public NetworkPacket createPairPacket() {
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
np.set("pair", true);
return np;
}
@Override
public void packageReceived(NetworkPackage np) throws Exception{
public void packageReceived(NetworkPacket np) throws Exception {
boolean wantsPair = np.getBoolean("pair");
@@ -66,7 +68,7 @@ public class BluetoothPairingHandler extends BasePairingHandler {
if (wantsPair) {
if (mPairStatus == PairStatus.Requested) { //We started pairing
if (mPairStatus == PairStatus.Requested) { //We started pairing
hidePairingNotification();
pairingDone();
} else {
@@ -89,11 +91,11 @@ public class BluetoothPairingHandler extends BasePairingHandler {
mPairingTimer.schedule(new TimerTask() {
@Override
public void run() {
Log.w("KDE/Device","Unpairing (timeout B)");
Log.w("KDE/Device", "Unpairing (timeout B)");
mPairStatus = PairStatus.NotPaired;
hidePairingNotification();
}
}, 25*1000); //Time to show notification, waiting for user to accept (peer will timeout in 30 seconds)
}, 25 * 1000); //Time to show notification, waiting for user to accept (peer will timeout in 30 seconds)
mPairStatus = PairStatus.RequestedByPeer;
mCallback.incomingRequest();
@@ -117,7 +119,7 @@ public class BluetoothPairingHandler extends BasePairingHandler {
@Override
public void requestPairing() {
Device.SendPackageStatusCallback statusCallback = new Device.SendPackageStatusCallback() {
Device.SendPacketStatusCallback statusCallback = new Device.SendPacketStatusCallback() {
@Override
public void onSuccess() {
hidePairingNotification(); //Will stop the pairingTimer if it was running
@@ -126,10 +128,10 @@ public class BluetoothPairingHandler extends BasePairingHandler {
@Override
public void run() {
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_timed_out));
Log.w("KDE/Device","Unpairing (timeout A)");
Log.w("KDE/Device", "Unpairing (timeout A)");
mPairStatus = PairStatus.NotPaired;
}
}, 30*1000); //Time to wait for the other to accept
}, 30 * 1000); //Time to wait for the other to accept
mPairStatus = PairStatus.Requested;
}
@@ -138,20 +140,20 @@ public class BluetoothPairingHandler extends BasePairingHandler {
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_could_not_send_package));
}
};
mDevice.sendPackage(createPairPackage(), statusCallback);
mDevice.sendPacket(createPairPacket(), statusCallback);
}
public void hidePairingNotification() {
mDevice.hidePairingNotification();
if (mPairingTimer != null) {
mPairingTimer .cancel();
mPairingTimer.cancel();
}
}
@Override
public void acceptPairing() {
hidePairingNotification();
Device.SendPackageStatusCallback statusCallback = new Device.SendPackageStatusCallback() {
Device.SendPacketStatusCallback statusCallback = new Device.SendPacketStatusCallback() {
@Override
public void onSuccess() {
pairingDone();
@@ -162,16 +164,16 @@ public class BluetoothPairingHandler extends BasePairingHandler {
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_not_reachable));
}
};
mDevice.sendPackage(createPairPackage(), statusCallback);
mDevice.sendPacket(createPairPacket(), statusCallback);
}
@Override
public void rejectPairing() {
hidePairingNotification();
mPairStatus = PairStatus.NotPaired;
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
np.set("pair", false);
mDevice.sendPackage(np);
mDevice.sendPacket(np);
}
//@Override
@@ -186,8 +188,8 @@ public class BluetoothPairingHandler extends BasePairingHandler {
@Override
public void unpair() {
mPairStatus = PairStatus.NotPaired;
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
np.set("pair", false);
mDevice.sendPackage(np);
mDevice.sendPacket(np);
}
}

View File

@@ -30,7 +30,7 @@ import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
import org.kde.kdeconnect.Helpers.StringsHelper;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
import java.io.BufferedReader;
import java.io.IOException;
@@ -53,8 +53,8 @@ public class LanLink extends BaseLink {
}
public enum ConnectionStarted {
Locally, Remotely;
};
Locally, Remotely
}
private ConnectionStarted connectionSource; // If the other device sent me a broadcast,
// I should not close the connection with it
@@ -89,34 +89,31 @@ public class LanLink extends BaseLink {
//Log.e("LanLink", "Start listening");
//Create a thread to take care of incoming data for the new socket
new Thread(new Runnable() {
@Override
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(newSocket.getInputStream(), StringsHelper.UTF8));
while (true) {
String packet;
try {
packet = reader.readLine();
} catch (SocketTimeoutException e) {
continue;
}
if (packet == null) {
throw new IOException("End of stream");
}
if (packet.isEmpty()) {
continue;
}
NetworkPackage np = NetworkPackage.unserialize(packet);
receivedNetworkPackage(np);
new Thread(() -> {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(newSocket.getInputStream(), StringsHelper.UTF8));
while (true) {
String packet;
try {
packet = reader.readLine();
} catch (SocketTimeoutException e) {
continue;
}
} catch (Exception e) {
Log.i("LanLink", "Socket closed: " + newSocket.hashCode() + ". Reason: " + e.getMessage());
try { Thread.sleep(300); } catch (InterruptedException ignored) {} // Wait a bit because we might receive a new socket meanwhile
boolean thereIsaANewSocket = (newSocket != socket);
if (!thereIsaANewSocket) {
callback.linkDisconnected(LanLink.this);
if (packet == null) {
throw new IOException("End of stream");
}
if (packet.isEmpty()) {
continue;
}
NetworkPacket np = NetworkPacket.unserialize(packet);
receivedNetworkPacket(np);
}
} catch (Exception e) {
Log.i("LanLink", "Socket closed: " + newSocket.hashCode() + ". Reason: " + e.getMessage());
try { Thread.sleep(300); } catch (InterruptedException ignored) {} // Wait a bit because we might receive a new socket meanwhile
boolean thereIsaANewSocket = (newSocket != socket);
if (!thereIsaANewSocket) {
callback.linkDisconnected(LanLink.this);
}
}
}).start();
@@ -142,9 +139,9 @@ public class LanLink extends BaseLink {
}
//Blocking, do not call from main thread
private boolean sendPackageInternal(NetworkPackage np, final Device.SendPackageStatusCallback callback, PublicKey key) {
private boolean sendPacketInternal(NetworkPacket np, final Device.SendPacketStatusCallback callback, PublicKey key) {
if (socket == null) {
Log.e("KDE/sendPackage", "Not yet connected");
Log.e("KDE/sendPacket", "Not yet connected");
callback.onFailure(new NotYetConnectedException());
return false;
}
@@ -167,7 +164,7 @@ public class LanLink extends BaseLink {
np = RsaHelper.encrypt(np, key);
}
//Log.e("LanLink/sendPackage", np.getType());
//Log.e("LanLink/sendPacket", np.getType());
//Send body of the network package
try {
@@ -244,24 +241,24 @@ public class LanLink extends BaseLink {
//Blocking, do not call from main thread
@Override
public boolean sendPackage(NetworkPackage np,Device.SendPackageStatusCallback callback) {
return sendPackageInternal(np, callback, null);
public boolean sendPacket(NetworkPacket np, Device.SendPacketStatusCallback callback) {
return sendPacketInternal(np, callback, null);
}
//Blocking, do not call from main thread
@Override
public boolean sendPackageEncrypted(NetworkPackage np, Device.SendPackageStatusCallback callback, PublicKey key) {
return sendPackageInternal(np, callback, key);
public boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key) {
return sendPacketInternal(np, callback, key);
}
private void receivedNetworkPackage(NetworkPackage np) {
private void receivedNetworkPacket(NetworkPacket np) {
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_ENCRYPTED)) {
if (np.getType().equals(NetworkPacket.PACKET_TYPE_ENCRYPTED)) {
try {
np = RsaHelper.decrypt(np, privateKey);
} catch(Exception e) {
e.printStackTrace();
Log.e("KDE/onPackageReceived","Exception decrypting the package");
Log.e("KDE/onPacketReceived","Exception decrypting the package");
}
}

View File

@@ -15,7 +15,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.Backends.LanBackend;
@@ -27,6 +27,7 @@ import android.preference.PreferenceManager;
import android.util.Base64;
import android.util.Log;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device;
@@ -34,7 +35,7 @@ import org.kde.kdeconnect.Helpers.DeviceHelper;
import org.kde.kdeconnect.Helpers.NetworkHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
import org.kde.kdeconnect.Helpers.StringsHelper;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect.UserInterface.CustomDevicesActivity;
import java.io.BufferedReader;
@@ -59,6 +60,13 @@ import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLSocket;
/**
* This BaseLinkProvider creates {@link LanLink}s to other devices on the same
* WiFi network. The first packet sent over a socket must be an
* {@link NetworkPacket#createIdentityPacket(Context)}.
*
* @see #identityPacketReceived(NetworkPacket, Socket, LanLink.ConnectionStarted)
*/
public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDisconnectedCallback {
public static final int MIN_VERSION_WITH_SSL_SUPPORT = 6;
@@ -90,26 +98,26 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
}
//They received my UDP broadcast and are connecting to me. The first thing they sned should be their identity.
void tcpPackageReceived(Socket socket) throws Exception {
void tcpPacketReceived(Socket socket) throws Exception {
NetworkPackage networkPackage;
NetworkPacket networkPacket;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = reader.readLine();
networkPackage = NetworkPackage.unserialize(message);
//Log.e("TcpListener","Received TCP package: "+networkPackage.serialize());
networkPacket = NetworkPacket.unserialize(message);
//Log.e("TcpListener","Received TCP package: "+networkPacket.serialize());
} catch (Exception e) {
e.printStackTrace();
return;
}
if (!networkPackage.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
Log.e("KDE/LanLinkProvider", "Expecting an identity package instead of " + networkPackage.getType());
if (!networkPacket.getType().equals(NetworkPacket.PACKET_TYPE_IDENTITY)) {
Log.e("KDE/LanLinkProvider", "Expecting an identity package instead of " + networkPacket.getType());
return;
}
Log.i("KDE/LanLinkProvider", "Identity package received from a TCP connection from " + networkPackage.getString("deviceName"));
identityPackageReceived(networkPackage, socket, LanLink.ConnectionStarted.Locally);
Log.i("KDE/LanLinkProvider", "Identity package received from a TCP connection from " + networkPacket.getString("deviceName"));
identityPacketReceived(networkPacket, socket, LanLink.ConnectionStarted.Locally);
}
//I've received their broadcast and should connect to their TCP socket and send my identity.
@@ -120,9 +128,9 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
try {
String message = new String(packet.getData(), StringsHelper.UTF8);
final NetworkPackage identityPackage = NetworkPackage.unserialize(message);
final String deviceId = identityPackage.getString("deviceId");
if (!identityPackage.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
final NetworkPacket identityPacket = NetworkPacket.unserialize(message);
final String deviceId = identityPacket.getString("deviceId");
if (!identityPacket.getType().equals(NetworkPacket.PACKET_TYPE_IDENTITY)) {
Log.e("KDE/LanLinkProvider", "Expecting an UDP identity package");
return;
} else {
@@ -133,38 +141,38 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
}
}
if (identityPackage.getInt("protocolVersion") >= MIN_VERSION_WITH_NEW_PORT_SUPPORT && identityPackage.getInt("tcpPort") < MIN_PORT) {
if (identityPacket.getInt("protocolVersion") >= MIN_VERSION_WITH_NEW_PORT_SUPPORT && identityPacket.getInt("tcpPort") < MIN_PORT) {
Log.w("KDE/LanLinkProvider", "Ignoring a udp broadcast from legacy port because it comes from a device which knows about the new port.");
return;
}
Log.i("KDE/LanLinkProvider", "Broadcast identity package received from " + identityPackage.getString("deviceName"));
Log.i("KDE/LanLinkProvider", "Broadcast identity package received from " + identityPacket.getString("deviceName"));
int tcpPort = identityPackage.getInt("tcpPort", MIN_PORT);
int tcpPort = identityPacket.getInt("tcpPort", MIN_PORT);
SocketFactory socketFactory = SocketFactory.getDefault();
Socket socket = socketFactory.createSocket(address, tcpPort);
configureSocket(socket);
OutputStream out = socket.getOutputStream();
NetworkPackage myIdentity = NetworkPackage.createIdentityPackage(context);
NetworkPacket myIdentity = NetworkPacket.createIdentityPacket(context);
out.write(myIdentity.serialize().getBytes());
out.flush();
identityPackageReceived(identityPackage, socket, LanLink.ConnectionStarted.Remotely);
identityPacketReceived(identityPacket, socket, LanLink.ConnectionStarted.Remotely);
} catch (Exception e) {
Log.e("KDE/LanLinkProvider", "Cannot connect to " + address);
e.printStackTrace();
if (!reverseConnectionBlackList.contains(address)) {
Log.w("KDE/LanLinkProvider","Blacklisting "+address);
Log.w("KDE/LanLinkProvider", "Blacklisting " + address);
reverseConnectionBlackList.add(address);
new Timer().schedule(new TimerTask() {
@Override
public void run() {
reverseConnectionBlackList.remove(address);
}
}, 5*1000);
}, 5 * 1000);
// Try to cause a reverse connection
onNetworkChange();
@@ -180,10 +188,22 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
}
}
private void identityPackageReceived(final NetworkPackage identityPackage, final Socket socket, final LanLink.ConnectionStarted connectionStarted) {
/**
* Called when a new 'identity' packet is received. Those are passed here by
* {@link #tcpPacketReceived(Socket)} and {@link #udpPacketReceived(DatagramPacket)}.
* <p>
* If the remote device should be connected, this calls {@link #addLink}.
* Otherwise, if there was an Exception, we unpair from that device.
* </p>
*
* @param identityPacket identity of a remote device
* @param socket a new Socket, which should be used to receive packets from the remote device
* @param connectionStarted which side started this connection
*/
private void identityPacketReceived(final NetworkPacket identityPacket, final Socket socket, final LanLink.ConnectionStarted connectionStarted) {
String myId = DeviceHelper.getDeviceId(context);
final String deviceId = identityPackage.getString("deviceId");
final String deviceId = identityPacket.getString("deviceId");
if (deviceId.equals(myId)) {
Log.e("KDE/LanLinkProvider", "Somehow I'm connected to myself, ignoring. This should not happen.");
return;
@@ -194,70 +214,60 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
// Add ssl handler if device uses new protocol
try {
if (identityPackage.getInt("protocolVersion") >= MIN_VERSION_WITH_SSL_SUPPORT) {
if (identityPacket.getInt("protocolVersion") >= MIN_VERSION_WITH_SSL_SUPPORT) {
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
boolean isDeviceTrusted = preferences.getBoolean(deviceId, false);
if (isDeviceTrusted && !SslHelper.isCertificateStored(context, deviceId)) {
//Device paired with and old version, we can't use it as we lack the certificate
BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId);
if (device == null) return;
device.unpair();
//Retry as unpaired
identityPackageReceived(identityPackage, socket, connectionStarted);
}
BackgroundService.RunCommand(context, service -> {
Device device = service.getDevice(deviceId);
if (device == null) return;
device.unpair();
//Retry as unpaired
identityPacketReceived(identityPacket, socket, connectionStarted);
});
}
Log.i("KDE/LanLinkProvider","Starting SSL handshake with " + identityPackage.getString("deviceName") + " trusted:"+isDeviceTrusted);
Log.i("KDE/LanLinkProvider", "Starting SSL handshake with " + identityPacket.getString("deviceName") + " trusted:" + isDeviceTrusted);
final SSLSocket sslsocket = SslHelper.convertToSslSocket(context, socket, deviceId, isDeviceTrusted, clientMode);
sslsocket.addHandshakeCompletedListener(new HandshakeCompletedListener() {
@Override
public void handshakeCompleted(HandshakeCompletedEvent event) {
String mode = clientMode? "client" : "server";
try {
Certificate certificate = event.getPeerCertificates()[0];
identityPackage.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
Log.i("KDE/LanLinkProvider","Handshake as " + mode + " successful with " + identityPackage.getString("deviceName") + " secured with " + event.getCipherSuite());
addLink(identityPackage, sslsocket, connectionStarted);
} catch (Exception e) {
Log.e("KDE/LanLinkProvider","Handshake as " + mode + " failed with " + identityPackage.getString("deviceName"));
e.printStackTrace();
BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(deviceId);
if (device == null) return;
device.unpair();
}
});
}
sslsocket.addHandshakeCompletedListener(event -> {
String mode = clientMode ? "client" : "server";
try {
Certificate certificate = event.getPeerCertificates()[0];
identityPacket.set("certificate", Base64.encodeToString(certificate.getEncoded(), 0));
Log.i("KDE/LanLinkProvider", "Handshake as " + mode + " successful with " + identityPacket.getString("deviceName") + " secured with " + event.getCipherSuite());
addLink(identityPacket, sslsocket, connectionStarted);
} catch (Exception e) {
Log.e("KDE/LanLinkProvider", "Handshake as " + mode + " failed with " + identityPacket.getString("deviceName"));
e.printStackTrace();
BackgroundService.RunCommand(context, service -> {
Device device = service.getDevice(deviceId);
if (device == null) return;
device.unpair();
});
}
});
//Handshake is blocking, so do it on another thread and free this thread to keep receiving new connection
new Thread(new Runnable() {
@Override
public void run() {
try {
new Thread(() -> {
try {
synchronized (this) {
sslsocket.startHandshake();
} catch (Exception e) {
Log.e("KDE/LanLinkProvider","Handshake failed with " + identityPackage.getString("deviceName"));
e.printStackTrace();
//String[] ciphers = sslsocket.getSupportedCipherSuites();
//for (String cipher : ciphers) {
// Log.i("SupportedCiphers","cipher: " + cipher);
//}
}
} catch (Exception e) {
Log.e("KDE/LanLinkProvider", "Handshake failed with " + identityPacket.getString("deviceName"));
e.printStackTrace();
//String[] ciphers = sslsocket.getSupportedCipherSuites();
//for (String cipher : ciphers) {
// Log.i("SupportedCiphers","cipher: " + cipher);
//}
}
}).start();
} else {
addLink(identityPackage, socket, connectionStarted);
addLink(identityPacket, socket, connectionStarted);
}
} catch (Exception e) {
e.printStackTrace();
@@ -265,9 +275,22 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
}
private synchronized void addLink(final NetworkPackage identityPackage, Socket socket, LanLink.ConnectionStarted connectionOrigin) throws IOException {
/**
* Add or update a link in the {@link #visibleComputers} map. This method is synchronized, which ensures that only one
* link is operated on at a time.
* <p>
* Without synchronization, the call to {@link SslHelper#parseCertificate(byte[])} in
* {@link Device#addLink(NetworkPacket, BaseLink)} crashes on some devices running Oreo 8.1 (SDK level 27).
* </p>
*
* @param identityPacket representation of remote device
* @param socket a new Socket, which should be used to receive packets from the remote device
* @param connectionOrigin which side started this connection
* @throws IOException if an exception is thrown by {@link LanLink#reset(Socket, LanLink.ConnectionStarted)}
*/
private void addLink(final NetworkPacket identityPacket, Socket socket, LanLink.ConnectionStarted connectionOrigin) throws IOException {
String deviceId = identityPackage.getString("deviceId");
String deviceId = identityPacket.getString("deviceId");
LanLink currentLink = visibleComputers.get(deviceId);
if (currentLink != null) {
//Update old link
@@ -279,7 +302,7 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
//Let's create the link
LanLink link = new LanLink(context, deviceId, this, socket, connectionOrigin);
visibleComputers.put(deviceId, link);
connectionAccepted(identityPackage, link);
connectionAccepted(identityPacket, link);
}
}
@@ -298,23 +321,20 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
e.printStackTrace();
return null;
}
new Thread(new Runnable() {
@Override
public void run() {
while (listening) {
final int bufferSize = 1024 * 512;
byte[] data = new byte[bufferSize];
DatagramPacket packet = new DatagramPacket(data, bufferSize);
try {
server.receive(packet);
udpPacketReceived(packet);
} catch (Exception e) {
e.printStackTrace();
Log.e("LanLinkProvider", "UdpReceive exception");
}
new Thread(() -> {
while (listening) {
final int bufferSize = 1024 * 512;
byte[] data = new byte[bufferSize];
DatagramPacket packet = new DatagramPacket(data, bufferSize);
try {
server.receive(packet);
udpPacketReceived(packet);
} catch (Exception e) {
e.printStackTrace();
Log.e("LanLinkProvider", "UdpReceive exception");
}
Log.w("UdpListener","Stopping UDP listener");
}
Log.w("UdpListener", "Stopping UDP listener");
}).start();
return server;
}
@@ -323,21 +343,18 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
try {
tcpServer = openServerSocketOnFreePort(MIN_PORT);
new Thread(new Runnable() {
@Override
public void run() {
while (listening) {
try {
Socket socket = tcpServer.accept();
configureSocket(socket);
tcpPackageReceived(socket);
} catch (Exception e) {
e.printStackTrace();
Log.e("LanLinkProvider", "TcpReceive exception");
}
new Thread(() -> {
while (listening) {
try {
Socket socket = tcpServer.accept();
configureSocket(socket);
tcpPacketReceived(socket);
} catch (Exception e) {
e.printStackTrace();
Log.e("LanLinkProvider", "TcpReceive exception");
}
Log.w("TcpListener", "Stopping TCP listener");
}
Log.w("TcpListener", "Stopping TCP listener");
}).start();
} catch (Exception e) {
@@ -347,13 +364,13 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
static ServerSocket openServerSocketOnFreePort(int minPort) throws IOException {
int tcpPort = minPort;
while(tcpPort < MAX_PORT) {
while (tcpPort < MAX_PORT) {
try {
ServerSocket candidateServer = new ServerSocket();
candidateServer.bind(new InetSocketAddress(tcpPort));
Log.i("KDE/LanLink", "Using port "+tcpPort);
Log.i("KDE/LanLink", "Using port " + tcpPort);
return candidateServer;
} catch(IOException e) {
} catch (IOException e) {
tcpPort++;
}
}
@@ -361,60 +378,58 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
throw new IOException("No ports available");
}
private void broadcastUdpPackage() {
private void broadcastUdpPacket() {
if (NetworkHelper.isOnMobileNetwork(context)) {
Log.w("LanLinkProvider", "On 3G network, not sending broadcast.");
return;
}
new Thread(new Runnable() {
@Override
public void run() {
new Thread(() -> {
String deviceListPrefs = PreferenceManager.getDefaultSharedPreferences(context).getString(CustomDevicesActivity.KEY_CUSTOM_DEVLIST_PREFERENCE, "");
ArrayList<String> iplist = new ArrayList<>();
if (!deviceListPrefs.isEmpty()) {
iplist = CustomDevicesActivity.deserializeIpList(deviceListPrefs);
}
iplist.add("255.255.255.255"); //Default: broadcast.
String deviceListPrefs = PreferenceManager.getDefaultSharedPreferences(context).getString(CustomDevicesActivity.KEY_CUSTOM_DEVLIST_PREFERENCE, "");
ArrayList<String> iplist = new ArrayList<>();
if (!deviceListPrefs.isEmpty()) {
iplist = CustomDevicesActivity.deserializeIpList(deviceListPrefs);
}
iplist.add("255.255.255.255"); //Default: broadcast.
NetworkPackage identity = NetworkPackage.createIdentityPackage(context);
identity.set("tcpPort", MIN_PORT);
DatagramSocket socket = null;
byte[] bytes = null;
try {
socket = new DatagramSocket();
socket.setReuseAddress(true);
socket.setBroadcast(true);
bytes = identity.serialize().getBytes(StringsHelper.UTF8);
} catch (Exception e) {
e.printStackTrace();
Log.e("KDE/LanLinkProvider","Failed to create DatagramSocket");
}
NetworkPacket identity = NetworkPacket.createIdentityPacket(context);
identity.set("tcpPort", MIN_PORT);
DatagramSocket socket = null;
byte[] bytes = null;
try {
socket = new DatagramSocket();
socket.setReuseAddress(true);
socket.setBroadcast(true);
bytes = identity.serialize().getBytes(StringsHelper.UTF8);
} catch (Exception e) {
e.printStackTrace();
Log.e("KDE/LanLinkProvider", "Failed to create DatagramSocket");
}
if (bytes != null) {
//Log.e("KDE/LanLinkProvider","Sending packet to "+iplist.size()+" ips");
for (String ipstr : iplist) {
try {
InetAddress client = InetAddress.getByName(ipstr);
socket.send(new DatagramPacket(bytes, bytes.length, client, MIN_PORT));
socket.send(new DatagramPacket(bytes, bytes.length, client, MIN_PORT_LEGACY));
//Log.i("KDE/LanLinkProvider","Udp identity package sent to address "+client);
} catch (Exception e) {
e.printStackTrace();
Log.e("KDE/LanLinkProvider", "Sending udp identity package failed. Invalid address? (" + ipstr + ")");
}
if (bytes != null) {
//Log.e("KDE/LanLinkProvider","Sending packet to "+iplist.size()+" ips");
for (String ipstr : iplist) {
try {
InetAddress client = InetAddress.getByName(ipstr);
socket.send(new DatagramPacket(bytes, bytes.length, client, MIN_PORT));
socket.send(new DatagramPacket(bytes, bytes.length, client, MIN_PORT_LEGACY));
//Log.i("KDE/LanLinkProvider","Udp identity package sent to address "+client);
} catch (Exception e) {
e.printStackTrace();
Log.e("KDE/LanLinkProvider", "Sending udp identity package failed. Invalid address? (" + ipstr + ")");
}
}
if (socket != null) {
socket.close();
}
}
if (socket != null) {
socket.close();
}
}).start();
}
@Override
public void onStart() {
//Log.i("KDE/LanLinkProvider", "onStart");
@@ -431,18 +446,18 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
// and newer android versions. Although devices with android version less than ICS cannot connect to other devices who also have android version less
// than ICS because server is disabled on both
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
Log.w("KDE/LanLinkProvider","Not starting a TCP server because it's not supported on Android < 14. Operating only as client.");
Log.w("KDE/LanLinkProvider", "Not starting a TCP server because it's not supported on Android < 14. Operating only as client.");
} else {
setupTcpListener();
}
broadcastUdpPackage();
broadcastUdpPacket();
}
}
@Override
public void onNetworkChange() {
broadcastUdpPackage();
broadcastUdpPacket();
}
@Override
@@ -451,17 +466,17 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis
listening = false;
try {
tcpServer.close();
} catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
}
try {
udpServer.close();
} catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
}
try {
udpServerOldPort.close();
} catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
}
}

View File

@@ -28,7 +28,7 @@ import android.util.Log;
import org.kde.kdeconnect.Backends.BasePairingHandler;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
import org.kde.kdeconnect_tp.R;
import java.security.KeyFactory;
@@ -51,8 +51,8 @@ public class LanPairingHandler extends BasePairingHandler {
}
}
private NetworkPackage createPairPackage() {
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);
private NetworkPacket createPairPacket() {
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
np.set("pair", true);
SharedPreferences globalSettings = PreferenceManager.getDefaultSharedPreferences(mDevice.getContext());
String publicKey = "-----BEGIN PUBLIC KEY-----\n" + globalSettings.getString("publicKey", "").trim()+ "\n-----END PUBLIC KEY-----\n";
@@ -61,7 +61,7 @@ public class LanPairingHandler extends BasePairingHandler {
}
@Override
public void packageReceived(NetworkPackage np) throws Exception{
public void packageReceived(NetworkPacket np) throws Exception{
boolean wantsPair = np.getBoolean("pair");
@@ -140,7 +140,7 @@ public class LanPairingHandler extends BasePairingHandler {
@Override
public void requestPairing() {
Device.SendPackageStatusCallback statusCallback = new Device.SendPackageStatusCallback() {
Device.SendPacketStatusCallback statusCallback = new Device.SendPacketStatusCallback() {
@Override
public void onSuccess() {
hidePairingNotification(); //Will stop the pairingTimer if it was running
@@ -166,7 +166,7 @@ public class LanPairingHandler extends BasePairingHandler {
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_could_not_send_package));
}
};
mDevice.sendPackage(createPairPackage(), statusCallback);
mDevice.sendPacket(createPairPacket(), statusCallback);
}
void hidePairingNotification() {
@@ -179,7 +179,7 @@ public class LanPairingHandler extends BasePairingHandler {
@Override
public void acceptPairing() {
hidePairingNotification();
Device.SendPackageStatusCallback statusCallback = new Device.SendPackageStatusCallback() {
Device.SendPacketStatusCallback statusCallback = new Device.SendPacketStatusCallback() {
@Override
public void onSuccess() {
pairingDone();
@@ -195,16 +195,16 @@ public class LanPairingHandler extends BasePairingHandler {
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_not_reachable));
}
};
mDevice.sendPackage(createPairPackage(), statusCallback);
mDevice.sendPacket(createPairPacket(), statusCallback);
}
@Override
public void rejectPairing() {
hidePairingNotification();
mPairStatus = PairStatus.NotPaired;
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
np.set("pair", false);
mDevice.sendPackage(np);
mDevice.sendPacket(np);
}
void pairingDone() {
@@ -242,8 +242,8 @@ public class LanPairingHandler extends BasePairingHandler {
@Override
public void unpair() {
mPairStatus = PairStatus.NotPaired;
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);
NetworkPacket np = new NetworkPacket(NetworkPacket.PACKET_TYPE_PAIR);
np.set("pair", false);
mDevice.sendPackage(np);
mDevice.sendPacket(np);
}
}

View File

@@ -26,7 +26,7 @@ import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.Backends.BasePairingHandler;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
import java.security.PublicKey;
@@ -47,7 +47,7 @@ public class LoopbackLink extends BaseLink {
}
@Override
public boolean sendPackage(NetworkPackage in, Device.SendPackageStatusCallback callback) {
public boolean sendPacket(NetworkPacket in, Device.SendPacketStatusCallback callback) {
packageReceived(in);
if (in.hasPayload()) {
callback.onProgressChanged(0);
@@ -59,7 +59,7 @@ public class LoopbackLink extends BaseLink {
}
@Override
public boolean sendPackageEncrypted(NetworkPackage np, Device.SendPackageStatusCallback callback, PublicKey key) {
return sendPackage(np, callback);
public boolean sendPacketEncrypted(NetworkPacket np, Device.SendPacketStatusCallback callback, PublicKey key) {
return sendPacket(np, callback);
}
}

View File

@@ -23,7 +23,7 @@ package org.kde.kdeconnect.Backends.LoopbackBackend;
import android.content.Context;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
public class LoopbackLinkProvider extends BaseLinkProvider {
@@ -44,7 +44,7 @@ public class LoopbackLinkProvider extends BaseLinkProvider {
@Override
public void onNetworkChange() {
NetworkPackage np = NetworkPackage.createIdentityPackage(context);
NetworkPacket np = NetworkPacket.createIdentityPacket(context);
connectionAccepted(np, new LoopbackLink(context, this));
}
/*

View File

@@ -24,7 +24,7 @@ import android.util.Log;
import org.kde.kdeconnect.Backends.BasePairingHandler;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.NetworkPacket;
public class LoopbackPairingHandler extends BasePairingHandler {
@@ -33,7 +33,7 @@ public class LoopbackPairingHandler extends BasePairingHandler {
}
@Override
public void packageReceived(NetworkPackage np) throws Exception {
public void packageReceived(NetworkPacket np) throws Exception {
}

View File

@@ -60,7 +60,7 @@ public class BackgroundService extends Service {
private final HashSet<Object> discoveryModeAcquisitions = new HashSet<>();
public static BackgroundService getInstance(){
public static BackgroundService getInstance() {
return instance;
}
@@ -87,24 +87,18 @@ public class BackgroundService extends Service {
}
public static void addGuiInUseCounter(final Context activity, final boolean forceNetworkRefresh) {
BackgroundService.RunCommand(activity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
boolean refreshed = service.acquireDiscoveryMode(activity);
if (!refreshed && forceNetworkRefresh) {
service.onNetworkChange();
}
BackgroundService.RunCommand(activity, service -> {
boolean refreshed = service.acquireDiscoveryMode(activity);
if (!refreshed && forceNetworkRefresh) {
service.onNetworkChange();
}
});
}
public static void removeGuiInUseCounter(final Context activity) {
BackgroundService.RunCommand(activity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
//If no user interface is open, close the connections open to other devices
service.releaseDiscoveryMode(activity);
}
BackgroundService.RunCommand(activity, service -> {
//If no user interface is open, close the connections open to other devices
service.releaseDiscoveryMode(activity);
});
}
@@ -113,14 +107,17 @@ public class BackgroundService extends Service {
public void incomingRequest() {
onDeviceListChanged();
}
@Override
public void pairingSuccessful() {
onDeviceListChanged();
}
@Override
public void pairingFailed(String error) {
onDeviceListChanged();
}
@Override
public void unpaired() {
onDeviceListChanged();
@@ -128,7 +125,7 @@ public class BackgroundService extends Service {
};
public void onDeviceListChanged() {
for(DeviceListChangedCallback callback : deviceListChangedCallbacks.values()) {
for (DeviceListChangedCallback callback : deviceListChangedCallbacks.values()) {
callback.onDeviceListChanged();
}
}
@@ -137,11 +134,11 @@ public class BackgroundService extends Service {
//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) {
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);
devices.put(deviceId, device);
device.addPairingCallback(devicePairingCallback);
}
}
@@ -164,13 +161,10 @@ public class BackgroundService extends Service {
}
private void cleanDevices() {
new Thread(new Runnable() {
@Override
public void run() {
for(Device d : devices.values()) {
if (!d.isPaired() && !d.isPairRequested() && !d.isPairRequestedByPeer() && !d.deviceShouldBeKeptAlive()) {
d.disconnect();
}
new Thread(() -> {
for (Device d : devices.values()) {
if (!d.isPaired() && !d.isPairRequested() && !d.isPairRequestedByPeer() && !d.deviceShouldBeKeptAlive()) {
d.disconnect();
}
}
}).start();
@@ -178,22 +172,21 @@ public class BackgroundService extends Service {
private final BaseLinkProvider.ConnectionReceiver deviceListener = new BaseLinkProvider.ConnectionReceiver() {
@Override
public void onConnectionReceived(final NetworkPackage identityPackage, final BaseLink link) {
public void onConnectionReceived(final NetworkPacket identityPacket, final BaseLink link) {
String deviceId = identityPackage.getString("deviceId");
String deviceId = identityPacket.getString("deviceId");
Device device = devices.get(deviceId);
if (device != null) {
Log.i("KDE/BackgroundService", "addLink, known device: " + deviceId);
device.addLink(identityPackage, link);
device.addLink(identityPacket, link);
} else {
Log.i("KDE/BackgroundService", "addLink,unknown device: " + deviceId);
device = new Device(BackgroundService.this, identityPackage, link);
device = new Device(BackgroundService.this, identityPacket, link);
if (device.isPaired() || device.isPairRequested() || device.isPairRequestedByPeer()
|| link.linkShouldBeKeptAlive()
||!discoveryModeAcquisitions.isEmpty() )
{
|| !discoveryModeAcquisitions.isEmpty()) {
devices.put(deviceId, device);
device.addPairingCallback(devicePairingCallback);
} else {
@@ -247,6 +240,7 @@ public class BackgroundService extends Service {
public void addDeviceListChangedCallback(String key, DeviceListChangedCallback callback) {
deviceListChangedCallbacks.put(key, callback);
}
public void removeDeviceListChangedCallback(String key) {
deviceListChangedCallbacks.remove(key);
}
@@ -290,7 +284,7 @@ public class BackgroundService extends Service {
}
@Override
public IBinder onBind (Intent intent) {
public IBinder onBind(Intent intent) {
return new Binder();
}
@@ -325,20 +319,17 @@ public class BackgroundService extends Service {
}
public static void RunCommand(final Context c, final InstanceCallback callback) {
new Thread(new Runnable() {
@Override
public void run() {
if (callback != null) {
mutex.lock();
try {
callbacks.add(callback);
} finally {
mutex.unlock();
}
new Thread(() -> {
if (callback != null) {
mutex.lock();
try {
callbacks.add(callback);
} finally {
mutex.unlock();
}
Intent serviceIntent = new Intent(c, BackgroundService.class);
c.startService(serviceIntent);
}
Intent serviceIntent = new Intent(c, BackgroundService.class);
c.startService(serviceIntent);
}).start();
}

View File

@@ -42,7 +42,7 @@ import org.kde.kdeconnect.Helpers.NotificationHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
import org.kde.kdeconnect.Plugins.Plugin;
import org.kde.kdeconnect.Plugins.PluginFactory;
import org.kde.kdeconnect.UserInterface.MaterialActivity;
import org.kde.kdeconnect.UserInterface.MainActivity;
import org.kde.kdeconnect_tp.R;
import java.security.KeyFactory;
@@ -61,7 +61,7 @@ import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
public class Device implements BaseLink.PackageReceiver {
public class Device implements BaseLink.PacketReceiver {
private final Context context;
@@ -103,26 +103,37 @@ public class Device implements BaseLink.PackageReceiver {
public enum DeviceType {
Phone,
Tablet,
Computer;
Computer,
Tv;
public static DeviceType FromString(String s) {
if ("tablet".equals(s)) return Tablet;
if ("phone".equals(s)) return Phone;
if ("tv".equals(s)) return Tv;
return Computer; //Default
}
public String toString() {
switch (this) {
case Tablet: return "tablet";
case Phone: return "phone";
default: return "desktop";
case Tablet:
return "tablet";
case Phone:
return "phone";
case Tv:
return "tv";
default:
return "desktop";
}
}
}
public interface PairingCallback {
void incomingRequest();
void pairingSuccessful();
void pairingFailed(String error);
void unpaired();
}
@@ -136,7 +147,7 @@ public class Device implements BaseLink.PackageReceiver {
this.deviceId = deviceId;
this.name = settings.getString("deviceName", context.getString(R.string.unknown_device));
this.pairStatus = PairStatus.Paired;
this.protocolVersion = NetworkPackage.ProtocolVersion; //We don't know it yet
this.protocolVersion = NetworkPacket.ProtocolVersion; //We don't know it yet
this.deviceType = DeviceType.FromString(settings.getString("deviceType", "desktop"));
try {
@@ -147,7 +158,7 @@ public class Device implements BaseLink.PackageReceiver {
}
} catch (Exception e) {
e.printStackTrace();
Log.e("KDE/Device","Exception deserializing stored public key for device");
Log.e("KDE/Device", "Exception deserializing stored public key for device");
}
//Assume every plugin is supported until addLink is called and we can get the actual list
@@ -158,7 +169,7 @@ 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) {
Device(Context context, NetworkPacket np, BaseLink dl) {
//Log.e("Device","Constructor B");
@@ -176,16 +187,23 @@ public class Device implements BaseLink.PackageReceiver {
}
public String getName() {
return name != null? name : context.getString(R.string.unknown_device);
return name != null ? name : context.getString(R.string.unknown_device);
}
public Drawable getIcon()
{
public Drawable getIcon() {
int drawableId;
switch (deviceType) {
case Phone: drawableId = R.drawable.ic_device_phone; break;
case Tablet: drawableId = R.drawable.ic_device_tablet; break;
default: drawableId = R.drawable.ic_device_laptop;
case Phone:
drawableId = R.drawable.ic_device_phone;
break;
case Tablet:
drawableId = R.drawable.ic_device_tablet;
break;
case Tv:
drawableId = R.drawable.ic_device_tv;
break;
default:
drawableId = R.drawable.ic_device_laptop;
}
return ContextCompat.getDrawable(context, drawableId);
}
@@ -204,12 +222,10 @@ public class Device implements BaseLink.PackageReceiver {
//Returns 0 if the version matches, < 0 if it is older or > 0 if it is newer
public int compareProtocolVersion() {
return protocolVersion - NetworkPackage.ProtocolVersion;
return protocolVersion - NetworkPacket.ProtocolVersion;
}
//
// Pairing-related functions
//
@@ -221,7 +237,7 @@ public class Device implements BaseLink.PackageReceiver {
/* Asks all pairing handlers that, is pair requested? */
public boolean isPairRequested() {
boolean pairRequested = false;
for (BasePairingHandler ph: pairingHandlers.values()) {
for (BasePairingHandler ph : pairingHandlers.values()) {
pairRequested = pairRequested || ph.isPairRequested();
}
return pairRequested;
@@ -248,14 +264,11 @@ public class Device implements BaseLink.PackageReceiver {
Resources res = context.getResources();
switch(pairStatus) {
case Paired:
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(res.getString(R.string.error_already_paired));
}
return;
case NotPaired:
;
if (isPaired()) {
for (PairingCallback cb : pairingCallback) {
cb.pairingFailed(res.getString(R.string.error_already_paired));
}
return;
}
if (!isReachable()) {
@@ -311,7 +324,7 @@ public class Device implements BaseLink.PackageReceiver {
//Store as trusted device
SharedPreferences preferences = context.getSharedPreferences("trusted_devices", Context.MODE_PRIVATE);
preferences.edit().putBoolean(deviceId,true).apply();
preferences.edit().putBoolean(deviceId, true).apply();
SharedPreferences.Editor editor = context.getSharedPreferences(deviceId, Context.MODE_PRIVATE).edit();
editor.putString("deviceName", name);
@@ -366,25 +379,25 @@ public class Device implements BaseLink.PackageReceiver {
hidePairingNotification();
notificationId = (int)System.currentTimeMillis();
notificationId = (int) System.currentTimeMillis();
Intent intent = new Intent(getContext(), MaterialActivity.class);
Intent intent = new Intent(getContext(), MainActivity.class);
intent.putExtra("deviceId", getDeviceId());
intent.putExtra("notificationId", notificationId);
PendingIntent pendingIntent = PendingIntent.getActivity(getContext(), 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
Intent acceptIntent = new Intent(getContext(), MaterialActivity.class);
Intent rejectIntent = new Intent(getContext(), MaterialActivity.class);
Intent acceptIntent = new Intent(getContext(), MainActivity.class);
Intent rejectIntent = new Intent(getContext(), MainActivity.class);
acceptIntent.putExtra("deviceId", getDeviceId());
acceptIntent.putExtra("notificationId", notificationId);
acceptIntent.setAction("action "+System.currentTimeMillis());
acceptIntent.putExtra(MaterialActivity.PAIR_REQUEST_STATUS, MaterialActivity.PAIRING_ACCEPTED);
acceptIntent.setAction("action " + System.currentTimeMillis());
acceptIntent.putExtra(MainActivity.PAIR_REQUEST_STATUS, MainActivity.PAIRING_ACCEPTED);
rejectIntent.putExtra("deviceId", getDeviceId());
rejectIntent.putExtra("notificationId", notificationId);
rejectIntent.setAction("action "+System.currentTimeMillis());
rejectIntent.putExtra(MaterialActivity.PAIR_REQUEST_STATUS, MaterialActivity.PAIRING_REJECTED);
rejectIntent.setAction("action " + System.currentTimeMillis());
rejectIntent.putExtra(MainActivity.PAIR_REQUEST_STATUS, MainActivity.PAIRING_REJECTED);
PendingIntent acceptedPendingIntent = PendingIntent.getActivity(getContext(), 2, acceptIntent, PendingIntent.FLAG_ONE_SHOT);
PendingIntent rejectedPendingIntent = PendingIntent.getActivity(getContext(), 4, rejectIntent, PendingIntent.FLAG_ONE_SHOT);
@@ -423,24 +436,24 @@ public class Device implements BaseLink.PackageReceiver {
return !links.isEmpty();
}
public void addLink(NetworkPackage identityPackage, BaseLink link) {
public void addLink(NetworkPacket identityPacket, BaseLink link) {
//FilesHelper.LogOpenFileCount();
this.protocolVersion = identityPackage.getInt("protocolVersion");
this.protocolVersion = identityPacket.getInt("protocolVersion");
if (identityPackage.has("deviceName")) {
this.name = identityPackage.getString("deviceName", this.name);
if (identityPacket.has("deviceName")) {
this.name = identityPacket.getString("deviceName", this.name);
SharedPreferences.Editor editor = settings.edit();
editor.putString("deviceName", this.name);
editor.apply();
}
if (identityPackage.has("deviceType")) {
this.deviceType = DeviceType.FromString(identityPackage.getString("deviceType", "desktop"));
if (identityPacket.has("deviceType")) {
this.deviceType = DeviceType.FromString(identityPacket.getString("deviceType", "desktop"));
}
if (identityPackage.has("certificate")) {
String certificateString = identityPackage.getString("certificate");
if (identityPacket.has("certificate")) {
String certificateString = identityPacket.getString("certificate");
try {
byte[] certificateBytes = Base64.decode(certificateString, 0);
@@ -466,7 +479,7 @@ public class Device implements BaseLink.PackageReceiver {
Log.e("KDE/Device", "Exception reading our own private key"); //Should not happen
}
Log.i("KDE/Device","addLink "+link.getLinkProvider().getName()+" -> "+getName() + " active links: "+ links.size());
Log.i("KDE/Device", "addLink " + link.getLinkProvider().getName() + " -> " + getName() + " active links: " + links.size());
if (!pairingHandlers.containsKey(link.getName())) {
BasePairingHandler.PairingHandlerCallback callback = new BasePairingHandler.PairingHandlerCallback() {
@@ -497,15 +510,15 @@ public class Device implements BaseLink.PackageReceiver {
pairingHandlers.put(link.getName(), link.getPairingHandler(this, callback));
}
Set<String> outgoingCapabilities = identityPackage.getStringSet("outgoingCapabilities", null);
Set<String> incomingCapabilities = identityPackage.getStringSet("incomingCapabilities", null);
Set<String> outgoingCapabilities = identityPacket.getStringSet("outgoingCapabilities", null);
Set<String> incomingCapabilities = identityPacket.getStringSet("incomingCapabilities", null);
if (incomingCapabilities != null && outgoingCapabilities != null) {
m_supportedPlugins = new Vector<>(PluginFactory.pluginsForCapabilities(context, incomingCapabilities, outgoingCapabilities));
} else {
m_supportedPlugins = new Vector<>(PluginFactory.getAvailablePlugins());
}
link.addPackageReceiver(this);
link.addPacketReceiver(this);
reloadPluginsFromSettings();
@@ -526,7 +539,7 @@ public class Device implements BaseLink.PackageReceiver {
pairingHandlers.remove(link.getName());
}
link.removePackageReceiver(this);
link.removePacketReceiver(this);
links.remove(link);
Log.i("KDE/Device", "removeLink: " + link.getLinkProvider().getName() + " -> " + getName() + " active links: " + links.size());
if (links.isEmpty()) {
@@ -535,20 +548,20 @@ public class Device implements BaseLink.PackageReceiver {
}
@Override
public void onPackageReceived(NetworkPackage np) {
public void onPacketReceived(NetworkPacket np) {
hackToMakeRetrocompatiblePacketTypes(np);
if (NetworkPackage.PACKAGE_TYPE_PAIR.equals(np.getType())) {
if (NetworkPacket.PACKET_TYPE_PAIR.equals(np.getType())) {
Log.i("KDE/Device", "Pair package");
for (BasePairingHandler ph: pairingHandlers.values()) {
for (BasePairingHandler ph : pairingHandlers.values()) {
try {
ph.packageReceived(np);
} catch (Exception e) {
e.printStackTrace();
Log.e("PairingPackageReceived","Exception");
Log.e("PairingPacketReceived", "Exception");
}
}
} else if (isPaired()) {
@@ -559,11 +572,11 @@ public class Device implements BaseLink.PackageReceiver {
for (String pluginKey : targetPlugins) {
Plugin plugin = plugins.get(pluginKey);
try {
plugin.onPackageReceived(np);
plugin.onPacketReceived(np);
} catch (Exception e) {
e.printStackTrace();
Log.e("KDE/Device", "Exception in " + plugin.getPluginKey() + "'s onPackageReceived()");
//try { Log.e("KDE/Device", "NetworkPackage:" + np.serialize()); } catch (Exception _) { }
Log.e("KDE/Device", "Exception in " + plugin.getPluginKey() + "'s onPacketReceived()");
//try { Log.e("KDE/Device", "NetworkPacket:" + np.serialize()); } catch (Exception _) { }
}
}
} else {
@@ -571,7 +584,7 @@ public class Device implements BaseLink.PackageReceiver {
}
} else {
//Log.e("KDE/onPackageReceived","Device not paired, will pass package to unpairedPackageListeners");
//Log.e("KDE/onPacketReceived","Device not paired, will pass package to unpairedPacketListeners");
// If it is pair package, it should be captured by "if" at start
// If not and device is paired, it should be captured by isPaired
@@ -585,10 +598,10 @@ public class Device implements BaseLink.PackageReceiver {
for (String pluginKey : targetPlugins) {
Plugin plugin = plugins.get(pluginKey);
try {
plugin.onUnpairedDevicePackageReceived(np);
plugin.onUnpairedDevicePacketReceived(np);
} catch (Exception e) {
e.printStackTrace();
Log.e("KDE/Device", "Exception in " + plugin.getDisplayName() + "'s onPackageReceived() in unPairedPackageListeners");
Log.e("KDE/Device", "Exception in " + plugin.getDisplayName() + "'s onPacketReceived() in unPairedPacketListeners");
}
}
} else {
@@ -598,70 +611,71 @@ public class Device implements BaseLink.PackageReceiver {
}
public static abstract class SendPackageStatusCallback {
public static abstract class SendPacketStatusCallback {
public abstract void onSuccess();
public abstract void onFailure(Throwable e);
public void onProgressChanged(int percent) { }
public void onProgressChanged(int percent) {
}
}
private SendPackageStatusCallback defaultCallback = new SendPackageStatusCallback() {
private SendPacketStatusCallback defaultCallback = new SendPacketStatusCallback() {
@Override
public void onSuccess() { }
public void onSuccess() {
}
@Override
public void onFailure(Throwable e) {
if (e != null) {
e.printStackTrace();
} else {
Log.e("KDE/sendPackage", "Unknown (null) exception");
Log.e("KDE/sendPacket", "Unknown (null) exception");
}
}
};
public void sendPackage(NetworkPackage np) {
sendPackage(np, defaultCallback);
public void sendPacket(NetworkPacket np) {
sendPacket(np, defaultCallback);
}
public boolean sendPackageBlocking(NetworkPackage np) {
return sendPackageBlocking(np, defaultCallback);
public boolean sendPacketBlocking(NetworkPacket np) {
return sendPacketBlocking(np, defaultCallback);
}
//Async
public void sendPackage(final NetworkPackage np, final SendPackageStatusCallback callback) {
new Thread(new Runnable() {
@Override
public void run() {
sendPackageBlocking(np, callback);
}
}).start();
public void sendPacket(final NetworkPacket np, final SendPacketStatusCallback callback) {
new Thread(() -> sendPacketBlocking(np, callback)).start();
}
public boolean sendPackageBlocking(final NetworkPackage np, final SendPackageStatusCallback callback) {
public boolean sendPacketBlocking(final NetworkPacket np, final SendPacketStatusCallback callback) {
/*
if (!m_outgoingCapabilities.contains(np.getType()) && !NetworkPackage.protocolPackageTypes.contains(np.getType())) {
Log.e("Device/sendPackage", "Plugin tried to send an undeclared package: " + np.getType());
Log.w("Device/sendPackage", "Declared outgoing package types: " + Arrays.toString(m_outgoingCapabilities.toArray()));
if (!m_outgoingCapabilities.contains(np.getType()) && !NetworkPacket.protocolPacketTypes.contains(np.getType())) {
Log.e("Device/sendPacket", "Plugin tried to send an undeclared package: " + np.getType());
Log.w("Device/sendPacket", "Declared outgoing package types: " + Arrays.toString(m_outgoingCapabilities.toArray()));
}
*/
hackToMakeRetrocompatiblePacketTypes(np);
boolean useEncryption = (protocolVersion < LanLinkProvider.MIN_VERSION_WITH_SSL_SUPPORT && (!np.getType().equals(NetworkPackage.PACKAGE_TYPE_PAIR) && isPaired()));
boolean useEncryption = (protocolVersion < LanLinkProvider.MIN_VERSION_WITH_SSL_SUPPORT && (!np.getType().equals(NetworkPacket.PACKET_TYPE_PAIR) && isPaired()));
boolean success = false;
//Make a copy to avoid concurrent modification exception if the original list changes
for (final BaseLink link : links) {
if (link == null) continue; //Since we made a copy, maybe somebody destroyed the link in the meanwhile
if (link == null)
continue; //Since we made a copy, maybe somebody destroyed the link in the meanwhile
if (useEncryption) {
success = link.sendPackageEncrypted(np, callback, publicKey);
success = link.sendPacketEncrypted(np, callback, publicKey);
} else {
success = link.sendPackage(np, callback);
success = link.sendPacket(np, callback);
}
if (success) break; //If the link didn't call sendSuccess(), try the next one
}
if (!success) {
Log.e("KDE/sendPackage", "No device link (of "+links.size()+" available) could send the package. Package "+np.getType()+" to " + name + " lost!");
Log.e("KDE/sendPacket", "No device link (of " + links.size() + " available) could send the package. Packet " + np.getType() + " to " + name + " lost!");
}
return success;
@@ -672,11 +686,11 @@ public class Device implements BaseLink.PackageReceiver {
//
public <T extends Plugin> T getPlugin(Class<T> pluginClass) {
return (T)getPlugin(Plugin.getPluginKey(pluginClass));
return (T) getPlugin(Plugin.getPluginKey(pluginClass));
}
public <T extends Plugin> T getPlugin(Class<T> pluginClass, boolean includeFailed) {
return (T)getPlugin(Plugin.getPluginKey(pluginClass), includeFailed);
return (T) getPlugin(Plugin.getPluginKey(pluginClass), includeFailed);
}
public Plugin getPlugin(String pluginKey) {
@@ -713,7 +727,7 @@ public class Device implements BaseLink.PackageReceiver {
final Plugin plugin = PluginFactory.instantiatePluginForDevice(context, pluginKey, this);
if (plugin == null) {
Log.e("KDE/addPlugin","could not instantiate plugin: "+pluginKey);
Log.e("KDE/addPlugin", "could not instantiate plugin: " + pluginKey);
//Can't put a null
//failedPlugins.put(pluginKey, null);
return false;
@@ -743,7 +757,7 @@ public class Device implements BaseLink.PackageReceiver {
failedPlugins.put(pluginKey, plugin);
}
if(!plugin.checkRequiredPermissions()){
if (!plugin.checkRequiredPermissions()) {
Log.e("KDE/addPlugin", "No permission " + pluginKey);
plugins.remove(pluginKey);
pluginsWithoutPermissions.put(pluginKey, plugin);
@@ -782,21 +796,20 @@ public class Device implements BaseLink.PackageReceiver {
//Log.e("removePlugin","removed " + pluginKey);
} catch (Exception e) {
e.printStackTrace();
Log.e("KDE/removePlugin","Exception calling onDestroy for plugin "+pluginKey);
Log.e("KDE/removePlugin", "Exception calling onDestroy for plugin " + pluginKey);
}
return true;
}
public void setPluginEnabled(String pluginKey, boolean value) {
settings.edit().putBoolean(pluginKey,value).apply();
settings.edit().putBoolean(pluginKey, value).apply();
reloadPluginsFromSettings();
}
public boolean isPluginEnabled(String pluginKey) {
boolean enabledByDefault = PluginFactory.getPluginInfo(context, pluginKey).isEnabledByDefault();
boolean enabled = settings.getBoolean(pluginKey, enabledByDefault);
return enabled;
return settings.getBoolean(pluginKey, enabledByDefault);
}
public void reloadPluginsFromSettings() {
@@ -818,7 +831,7 @@ public class Device implements BaseLink.PackageReceiver {
if (pluginEnabled) {
boolean success = addPlugin(pluginKey);
if (success) {
for (String packageType : pluginInfo.getSupportedPackageTypes()) {
for (String packageType : pluginInfo.getSupportedPacketTypes()) {
packageType = hackToMakeRetrocompatiblePacketTypes(packageType);
ArrayList<String> plugins = newPluginsByIncomingInterface.get(packageType);
if (plugins == null) plugins = new ArrayList<>();
@@ -843,11 +856,11 @@ public class Device implements BaseLink.PackageReceiver {
}
}
public ConcurrentHashMap<String,Plugin> getLoadedPlugins() {
public ConcurrentHashMap<String, Plugin> getLoadedPlugins() {
return plugins;
}
public ConcurrentHashMap<String,Plugin> getFailedPlugins() {
public ConcurrentHashMap<String, Plugin> getFailedPlugins() {
return failedPlugins;
}
@@ -855,7 +868,7 @@ public class Device implements BaseLink.PackageReceiver {
return pluginsWithoutPermissions;
}
public ConcurrentHashMap<String,Plugin> getPluginsWithoutOptionalPermissions() {
public ConcurrentHashMap<String, Plugin> getPluginsWithoutOptionalPermissions() {
return pluginsWithoutOptionalPermissions;
}
@@ -868,7 +881,7 @@ public class Device implements BaseLink.PackageReceiver {
}
public void disconnect() {
for(BaseLink link : links) {
for (BaseLink link : links) {
link.disconnect();
}
}
@@ -881,7 +894,7 @@ public class Device implements BaseLink.PackageReceiver {
return true; //Already paired
}
for(BaseLink l : links) {
for (BaseLink l : links) {
if (l.linkShouldBeKeptAlive()) {
return true;
}
@@ -893,10 +906,11 @@ public class Device implements BaseLink.PackageReceiver {
return m_supportedPlugins;
}
public void hackToMakeRetrocompatiblePacketTypes(NetworkPackage np) {
public void hackToMakeRetrocompatiblePacketTypes(NetworkPacket np) {
if (protocolVersion >= 6) return;
np.mType = np.getType().replace(".request","");
np.mType = np.getType().replace(".request", "");
}
public String hackToMakeRetrocompatiblePacketTypes(String type) {
if (protocolVersion >= 6) return type;
return type.replace(".request", "");

View File

@@ -40,7 +40,7 @@ public class AppsHelper {
} catch (final PackageManager.NameNotFoundException e) {
e.printStackTrace();
Log.e("AppsHelper","Could not resolve name "+packageName);
Log.e("AppsHelper", "Could not resolve name " + packageName);
return null;
@@ -53,13 +53,13 @@ public class AppsHelper {
try {
PackageManager pm = context.getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo( packageName, 0);
ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
return pm.getApplicationIcon(ai);
} catch (final PackageManager.NameNotFoundException e) {
e.printStackTrace();
Log.e("AppsHelper","Could not find icon for "+packageName);
Log.e("AppsHelper", "Could not find icon for " + packageName);
return null;
@@ -68,5 +68,4 @@ public class AppsHelper {
}
}

View File

@@ -51,7 +51,7 @@ public class ContactsHelper {
try {
cursor = context.getContentResolver().query(
uri,
new String[] {
new String[]{
PhoneLookup.DISPLAY_NAME,
ContactsContract.PhoneLookup.PHOTO_URI
/*, PhoneLookup.TYPE
@@ -75,7 +75,10 @@ public class ContactsHelper {
contactInfo.put("photoID", cursor.getString(nameIndex));
}
try { cursor.close(); } catch (Exception e) {}
try {
cursor.close();
} catch (Exception e) {
}
if (!contactInfo.isEmpty()) {
return contactInfo;
@@ -92,7 +95,7 @@ public class ContactsHelper {
Uri photoUri = Uri.parse(photoId);
InputStream input = null;
Base64OutputStream output= null;
Base64OutputStream output = null;
try {
ByteArrayOutputStream encodedPhoto = new ByteArrayOutputStream();
output = new Base64OutputStream(encodedPhoto, Base64.DEFAULT);
@@ -107,8 +110,16 @@ public class ContactsHelper {
Log.e("ContactsHelper", ex.toString());
return "";
} finally {
try { input.close(); } catch(Exception ignored) { };
try { output.close(); } catch(Exception ignored) { };
try {
input.close();
} catch (Exception ignored) {
}
try {
output.close();
} catch (Exception ignored) {
}
}
}
}

View File

@@ -29,6 +29,8 @@ import android.preference.PreferenceManager;
import android.provider.Settings;
import android.util.Log;
import org.kde.kdeconnect.Device;
import java.util.HashMap;
public class DeviceHelper {
@@ -38,412 +40,442 @@ public class DeviceHelper {
//from https://github.com/meetup/android-device-names
//Converted to java using:
//cat android_models.properties | awk -F'=' '{sub(/ *$/, "", $1)} sub(/^ */, "", $2) { if ($2 != "") print "humanReadableNames.put(\""$1"\",\"" $2 "\");"}' | sed -e 's/\\ /_/g'
private final static HashMap<String,String> humanReadableNames = new HashMap<>();
private final static HashMap<String, String> humanReadableNames = new HashMap<>();
static {
humanReadableNames.put("5860E","Coolpad Quattro 4G");
humanReadableNames.put("831C","HTC One M8");
humanReadableNames.put("9920","Star Alps S9920");
humanReadableNames.put("A0001","OnePlus One");
humanReadableNames.put("A1-810","Acer Iconia A1-810");
humanReadableNames.put("ADR6300","HTC Droid Incredible");
humanReadableNames.put("ADR6330VW","HTC Rhyme");
humanReadableNames.put("ADR6350","HTC Droid Incredible 2");
humanReadableNames.put("ADR6400L","HTC Thunderbolt");
humanReadableNames.put("ADR6410LVW","HTC Droid Incredible 4G");
humanReadableNames.put("ADR6425LVW","HTC Rezound 4G");
humanReadableNames.put("ALCATEL_ONE_TOUCH_5035X","Alcatel One Touch X Pop");
humanReadableNames.put("ALCATEL_ONE_TOUCH_7041X","Alcatel One Touch Pop C7");
humanReadableNames.put("ASUS_T00J","Asus ZenFone 5");
humanReadableNames.put("ASUS_Transformer_Pad_TF300T","Asus Transformer Pad");
humanReadableNames.put("ASUS_Transformer_Pad_TF700T","Asus Transformer Pad");
humanReadableNames.put("Aquaris_E4.5","bq Aquaris E4.5");
humanReadableNames.put("C1905","Sony Xperia M");
humanReadableNames.put("C2105","Sony Xperia L");
humanReadableNames.put("C5155","Kyocera Rise");
humanReadableNames.put("C5170","Kyocera Hydro");
humanReadableNames.put("C5302","Xperia SP");
humanReadableNames.put("C5303","Sony Xperia SP");
humanReadableNames.put("C5306","Xperia SP");
humanReadableNames.put("C6603","Sony Xperia Z");
humanReadableNames.put("C6606","Sony Xperia Z");
humanReadableNames.put("C6833","Sony Xperia Z Ultra");
humanReadableNames.put("C6903","Sony Xperia Z1");
humanReadableNames.put("C6916","Sony Xperia Z1S");
humanReadableNames.put("CM990","Huawei Evolution III");
humanReadableNames.put("CUBOT_ONE","Cubot One");
humanReadableNames.put("D2005","Sony Xperia E1");
humanReadableNames.put("D2302","Xperia M2");
humanReadableNames.put("D2303","Sony Xperia M2");
humanReadableNames.put("D2305","Xperia M2");
humanReadableNames.put("D2306","Xperia M2");
humanReadableNames.put("D2316","Xperia M2");
humanReadableNames.put("D5503","Sony Xperia Z1");
humanReadableNames.put("D5803","Sony Xperia Z3 Compact");
humanReadableNames.put("D5833","Xperia Z3 Compact");
humanReadableNames.put("D6503","Sony Xperia Z2");
humanReadableNames.put("D6603","Sony Xperia Z3");
humanReadableNames.put("D6653","Sony Xperia Z3");
humanReadableNames.put("DROID2","Motorola Droid 2");
humanReadableNames.put("DROID2_GLOBAL","Motorola Droid 2 Global");
humanReadableNames.put("DROID3","Motorola Droid 3");
humanReadableNames.put("DROID4","Motorola Droid 4");
humanReadableNames.put("DROIDX","Motorola Droid X");
humanReadableNames.put("DROID_BIONIC","Motorola Droid Bionic");
humanReadableNames.put("DROID_Pro","Motorola Droid Pro");
humanReadableNames.put("DROID_RAZR","Motorola Droid Razr");
humanReadableNames.put("DROID_RAZR_HD","Motorola Droid Razr HD");
humanReadableNames.put("DROID_X2","Motorola Droid X2");
humanReadableNames.put("Desire_HD","HTC Desire HD");
humanReadableNames.put("Droid","Motorola Droid");
humanReadableNames.put("EVO","HTC Evo");
humanReadableNames.put("GT-I8160","Samsung Galaxy Ace 2");
humanReadableNames.put("GT-I8190","Samsung Galaxy S III Mini");
humanReadableNames.put("GT-I8190L","Samsung Galaxy S3 Mini");
humanReadableNames.put("GT-I8190N","Samsung Galaxy S III Mini");
humanReadableNames.put("GT-I8260","Samsung Galaxy Core");
humanReadableNames.put("GT-I8262","Samsung Galaxy Core");
humanReadableNames.put("GT-I8550L","Samsung Galaxy Win");
humanReadableNames.put("GT-I9000","Samsung Galaxy S");
humanReadableNames.put("GT-I9001","Samsung Galaxy S Plus");
humanReadableNames.put("GT-I9060","Samsung Galaxy Grand Neo");
humanReadableNames.put("GT-I9063T","Samsung Galaxy Grand Neo Duos");
humanReadableNames.put("GT-I9070","Samsung Galaxy S Advance");
humanReadableNames.put("GT-I9082","Samsung Galaxy Grand");
humanReadableNames.put("GT-I9100","Samsung Galaxy S II");
humanReadableNames.put("GT-I9100M","Samsung Galaxy S II");
humanReadableNames.put("GT-I9100P","Samsung Galaxy S II");
humanReadableNames.put("GT-I9100T","Samsung Galaxy S II");
humanReadableNames.put("GT-I9105P","Samsung Galaxy S2 Plus");
humanReadableNames.put("GT-I9190","Samsung Galaxy S4 Mini");
humanReadableNames.put("GT-I9192","Samsung Galaxy S4 Mini Duos");
humanReadableNames.put("GT-I9195","Samsung Galaxy S4 Mini");
humanReadableNames.put("GT-I9197","Galaxy S4 Mini");
humanReadableNames.put("GT-I9198","Galaxy S4 Mini");
humanReadableNames.put("GT-I9210","Galaxy S2");
humanReadableNames.put("GT-I9295","Samsung Galaxy S4 Active");
humanReadableNames.put("GT-I9300","Samsung Galaxy S III");
humanReadableNames.put("GT-I9300T","Samsung Galaxy S III");
humanReadableNames.put("GT-I9305","Samsung Galaxy S III");
humanReadableNames.put("GT-I9305T","Samsung Galaxy S III");
humanReadableNames.put("GT-I9500","Samsung Galaxy S4");
humanReadableNames.put("GT-I9505","Samsung Galaxy S4");
humanReadableNames.put("GT-I9506","Samsung Galaxy S4");
humanReadableNames.put("GT-I9507","Samsung Galaxy S4");
humanReadableNames.put("GT-N5110","Samsung Galaxy Note 8.0");
humanReadableNames.put("GT-N7000","Samsung Galaxy Note");
humanReadableNames.put("GT-N7100","Samsung Galaxy Note II");
humanReadableNames.put("GT-N7105","Samsung Galaxy Note II");
humanReadableNames.put("GT-N7105T","Samsung Galaxy Note II");
humanReadableNames.put("GT-N8000","Samsung Galaxy Note 10.1");
humanReadableNames.put("GT-N8010","Samsung Galaxy Note 10.1");
humanReadableNames.put("GT-N8013","Samsung Galaxy Note 10.1");
humanReadableNames.put("GT-P3100","Samsung Galaxy Tab 2");
humanReadableNames.put("GT-P3110","Samsung Galaxy Tab 2");
humanReadableNames.put("GT-P3113","Samsung Galaxy Tab 2 7.0");
humanReadableNames.put("GT-P5110","Samsung Galaxy Tab 2");
humanReadableNames.put("GT-P5113","Samsnung Galaxy Tab 2 10.1");
humanReadableNames.put("GT-P5210","Samsung Galaxy Tab 3 10.1");
humanReadableNames.put("GT-P7510","Samsung Galaxy Tab 10.1");
humanReadableNames.put("GT-S5301L","Samsung Galaxy Pocket Plus");
humanReadableNames.put("GT-S5360","Samsung Galaxy Y");
humanReadableNames.put("GT-S5570","Samsung Galaxy Mini");
humanReadableNames.put("GT-S5830","Samsung Galaxy Ace");
humanReadableNames.put("GT-S5830i","Samsung Galaxy Ace");
humanReadableNames.put("GT-S6310","Samsung Galaxy Young");
humanReadableNames.put("GT-S6310N","Samsung Galaxy Young");
humanReadableNames.put("GT-S6810P","Samsung Galaxy Fame");
humanReadableNames.put("GT-S7560M","Samsung Galaxy Ace II X");
humanReadableNames.put("GT-S7562","Samsung Galaxy S Duos");
humanReadableNames.put("GT-S7580","Samsung Galaxy Trend Plus");
humanReadableNames.put("Galaxy_Nexus","Samsung Galaxy Nexus");
humanReadableNames.put("HM_1SW","Xiaomi Redmi");
humanReadableNames.put("HTC6435LVW","HTC Droid DNA");
humanReadableNames.put("HTC6500LVW","HTC One");
humanReadableNames.put("HTC6525LVW","HTC One M8");
humanReadableNames.put("HTCEVODesign4G","HTC Evo Design 4G");
humanReadableNames.put("HTCEVOV4G","HTC Evo V 4G");
humanReadableNames.put("HTCONE","HTC One");
humanReadableNames.put("HTC_Desire_500","HTC Desire 500");
humanReadableNames.put("HTC_Desire_HD_A9191","HTC Desire HD");
humanReadableNames.put("HTC_One_mini","HTC One mini");
humanReadableNames.put("HTC_PH39100","HTC Vivid 4G");
humanReadableNames.put("HTC_PN071","HTC One");
humanReadableNames.put("HTC_Sensation_Z710e","HTC Sensation");
humanReadableNames.put("HTC_Sensation_4G","HTC Sensation");
humanReadableNames.put("HTC_VLE_U","HTC One S");
humanReadableNames.put("HUAWEI_G510-0251","Huawei Ascend G510");
humanReadableNames.put("HUAWEI_P6-U06","Huawei Ascend P6");
humanReadableNames.put("HUAWEI_Y300-0100","Huawei Ascend Y300");
humanReadableNames.put("ISW11SC","Galaxy S2");
humanReadableNames.put("KFJWA","Kindle Fire HD 8.9");
humanReadableNames.put("KFJWI","Kindle Fire HD 8.9");
humanReadableNames.put("KFOT","Kindle Fire");
humanReadableNames.put("KFTT","Kindle Fire HD 7");
humanReadableNames.put("L-01F","G2");
humanReadableNames.put("LG-C800","LG myTouch Q");
humanReadableNames.put("LG-D415","LG Optimus L90");
humanReadableNames.put("LG-D620","LG G2 Mini");
humanReadableNames.put("LG-D686","LG G Pro Lite Dual");
humanReadableNames.put("LG-D800","LG G2");
humanReadableNames.put("LG-D801","LG G2");
humanReadableNames.put("LG-D802","LG G2");
humanReadableNames.put("LG-D803","G2");
humanReadableNames.put("LG-D805","G2");
humanReadableNames.put("LG-D850","LG G3");
humanReadableNames.put("LG-D851","LG G3");
humanReadableNames.put("LG-D852","G3");
humanReadableNames.put("LG-D855","LG G3");
humanReadableNames.put("LG-E411g","LG Optimus L1 II");
humanReadableNames.put("LG-E425g","LG Optimus L3 II");
humanReadableNames.put("LG-E440g","LG Optimus L4 II");
humanReadableNames.put("LG-E460","LG Optimus L5 II");
humanReadableNames.put("LG-E610","LG Optimus L5");
humanReadableNames.put("LG-E612g","LG Optimus L5 Dual");
humanReadableNames.put("LG-E739","LG MyTouch e739");
humanReadableNames.put("LG-E970","LG Optimus G");
humanReadableNames.put("LG-E971","Optimus G");
humanReadableNames.put("LG-E980","LG Optimus G Pro");
humanReadableNames.put("LG-H815","G4");
humanReadableNames.put("LG-LG730","LG Venice");
humanReadableNames.put("LG-LS720","LG Optimus F3");
humanReadableNames.put("LG-LS840","LG Viper");
humanReadableNames.put("LG-LS970","LG Optimus G");
humanReadableNames.put("LG-LS980","LG G2");
humanReadableNames.put("LG-MS770","LG Motion 4G");
humanReadableNames.put("LG-MS910","LG Esteem");
humanReadableNames.put("LG-P509","LG Optimus T");
humanReadableNames.put("LG-P760","LG Optimus L9");
humanReadableNames.put("LG-P768","LG Optimus L9");
humanReadableNames.put("LG-P769","LG Optimus L9");
humanReadableNames.put("LG-P999","LG G2X P999");
humanReadableNames.put("LG-VM696","LG Optimus Elite");
humanReadableNames.put("LGL34C","LG Optimus Fuel");
humanReadableNames.put("LGL55C","LG LGL55C");
humanReadableNames.put("LGLS740","LG Volt");
humanReadableNames.put("LGLS990","LG G3");
humanReadableNames.put("LGMS323","LG Optimus L70");
humanReadableNames.put("LGMS500","LG Optimus F6");
humanReadableNames.put("LGMS769","LG Optimus L9");
humanReadableNames.put("LS670","LG Optimus S");
humanReadableNames.put("LT22i","Sony Xperia P");
humanReadableNames.put("LT25i","Sony Xperia V");
humanReadableNames.put("LT26i","Sony Xperia S");
humanReadableNames.put("LT30p","Sony Xperia T");
humanReadableNames.put("MB855","Motorola Photon 4G");
humanReadableNames.put("MB860","Motorola Atrix 4G");
humanReadableNames.put("MB865","Motorola Atrix 2");
humanReadableNames.put("MB886","Motorola Atrix HD");
humanReadableNames.put("ME173X","Asus MeMO Pad HD 7");
humanReadableNames.put("MI_3W","Xiaomi Mi 3");
humanReadableNames.put("MOTWX435KT","Motorola Triumph");
humanReadableNames.put("N3","Star NO.1 N3");
humanReadableNames.put("N860","ZTE Warp N860");
humanReadableNames.put("NEXUS_4","Nexus 4");
humanReadableNames.put("NEXUS_5","Nexus 5");
humanReadableNames.put("NEXUS_5X","Nexus 5X");
humanReadableNames.put("LG-D820","Nexus 5");
humanReadableNames.put("LG-D821","Nexus 5");
humanReadableNames.put("NEXUS_6","Nexus 6");
humanReadableNames.put("NEXUS_6P","Nexus 6P");
humanReadableNames.put("Nexus_10","Google Nexus 10");
humanReadableNames.put("Nexus_4","Google Nexus 4");
humanReadableNames.put("Nexus_7","Asus Nexus 7");
humanReadableNames.put("Nexus_S","Samsung Nexus S");
humanReadableNames.put("Nexus_S_4G","Samsung Nexus S 4G");
humanReadableNames.put("Orange_Daytona","Huawei Ascend G510");
humanReadableNames.put("PC36100","HTC Evo 4G");
humanReadableNames.put("PG06100","HTC EVO Shift 4G");
humanReadableNames.put("PG86100","HTC Evo 3D");
humanReadableNames.put("PH44100","HTC Evo Design 4G");
humanReadableNames.put("PantechP9070","Pantech Burst");
humanReadableNames.put("QMV7A","Verizon Ellipsis 7");
humanReadableNames.put("SAMSUNG-SGH-I317","Samsung Galaxy Note II");
humanReadableNames.put("SAMSUNG-SGH-I337","Samsung Galaxy S4");
humanReadableNames.put("SAMSUNG-SGH-I527","Samsung Galaxy Mega");
humanReadableNames.put("SAMSUNG-SGH-I537","Samsung Galaxy S4 Active");
humanReadableNames.put("SAMSUNG-SGH-I717","Samsung Galaxy Note");
humanReadableNames.put("SAMSUNG-SGH-I727","Samsung Skyrocket");
humanReadableNames.put("SAMSUNG-SGH-I747","Samsung Galaxy S III");
humanReadableNames.put("SAMSUNG-SGH-I777","Samsung Galaxy S II");
humanReadableNames.put("SAMSUNG-SGH-I897","Samsung Captivate");
humanReadableNames.put("SAMSUNG-SGH-I927","Samsung Captivate Glide");
humanReadableNames.put("SAMSUNG-SGH-I997","Samsung Infuse 4G");
humanReadableNames.put("SAMSUNG-SM-G730A","Samsung Galaxy S3 Mini");
humanReadableNames.put("SAMSUNG-SM-G870A","Samsung Galaxy S5 Active");
humanReadableNames.put("SAMSUNG-SM-G900A","Samsung Galaxy S5");
humanReadableNames.put("SAMSUNG-SM-G920A","Samsung Galaxy S6");
humanReadableNames.put("SAMSUNG-SM-N900A","Samsung Galaxy Note 3");
humanReadableNames.put("SAMSUNG-SM-N910A","Samsung Galaxy Note 4");
humanReadableNames.put("SC-02C","Galaxy S2");
humanReadableNames.put("SC-03E","Galaxy S3");
humanReadableNames.put("SC-04E","Galaxy S4");
humanReadableNames.put("SC-06D","Galaxy S3");
humanReadableNames.put("SCH-I200","Samsung Galaxy Stellar");
humanReadableNames.put("SCH-I337","Galaxy S4");
humanReadableNames.put("SCH-I405","Samsung Stratosphere");
humanReadableNames.put("SCH-I415","Samsung Galaxy Stratosphere II");
humanReadableNames.put("SCH-I435","Samsung Galaxy S4 Mini");
humanReadableNames.put("SCH-I500","Samsung Fascinate");
humanReadableNames.put("SCH-I510","Samsung Droid Charge");
humanReadableNames.put("SCH-I535","Samsung Galaxy S III");
humanReadableNames.put("SCH-I545","Samsung Galaxy S4");
humanReadableNames.put("SCH-I605","Samsung Galaxy Note II");
humanReadableNames.put("SCH-I800","Samsung Galaxy Tab 7.0");
humanReadableNames.put("SCH-I939","Galaxy S3");
humanReadableNames.put("SCH-I959","Galaxy S4");
humanReadableNames.put("SCH-J021","Galaxy S3");
humanReadableNames.put("SCH-R530C","Samsung Galaxy S3");
humanReadableNames.put("SCH-R530M","Samsung Galaxy S III");
humanReadableNames.put("SCH-R530U","Samsung Galaxy S III");
humanReadableNames.put("SCH-R720","Samsung Admire");
humanReadableNames.put("SCH-R760","Galaxy S2");
humanReadableNames.put("SCH-R970","Samsung Galaxy S4");
humanReadableNames.put("SCH-S720C","Samsung Proclaim");
humanReadableNames.put("SCH-S738C","Samsung Galaxy Centura");
humanReadableNames.put("SCH-S968C","Samsung Galaxy S III");
humanReadableNames.put("SCL21","Galaxy S3");
humanReadableNames.put("SGH-I257M","Samsung Galaxy S4 Mini");
humanReadableNames.put("SGH-I317M","Samsung Galaxy Note II");
humanReadableNames.put("SGH-I337M","Samsung Galaxy S4");
humanReadableNames.put("SGH-I727R","Samsung Galaxy S II");
humanReadableNames.put("SGH-I747M","Samsung Galaxy S III");
humanReadableNames.put("SGH-I757M","Galaxy S2");
humanReadableNames.put("SGH-I777M","Galaxy S2");
humanReadableNames.put("SGH-M919","Samsung Galaxy S4");
humanReadableNames.put("SGH-M919N","Samsung Galaxy S4");
humanReadableNames.put("SGH-N035","Galaxy S3");
humanReadableNames.put("SGH-N045","Galaxy S4");
humanReadableNames.put("SGH-N064","Galaxy S3");
humanReadableNames.put("SGH-T399","Samsung Galaxy Light");
humanReadableNames.put("SGH-T399N","Samsung Galaxy Light");
humanReadableNames.put("SGH-T599N","Samsung Galaxy Exhibit");
humanReadableNames.put("SGH-T679","Samsung Exhibit II");
humanReadableNames.put("SGH-T769","Samsung Galaxy S Blaze");
humanReadableNames.put("SGH-T889","Samsung Galaxy Note II");
humanReadableNames.put("SGH-T959","Samsung Galaxy S Vibrant");
humanReadableNames.put("SGH-T959V","Samsung Galaxy S 4G");
humanReadableNames.put("SGH-T989","Samsung Galaxy S II");
humanReadableNames.put("SGH-T989D","Samsung Galaxy S II");
humanReadableNames.put("SGH-T999","Samsung Galaxy S III");
humanReadableNames.put("SGH-T999L","Samsung Galaxy S III");
humanReadableNames.put("SGH-T999V","Samsung Galaxy S III");
humanReadableNames.put("SGP312","Sony Xperia Tablet Z");
humanReadableNames.put("SHV-E210K","Samsung Galaxy S3");
humanReadableNames.put("SHV-E210S","Samsung Galaxy S III");
humanReadableNames.put("SHV-E250K","Samsung Galaxy Note 2");
humanReadableNames.put("SHV-E250S","Samsung Galaxy Note II");
humanReadableNames.put("SHV-E300","Galaxy S4");
humanReadableNames.put("SHW-M250","Galaxy S2");
humanReadableNames.put("SM-G3815","Samsung Galaxy Express II");
humanReadableNames.put("SM-G386T","Samsung Galaxy Avant");
humanReadableNames.put("SM-G386T1","Samsung Galaxy Avant");
humanReadableNames.put("SM-G7102","Samsung Galaxy Grand II");
humanReadableNames.put("SM-G800F","Samsung Galaxy S5 Mini");
humanReadableNames.put("SM-G860P","Samsung Galaxy S5 Sport");
humanReadableNames.put("SM-G900F","Samsung Galaxy S5");
humanReadableNames.put("SM-G900H","Samsung Galaxy S5");
humanReadableNames.put("SM-G900I","Samsung Galaxy S5");
humanReadableNames.put("SM-G900P","Samsung Galaxy S5");
humanReadableNames.put("SM-G900R4","Galaxy S5");
humanReadableNames.put("SM-G900RZWAUSC","Galaxy S5");
humanReadableNames.put("SM-G900T","Samsung Galaxy S5");
humanReadableNames.put("SM-G900V","Samsung Galaxy S5");
humanReadableNames.put("SM-G900W8","Samsung Galaxy S5");
humanReadableNames.put("SM-G9200","Galaxy S6");
humanReadableNames.put("SM-G920F","Galaxy S6");
humanReadableNames.put("SM-G920I","Galaxy S6");
humanReadableNames.put("SM-G920P","Samsung Galaxy S6");
humanReadableNames.put("SM-G920R","Galaxy S6");
humanReadableNames.put("SM-G920T","Samsung Galaxy S6");
humanReadableNames.put("SM-G920V","Samsung Galaxy S6");
humanReadableNames.put("SM-G920W8","Galaxy S6");
humanReadableNames.put("SM-G9250","Galaxy S6 Edge");
humanReadableNames.put("SM-G925A","Galaxy S6 Edge");
humanReadableNames.put("SM-G925F","Galaxy S6 Edge");
humanReadableNames.put("SM-G925P","Galaxy S6 Edge");
humanReadableNames.put("SM-G925R","Galaxy S6 Edge");
humanReadableNames.put("SM-G925T","Galaxy S6 Edge");
humanReadableNames.put("SM-G925V","Galaxy S6 Edge");
humanReadableNames.put("SM-G925W8","Galaxy S6 Edge");
humanReadableNames.put("SM-N7505","Samsung Galaxy Note 3 Neo");
humanReadableNames.put("SM-N900","Samsung Galaxy Note 3");
humanReadableNames.put("SM-N9005","Samsung Galaxy Note 3");
humanReadableNames.put("SM-N9006","Samsung Galaxy Note 3");
humanReadableNames.put("SM-N900P","Samsung Galaxy Note 3");
humanReadableNames.put("SM-N900T","Samsung Galaxy Note 3");
humanReadableNames.put("SM-N900V","Samsung Galaxy Note 3");
humanReadableNames.put("SM-N900W8","Samsung Galaxy Note 3");
humanReadableNames.put("SM-N910C","Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910F","Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910G","Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910P","Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910T","Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910V","Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910W8","Samsung Galaxy Note 4");
humanReadableNames.put("SM-P600","Samsung Galaxy Note 10.1");
humanReadableNames.put("SM-T210R","Samsung Galaxy Tab 3 7.0");
humanReadableNames.put("SM-T217S","Samsung Galaxy Tab 3 7.0");
humanReadableNames.put("SM-T230NU","Samsung Galaxy Tab 4");
humanReadableNames.put("SM-T310","Samsung Galaxy Tab 3 8.0");
humanReadableNames.put("SM-T530NU","Samsung Galaxy Tab 4 10.1");
humanReadableNames.put("SM-T800","Samsung Galaxy Tab S 10.5");
humanReadableNames.put("SPH-D600","Samsung Conquer 4G");
humanReadableNames.put("SPH-D700","Samsung Epic 4G");
humanReadableNames.put("SPH-D710","Samsung Epic");
humanReadableNames.put("SPH-D710BST","Samsung Galaxy S II");
humanReadableNames.put("SPH-D710VMUB","Samsung Galaxy S II");
humanReadableNames.put("SPH-L300","Samsung Galaxy Victory");
humanReadableNames.put("SPH-L520","Samsung Galaxy S4 Mini");
humanReadableNames.put("SPH-L710","Samsung Galaxy S III");
humanReadableNames.put("SPH-L710T","Samsung Galaxy S III");
humanReadableNames.put("SPH-L720","Samsung Galaxy S4");
humanReadableNames.put("SPH-L720T","Samsung Galaxy S4");
humanReadableNames.put("SPH-L900","Samsung Galaxy Note II");
humanReadableNames.put("SPH-M820-BST","Samsung Galaxy Prevail");
humanReadableNames.put("SPH-M830","Samsung Galaxy Rush");
humanReadableNames.put("SPH-M840","Samsung Galaxy Prevail 2");
humanReadableNames.put("SPH-M930BST","Samsung Transform Ultra");
humanReadableNames.put("ST21i","Sony Xperia Tipo");
humanReadableNames.put("ST25i","Sony Xperia U");
humanReadableNames.put("ST26i","Sony Xperia J");
humanReadableNames.put("Transformer_Prime_TF201","Asus Transformer Prime");
humanReadableNames.put("Transformer_TF101","Asus Transformer");
humanReadableNames.put("VM670","LG Optimus V");
humanReadableNames.put("VS840_4G","LG Lucid 4G");
humanReadableNames.put("VS870_4G","LG Lucid 2");
humanReadableNames.put("VS910_4G","LG Revolution 4G");
humanReadableNames.put("VS920_4G","LG Spectrum 4G");
humanReadableNames.put("VS930_4G","LG Spectrum 2");
humanReadableNames.put("VS980_4G","LG G2");
humanReadableNames.put("VS985_4G","LG G3 4G");
humanReadableNames.put("XT1022","Motorola Moto E");
humanReadableNames.put("XT1028","Motorola Moto G");
humanReadableNames.put("XT1030","Motorola Droid Mini");
humanReadableNames.put("XT1031","Motorola Moto G");
humanReadableNames.put("XT1032","Motorola Moto G");
humanReadableNames.put("XT1033","Motorola Moto G");
humanReadableNames.put("XT1034","Motorola Moto G");
humanReadableNames.put("XT1039","Motorola Moto G");
humanReadableNames.put("XT1045","Motorola Moto G");
humanReadableNames.put("XT1049","Motorola Moto X");
humanReadableNames.put("XT1053","Motorola Moto X");
humanReadableNames.put("XT1056","Motorola Moto X");
humanReadableNames.put("XT1058","Motorola Moto X");
humanReadableNames.put("XT1060","Motorola Moto X");
humanReadableNames.put("XT1068","Motorola Moto G");
humanReadableNames.put("XT1080","Motorola Droid Ultra");
humanReadableNames.put("XT1095","Motorola Moto X");
humanReadableNames.put("XT1096","Motorola Moto X");
humanReadableNames.put("XT1097","Motorola Moto X");
humanReadableNames.put("XT1254","Motorola Droid Turbo");
humanReadableNames.put("XT897","Motorola Photo Q");
humanReadableNames.put("XT907","Motorola Droid Razr M");
humanReadableNames.put("Xoom","Motorola Xoom");
humanReadableNames.put("Z970","ZTE ZMax");
humanReadableNames.put("bq_Aquaris_5","bq Aquaris 5");
humanReadableNames.put("bq_Aquaris_5_HD","bq Aquaris 5 HD");
humanReadableNames.put("google_sdk","Android Emulator");
humanReadableNames.put("myTouch_4G_Slide","HTC myTouch 4G Slide");
humanReadableNames.put("5860E", "Coolpad Quattro 4G");
humanReadableNames.put("831C", "HTC One M8");
humanReadableNames.put("9920", "Star Alps S9920");
humanReadableNames.put("A0001", "OnePlus One");
humanReadableNames.put("A1-810", "Acer Iconia A1-810");
humanReadableNames.put("ADR6300", "HTC Droid Incredible");
humanReadableNames.put("ADR6330VW", "HTC Rhyme");
humanReadableNames.put("ADR6350", "HTC Droid Incredible 2");
humanReadableNames.put("ADR6400L", "HTC Thunderbolt");
humanReadableNames.put("ADR6410LVW", "HTC Droid Incredible 4G");
humanReadableNames.put("ADR6425LVW", "HTC Rezound 4G");
humanReadableNames.put("ALCATEL_ONE_TOUCH_5035X", "Alcatel One Touch X Pop");
humanReadableNames.put("ALCATEL_ONE_TOUCH_7041X", "Alcatel One Touch Pop C7");
humanReadableNames.put("ASUS_T00J", "Asus ZenFone 5");
humanReadableNames.put("ASUS_Transformer_Pad_TF300T", "Asus Transformer Pad");
humanReadableNames.put("ASUS_Transformer_Pad_TF700T", "Asus Transformer Pad");
humanReadableNames.put("Aquaris_E4.5", "bq Aquaris E4.5");
humanReadableNames.put("C1905", "Sony Xperia M");
humanReadableNames.put("C2105", "Sony Xperia L");
humanReadableNames.put("C5155", "Kyocera Rise");
humanReadableNames.put("C5170", "Kyocera Hydro");
humanReadableNames.put("C5302", "Xperia SP");
humanReadableNames.put("C5303", "Sony Xperia SP");
humanReadableNames.put("C5306", "Xperia SP");
humanReadableNames.put("C6603", "Sony Xperia Z");
humanReadableNames.put("C6606", "Sony Xperia Z");
humanReadableNames.put("C6833", "Sony Xperia Z Ultra");
humanReadableNames.put("C6903", "Sony Xperia Z1");
humanReadableNames.put("C6916", "Sony Xperia Z1S");
humanReadableNames.put("CM990", "Huawei Evolution III");
humanReadableNames.put("CUBOT_ONE", "Cubot One");
humanReadableNames.put("D2005", "Sony Xperia E1");
humanReadableNames.put("D2302", "Xperia M2");
humanReadableNames.put("D2303", "Sony Xperia M2");
humanReadableNames.put("D2305", "Xperia M2");
humanReadableNames.put("D2306", "Xperia M2");
humanReadableNames.put("D2316", "Xperia M2");
humanReadableNames.put("D5503", "Sony Xperia Z1");
humanReadableNames.put("D5803", "Sony Xperia Z3 Compact");
humanReadableNames.put("D5833", "Xperia Z3 Compact");
humanReadableNames.put("D6503", "Sony Xperia Z2");
humanReadableNames.put("D6603", "Sony Xperia Z3");
humanReadableNames.put("D6653", "Sony Xperia Z3");
humanReadableNames.put("DROID2", "Motorola Droid 2");
humanReadableNames.put("DROID2_GLOBAL", "Motorola Droid 2 Global");
humanReadableNames.put("DROID3", "Motorola Droid 3");
humanReadableNames.put("DROID4", "Motorola Droid 4");
humanReadableNames.put("DROIDX", "Motorola Droid X");
humanReadableNames.put("DROID_BIONIC", "Motorola Droid Bionic");
humanReadableNames.put("DROID_Pro", "Motorola Droid Pro");
humanReadableNames.put("DROID_RAZR", "Motorola Droid Razr");
humanReadableNames.put("DROID_RAZR_HD", "Motorola Droid Razr HD");
humanReadableNames.put("DROID_X2", "Motorola Droid X2");
humanReadableNames.put("Desire_HD", "HTC Desire HD");
humanReadableNames.put("Droid", "Motorola Droid");
humanReadableNames.put("EVO", "HTC Evo");
humanReadableNames.put("GT-I8160", "Samsung Galaxy Ace 2");
humanReadableNames.put("GT-I8190", "Samsung Galaxy S III Mini");
humanReadableNames.put("GT-I8190L", "Samsung Galaxy S3 Mini");
humanReadableNames.put("GT-I8190N", "Samsung Galaxy S III Mini");
humanReadableNames.put("GT-I8260", "Samsung Galaxy Core");
humanReadableNames.put("GT-I8262", "Samsung Galaxy Core");
humanReadableNames.put("GT-I8550L", "Samsung Galaxy Win");
humanReadableNames.put("GT-I9000", "Samsung Galaxy S");
humanReadableNames.put("GT-I9001", "Samsung Galaxy S Plus");
humanReadableNames.put("GT-I9060", "Samsung Galaxy Grand Neo");
humanReadableNames.put("GT-I9063T", "Samsung Galaxy Grand Neo Duos");
humanReadableNames.put("GT-I9070", "Samsung Galaxy S Advance");
humanReadableNames.put("GT-I9082", "Samsung Galaxy Grand");
humanReadableNames.put("GT-I9100", "Samsung Galaxy S II");
humanReadableNames.put("GT-I9100M", "Samsung Galaxy S II");
humanReadableNames.put("GT-I9100P", "Samsung Galaxy S II");
humanReadableNames.put("GT-I9100T", "Samsung Galaxy S II");
humanReadableNames.put("GT-I9105P", "Samsung Galaxy S2 Plus");
humanReadableNames.put("GT-I9190", "Samsung Galaxy S4 Mini");
humanReadableNames.put("GT-I9192", "Samsung Galaxy S4 Mini Duos");
humanReadableNames.put("GT-I9195", "Samsung Galaxy S4 Mini");
humanReadableNames.put("GT-I9197", "Galaxy S4 Mini");
humanReadableNames.put("GT-I9198", "Galaxy S4 Mini");
humanReadableNames.put("GT-I9210", "Galaxy S2");
humanReadableNames.put("GT-I9295", "Samsung Galaxy S4 Active");
humanReadableNames.put("GT-I9300", "Samsung Galaxy S III");
humanReadableNames.put("GT-I9300T", "Samsung Galaxy S III");
humanReadableNames.put("GT-I9305", "Samsung Galaxy S III");
humanReadableNames.put("GT-I9305T", "Samsung Galaxy S III");
humanReadableNames.put("GT-I9500", "Samsung Galaxy S4");
humanReadableNames.put("GT-I9505", "Samsung Galaxy S4");
humanReadableNames.put("GT-I9506", "Samsung Galaxy S4");
humanReadableNames.put("GT-I9507", "Samsung Galaxy S4");
humanReadableNames.put("GT-N5110", "Samsung Galaxy Note 8.0");
humanReadableNames.put("GT-N7000", "Samsung Galaxy Note");
humanReadableNames.put("GT-N7100", "Samsung Galaxy Note II");
humanReadableNames.put("GT-N7105", "Samsung Galaxy Note II");
humanReadableNames.put("GT-N7105T", "Samsung Galaxy Note II");
humanReadableNames.put("GT-N8000", "Samsung Galaxy Note 10.1");
humanReadableNames.put("GT-N8010", "Samsung Galaxy Note 10.1");
humanReadableNames.put("GT-N8013", "Samsung Galaxy Note 10.1");
humanReadableNames.put("GT-P3100", "Samsung Galaxy Tab 2");
humanReadableNames.put("GT-P3110", "Samsung Galaxy Tab 2");
humanReadableNames.put("GT-P3113", "Samsung Galaxy Tab 2 7.0");
humanReadableNames.put("GT-P5110", "Samsung Galaxy Tab 2");
humanReadableNames.put("GT-P5113", "Samsnung Galaxy Tab 2 10.1");
humanReadableNames.put("GT-P5210", "Samsung Galaxy Tab 3 10.1");
humanReadableNames.put("GT-P7510", "Samsung Galaxy Tab 10.1");
humanReadableNames.put("GT-S5301L", "Samsung Galaxy Pocket Plus");
humanReadableNames.put("GT-S5360", "Samsung Galaxy Y");
humanReadableNames.put("GT-S5570", "Samsung Galaxy Mini");
humanReadableNames.put("GT-S5830", "Samsung Galaxy Ace");
humanReadableNames.put("GT-S5830i", "Samsung Galaxy Ace");
humanReadableNames.put("GT-S6310", "Samsung Galaxy Young");
humanReadableNames.put("GT-S6310N", "Samsung Galaxy Young");
humanReadableNames.put("GT-S6810P", "Samsung Galaxy Fame");
humanReadableNames.put("GT-S7560M", "Samsung Galaxy Ace II X");
humanReadableNames.put("GT-S7562", "Samsung Galaxy S Duos");
humanReadableNames.put("GT-S7580", "Samsung Galaxy Trend Plus");
humanReadableNames.put("Galaxy_Nexus", "Samsung Galaxy Nexus");
humanReadableNames.put("HM_1SW", "Xiaomi Redmi");
humanReadableNames.put("HTC6435LVW", "HTC Droid DNA");
humanReadableNames.put("HTC6500LVW", "HTC One");
humanReadableNames.put("HTC6525LVW", "HTC One M8");
humanReadableNames.put("HTCEVODesign4G", "HTC Evo Design 4G");
humanReadableNames.put("HTCEVOV4G", "HTC Evo V 4G");
humanReadableNames.put("HTCONE", "HTC One");
humanReadableNames.put("HTC_Desire_500", "HTC Desire 500");
humanReadableNames.put("HTC_Desire_HD_A9191", "HTC Desire HD");
humanReadableNames.put("HTC_One_mini", "HTC One mini");
humanReadableNames.put("HTC_PH39100", "HTC Vivid 4G");
humanReadableNames.put("HTC_PN071", "HTC One");
humanReadableNames.put("HTC_Sensation_Z710e", "HTC Sensation");
humanReadableNames.put("HTC_Sensation_4G", "HTC Sensation");
humanReadableNames.put("HTC_VLE_U", "HTC One S");
humanReadableNames.put("HUAWEI_G510-0251", "Huawei Ascend G510");
humanReadableNames.put("HUAWEI_P6-U06", "Huawei Ascend P6");
humanReadableNames.put("HUAWEI_Y300-0100", "Huawei Ascend Y300");
humanReadableNames.put("ISW11SC", "Galaxy S2");
humanReadableNames.put("KFJWA", "Kindle Fire HD 8.9");
humanReadableNames.put("KFJWI", "Kindle Fire HD 8.9");
humanReadableNames.put("KFOT", "Kindle Fire");
humanReadableNames.put("KFTT", "Kindle Fire HD 7");
humanReadableNames.put("L-01F", "G2");
humanReadableNames.put("LG-C800", "LG myTouch Q");
humanReadableNames.put("LG-D415", "LG Optimus L90");
humanReadableNames.put("LG-D620", "LG G2 Mini");
humanReadableNames.put("LG-D686", "LG G Pro Lite Dual");
humanReadableNames.put("LG-D800", "LG G2");
humanReadableNames.put("LG-D801", "LG G2");
humanReadableNames.put("LG-D802", "LG G2");
humanReadableNames.put("LG-D803", "G2");
humanReadableNames.put("LG-D805", "G2");
humanReadableNames.put("LG-D850", "LG G3");
humanReadableNames.put("LG-D851", "LG G3");
humanReadableNames.put("LG-D852", "G3");
humanReadableNames.put("LG-D855", "LG G3");
humanReadableNames.put("LG-E411g", "LG Optimus L1 II");
humanReadableNames.put("LG-E425g", "LG Optimus L3 II");
humanReadableNames.put("LG-E440g", "LG Optimus L4 II");
humanReadableNames.put("LG-E460", "LG Optimus L5 II");
humanReadableNames.put("LG-E610", "LG Optimus L5");
humanReadableNames.put("LG-E612g", "LG Optimus L5 Dual");
humanReadableNames.put("LG-E739", "LG MyTouch e739");
humanReadableNames.put("LG-E970", "LG Optimus G");
humanReadableNames.put("LG-E971", "Optimus G");
humanReadableNames.put("LG-E980", "LG Optimus G Pro");
humanReadableNames.put("LG-H815", "G4");
humanReadableNames.put("LG-LG730", "LG Venice");
humanReadableNames.put("LG-LS720", "LG Optimus F3");
humanReadableNames.put("LG-LS840", "LG Viper");
humanReadableNames.put("LG-LS970", "LG Optimus G");
humanReadableNames.put("LG-LS980", "LG G2");
humanReadableNames.put("LG-MS770", "LG Motion 4G");
humanReadableNames.put("LG-MS910", "LG Esteem");
humanReadableNames.put("LG-P509", "LG Optimus T");
humanReadableNames.put("LG-P760", "LG Optimus L9");
humanReadableNames.put("LG-P768", "LG Optimus L9");
humanReadableNames.put("LG-P769", "LG Optimus L9");
humanReadableNames.put("LG-P999", "LG G2X P999");
humanReadableNames.put("LG-VM696", "LG Optimus Elite");
humanReadableNames.put("LGL34C", "LG Optimus Fuel");
humanReadableNames.put("LGL55C", "LG LGL55C");
humanReadableNames.put("LGLS740", "LG Volt");
humanReadableNames.put("LGLS990", "LG G3");
humanReadableNames.put("LGMS323", "LG Optimus L70");
humanReadableNames.put("LGMS500", "LG Optimus F6");
humanReadableNames.put("LGMS769", "LG Optimus L9");
humanReadableNames.put("LS670", "LG Optimus S");
humanReadableNames.put("LT22i", "Sony Xperia P");
humanReadableNames.put("LT25i", "Sony Xperia V");
humanReadableNames.put("LT26i", "Sony Xperia S");
humanReadableNames.put("LT30p", "Sony Xperia T");
humanReadableNames.put("MB855", "Motorola Photon 4G");
humanReadableNames.put("MB860", "Motorola Atrix 4G");
humanReadableNames.put("MB865", "Motorola Atrix 2");
humanReadableNames.put("MB886", "Motorola Atrix HD");
humanReadableNames.put("ME173X", "Asus MeMO Pad HD 7");
humanReadableNames.put("MI_3W", "Xiaomi Mi 3");
humanReadableNames.put("MOTWX435KT", "Motorola Triumph");
humanReadableNames.put("N3", "Star NO.1 N3");
humanReadableNames.put("N860", "ZTE Warp N860");
humanReadableNames.put("NEXUS_4", "Nexus 4");
humanReadableNames.put("NEXUS_5", "Nexus 5");
humanReadableNames.put("NEXUS_5X", "Nexus 5X");
humanReadableNames.put("LG-D820", "Nexus 5");
humanReadableNames.put("LG-D821", "Nexus 5");
humanReadableNames.put("NEXUS_6", "Nexus 6");
humanReadableNames.put("NEXUS_6P", "Nexus 6P");
humanReadableNames.put("Nexus_10", "Google Nexus 10");
humanReadableNames.put("Nexus_4", "Google Nexus 4");
humanReadableNames.put("Nexus_7", "Asus Nexus 7");
humanReadableNames.put("Nexus_S", "Samsung Nexus S");
humanReadableNames.put("Nexus_S_4G", "Samsung Nexus S 4G");
humanReadableNames.put("Orange_Daytona", "Huawei Ascend G510");
humanReadableNames.put("PC36100", "HTC Evo 4G");
humanReadableNames.put("PG06100", "HTC EVO Shift 4G");
humanReadableNames.put("PG86100", "HTC Evo 3D");
humanReadableNames.put("PH44100", "HTC Evo Design 4G");
humanReadableNames.put("PantechP9070", "Pantech Burst");
humanReadableNames.put("QMV7A", "Verizon Ellipsis 7");
humanReadableNames.put("SAMSUNG-SGH-I317", "Samsung Galaxy Note II");
humanReadableNames.put("SAMSUNG-SGH-I337", "Samsung Galaxy S4");
humanReadableNames.put("SAMSUNG-SGH-I527", "Samsung Galaxy Mega");
humanReadableNames.put("SAMSUNG-SGH-I537", "Samsung Galaxy S4 Active");
humanReadableNames.put("SAMSUNG-SGH-I717", "Samsung Galaxy Note");
humanReadableNames.put("SAMSUNG-SGH-I727", "Samsung Skyrocket");
humanReadableNames.put("SAMSUNG-SGH-I747", "Samsung Galaxy S III");
humanReadableNames.put("SAMSUNG-SGH-I777", "Samsung Galaxy S II");
humanReadableNames.put("SAMSUNG-SGH-I897", "Samsung Captivate");
humanReadableNames.put("SAMSUNG-SGH-I927", "Samsung Captivate Glide");
humanReadableNames.put("SAMSUNG-SGH-I997", "Samsung Infuse 4G");
humanReadableNames.put("SAMSUNG-SM-G730A", "Samsung Galaxy S3 Mini");
humanReadableNames.put("SAMSUNG-SM-G870A", "Samsung Galaxy S5 Active");
humanReadableNames.put("SAMSUNG-SM-G900A", "Samsung Galaxy S5");
humanReadableNames.put("SAMSUNG-SM-G920A", "Samsung Galaxy S6");
humanReadableNames.put("SAMSUNG-SM-N900A", "Samsung Galaxy Note 3");
humanReadableNames.put("SAMSUNG-SM-N910A", "Samsung Galaxy Note 4");
humanReadableNames.put("SC-02C", "Galaxy S2");
humanReadableNames.put("SC-03E", "Galaxy S3");
humanReadableNames.put("SC-04E", "Galaxy S4");
humanReadableNames.put("SC-06D", "Galaxy S3");
humanReadableNames.put("SCH-I200", "Samsung Galaxy Stellar");
humanReadableNames.put("SCH-I337", "Galaxy S4");
humanReadableNames.put("SCH-I405", "Samsung Stratosphere");
humanReadableNames.put("SCH-I415", "Samsung Galaxy Stratosphere II");
humanReadableNames.put("SCH-I435", "Samsung Galaxy S4 Mini");
humanReadableNames.put("SCH-I500", "Samsung Fascinate");
humanReadableNames.put("SCH-I510", "Samsung Droid Charge");
humanReadableNames.put("SCH-I535", "Samsung Galaxy S III");
humanReadableNames.put("SCH-I545", "Samsung Galaxy S4");
humanReadableNames.put("SCH-I605", "Samsung Galaxy Note II");
humanReadableNames.put("SCH-I800", "Samsung Galaxy Tab 7.0");
humanReadableNames.put("SCH-I939", "Galaxy S3");
humanReadableNames.put("SCH-I959", "Galaxy S4");
humanReadableNames.put("SCH-J021", "Galaxy S3");
humanReadableNames.put("SCH-R530C", "Samsung Galaxy S3");
humanReadableNames.put("SCH-R530M", "Samsung Galaxy S III");
humanReadableNames.put("SCH-R530U", "Samsung Galaxy S III");
humanReadableNames.put("SCH-R720", "Samsung Admire");
humanReadableNames.put("SCH-R760", "Galaxy S2");
humanReadableNames.put("SCH-R970", "Samsung Galaxy S4");
humanReadableNames.put("SCH-S720C", "Samsung Proclaim");
humanReadableNames.put("SCH-S738C", "Samsung Galaxy Centura");
humanReadableNames.put("SCH-S968C", "Samsung Galaxy S III");
humanReadableNames.put("SCL21", "Galaxy S3");
humanReadableNames.put("SGH-I257M", "Samsung Galaxy S4 Mini");
humanReadableNames.put("SGH-I317M", "Samsung Galaxy Note II");
humanReadableNames.put("SGH-I337M", "Samsung Galaxy S4");
humanReadableNames.put("SGH-I727R", "Samsung Galaxy S II");
humanReadableNames.put("SGH-I747M", "Samsung Galaxy S III");
humanReadableNames.put("SGH-I757M", "Galaxy S2");
humanReadableNames.put("SGH-I777M", "Galaxy S2");
humanReadableNames.put("SGH-M919", "Samsung Galaxy S4");
humanReadableNames.put("SGH-M919N", "Samsung Galaxy S4");
humanReadableNames.put("SGH-N035", "Galaxy S3");
humanReadableNames.put("SGH-N045", "Galaxy S4");
humanReadableNames.put("SGH-N064", "Galaxy S3");
humanReadableNames.put("SGH-T399", "Samsung Galaxy Light");
humanReadableNames.put("SGH-T399N", "Samsung Galaxy Light");
humanReadableNames.put("SGH-T599N", "Samsung Galaxy Exhibit");
humanReadableNames.put("SGH-T679", "Samsung Exhibit II");
humanReadableNames.put("SGH-T769", "Samsung Galaxy S Blaze");
humanReadableNames.put("SGH-T889", "Samsung Galaxy Note II");
humanReadableNames.put("SGH-T959", "Samsung Galaxy S Vibrant");
humanReadableNames.put("SGH-T959V", "Samsung Galaxy S 4G");
humanReadableNames.put("SGH-T989", "Samsung Galaxy S II");
humanReadableNames.put("SGH-T989D", "Samsung Galaxy S II");
humanReadableNames.put("SGH-T999", "Samsung Galaxy S III");
humanReadableNames.put("SGH-T999L", "Samsung Galaxy S III");
humanReadableNames.put("SGH-T999V", "Samsung Galaxy S III");
humanReadableNames.put("SGP312", "Sony Xperia Tablet Z");
humanReadableNames.put("SHV-E210K", "Samsung Galaxy S3");
humanReadableNames.put("SHV-E210S", "Samsung Galaxy S III");
humanReadableNames.put("SHV-E250K", "Samsung Galaxy Note 2");
humanReadableNames.put("SHV-E250S", "Samsung Galaxy Note II");
humanReadableNames.put("SHV-E300", "Galaxy S4");
humanReadableNames.put("SHW-M250", "Galaxy S2");
humanReadableNames.put("SM-G3815", "Samsung Galaxy Express II");
humanReadableNames.put("SM-G386T", "Samsung Galaxy Avant");
humanReadableNames.put("SM-G386T1", "Samsung Galaxy Avant");
humanReadableNames.put("SM-G388F", "Samsung Galaxy Xcover 3");
humanReadableNames.put("SM-G7102", "Samsung Galaxy Grand II");
humanReadableNames.put("SM-G800F", "Samsung Galaxy S5 Mini");
humanReadableNames.put("SM-G860P", "Samsung Galaxy S5 Sport");
humanReadableNames.put("SM-G900F", "Samsung Galaxy S5");
humanReadableNames.put("SM-G900H", "Samsung Galaxy S5");
humanReadableNames.put("SM-G900I", "Samsung Galaxy S5");
humanReadableNames.put("SM-G900P", "Samsung Galaxy S5");
humanReadableNames.put("SM-G900R4", "Galaxy S5");
humanReadableNames.put("SM-G900RZWAUSC", "Galaxy S5");
humanReadableNames.put("SM-G900T", "Samsung Galaxy S5");
humanReadableNames.put("SM-G900V", "Samsung Galaxy S5");
humanReadableNames.put("SM-G900W8", "Samsung Galaxy S5");
humanReadableNames.put("SM-G9200", "Galaxy S6");
humanReadableNames.put("SM-G920F", "Galaxy S6");
humanReadableNames.put("SM-G920I", "Galaxy S6");
humanReadableNames.put("SM-G920P", "Samsung Galaxy S6");
humanReadableNames.put("SM-G920R", "Galaxy S6");
humanReadableNames.put("SM-G920T", "Samsung Galaxy S6");
humanReadableNames.put("SM-G920V", "Samsung Galaxy S6");
humanReadableNames.put("SM-G920W8", "Galaxy S6");
humanReadableNames.put("SM-G9250", "Galaxy S6 Edge");
humanReadableNames.put("SM-G925A", "Galaxy S6 Edge");
humanReadableNames.put("SM-G925F", "Galaxy S6 Edge");
humanReadableNames.put("SM-G925P", "Galaxy S6 Edge");
humanReadableNames.put("SM-G925R", "Galaxy S6 Edge");
humanReadableNames.put("SM-G925T", "Galaxy S6 Edge");
humanReadableNames.put("SM-G925V", "Galaxy S6 Edge");
humanReadableNames.put("SM-G925W8", "Galaxy S6 Edge");
humanReadableNames.put("SM-G9500", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950F", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950T", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950S", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950K", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950L", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950P", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950A", "Samsung Galaxy S8");
humanReadableNames.put("SM-G9509", "Samsung Galaxy S8");
humanReadableNames.put("SM-G9508", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950R4", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950V", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950FD", "Samsung Galaxy S8");
humanReadableNames.put("SM-G950W8", "Samsung Galaxy S8");
humanReadableNames.put("SM-G9550", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955F", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955T", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955S", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955K", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955L", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955P", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955A", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G9559", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G9558", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955R4", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955V", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955FD", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-G955W8", "Samsung Galaxy S8 Plus");
humanReadableNames.put("SM-N7505", "Samsung Galaxy Note 3 Neo");
humanReadableNames.put("SM-N900", "Samsung Galaxy Note 3");
humanReadableNames.put("SM-N9005", "Samsung Galaxy Note 3");
humanReadableNames.put("SM-N9006", "Samsung Galaxy Note 3");
humanReadableNames.put("SM-N900P", "Samsung Galaxy Note 3");
humanReadableNames.put("SM-N900T", "Samsung Galaxy Note 3");
humanReadableNames.put("SM-N900V", "Samsung Galaxy Note 3");
humanReadableNames.put("SM-N900W8", "Samsung Galaxy Note 3");
humanReadableNames.put("SM-N910C", "Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910F", "Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910G", "Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910P", "Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910T", "Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910V", "Samsung Galaxy Note 4");
humanReadableNames.put("SM-N910W8", "Samsung Galaxy Note 4");
humanReadableNames.put("SM-P600", "Samsung Galaxy Note 10.1");
humanReadableNames.put("SM-T210R", "Samsung Galaxy Tab 3 7.0");
humanReadableNames.put("SM-T217S", "Samsung Galaxy Tab 3 7.0");
humanReadableNames.put("SM-T230NU", "Samsung Galaxy Tab 4");
humanReadableNames.put("SM-T310", "Samsung Galaxy Tab 3 8.0");
humanReadableNames.put("SM-T530NU", "Samsung Galaxy Tab 4 10.1");
humanReadableNames.put("SM-T800", "Samsung Galaxy Tab S 10.5");
humanReadableNames.put("SPH-D600", "Samsung Conquer 4G");
humanReadableNames.put("SPH-D700", "Samsung Epic 4G");
humanReadableNames.put("SPH-D710", "Samsung Epic");
humanReadableNames.put("SPH-D710BST", "Samsung Galaxy S II");
humanReadableNames.put("SPH-D710VMUB", "Samsung Galaxy S II");
humanReadableNames.put("SPH-L300", "Samsung Galaxy Victory");
humanReadableNames.put("SPH-L520", "Samsung Galaxy S4 Mini");
humanReadableNames.put("SPH-L710", "Samsung Galaxy S III");
humanReadableNames.put("SPH-L710T", "Samsung Galaxy S III");
humanReadableNames.put("SPH-L720", "Samsung Galaxy S4");
humanReadableNames.put("SPH-L720T", "Samsung Galaxy S4");
humanReadableNames.put("SPH-L900", "Samsung Galaxy Note II");
humanReadableNames.put("SPH-M820-BST", "Samsung Galaxy Prevail");
humanReadableNames.put("SPH-M830", "Samsung Galaxy Rush");
humanReadableNames.put("SPH-M840", "Samsung Galaxy Prevail 2");
humanReadableNames.put("SPH-M930BST", "Samsung Transform Ultra");
humanReadableNames.put("ST21i", "Sony Xperia Tipo");
humanReadableNames.put("ST25i", "Sony Xperia U");
humanReadableNames.put("ST26i", "Sony Xperia J");
humanReadableNames.put("Transformer_Prime_TF201", "Asus Transformer Prime");
humanReadableNames.put("Transformer_TF101", "Asus Transformer");
humanReadableNames.put("VM670", "LG Optimus V");
humanReadableNames.put("VS840_4G", "LG Lucid 4G");
humanReadableNames.put("VS870_4G", "LG Lucid 2");
humanReadableNames.put("VS910_4G", "LG Revolution 4G");
humanReadableNames.put("VS920_4G", "LG Spectrum 4G");
humanReadableNames.put("VS930_4G", "LG Spectrum 2");
humanReadableNames.put("VS980_4G", "LG G2");
humanReadableNames.put("VS985_4G", "LG G3 4G");
humanReadableNames.put("XT1022", "Motorola Moto E");
humanReadableNames.put("XT1028", "Motorola Moto G");
humanReadableNames.put("XT1030", "Motorola Droid Mini");
humanReadableNames.put("XT1031", "Motorola Moto G");
humanReadableNames.put("XT1032", "Motorola Moto G");
humanReadableNames.put("XT1033", "Motorola Moto G");
humanReadableNames.put("XT1034", "Motorola Moto G");
humanReadableNames.put("XT1039", "Motorola Moto G");
humanReadableNames.put("XT1045", "Motorola Moto G");
humanReadableNames.put("XT1049", "Motorola Moto X");
humanReadableNames.put("XT1053", "Motorola Moto X");
humanReadableNames.put("XT1056", "Motorola Moto X");
humanReadableNames.put("XT1058", "Motorola Moto X");
humanReadableNames.put("XT1060", "Motorola Moto X");
humanReadableNames.put("XT1068", "Motorola Moto G");
humanReadableNames.put("XT1080", "Motorola Droid Ultra");
humanReadableNames.put("XT1095", "Motorola Moto X");
humanReadableNames.put("XT1096", "Motorola Moto X");
humanReadableNames.put("XT1097", "Motorola Moto X");
humanReadableNames.put("XT1254", "Motorola Droid Turbo");
humanReadableNames.put("XT897", "Motorola Photo Q");
humanReadableNames.put("XT907", "Motorola Droid Razr M");
humanReadableNames.put("Xoom", "Motorola Xoom");
humanReadableNames.put("Z970", "ZTE ZMax");
humanReadableNames.put("bq_Aquaris_5", "bq Aquaris 5");
humanReadableNames.put("bq_Aquaris_5_HD", "bq Aquaris 5 HD");
humanReadableNames.put("google_sdk", "Android Emulator");
humanReadableNames.put("myTouch_4G_Slide", "HTC myTouch 4G Slide");
}
@@ -474,19 +506,33 @@ public class DeviceHelper {
}
}
public static boolean isTablet() {
private 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;
return ((config.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE);
}
private static boolean isTv(Context context) {
int uiMode = context.getResources().getConfiguration().uiMode;
return (uiMode & Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION;
}
public static Device.DeviceType getDeviceType(Context context) {
if (isTv(context)) {
return Device.DeviceType.Tv;
} else if (isTablet()) {
return Device.DeviceType.Tablet;
} else {
return Device.DeviceType.Phone;
}
}
//It returns getAndroidDeviceName() if no user-defined name has been set with setDeviceName().
public static String getDeviceName(Context context){
public static String getDeviceName(Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
// Could use prefrences.contains but would need to check for empty String anyway.
String deviceName = preferences.getString(KEY_DEVICE_NAME_PREFERENCE, "");
if (deviceName.isEmpty()){
if (deviceName.isEmpty()) {
deviceName = DeviceHelper.getAndroidDeviceName();
Log.i("MainSettingsActivity", "New device name: " + deviceName);
preferences.edit().putString(KEY_DEVICE_NAME_PREFERENCE, deviceName).apply();
@@ -494,7 +540,7 @@ public class DeviceHelper {
return deviceName;
}
public static void setDeviceName(Context context, String name){
public static void setDeviceName(Context context, String name) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
preferences.edit().putString(KEY_DEVICE_NAME_PREFERENCE, name).apply();
}

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