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

Merge branch 'master' into 1.x

# Conflicts:
#	AndroidManifest.xml
#	res/values-es/strings.xml
#	res/values-fr/strings.xml
#	res/values-ru/strings.xml
#	res/values-sr/strings.xml
#	src/org/kde/kdeconnect/Helpers/NetworkHelper.java
#	src/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java
#	src/org/kde/kdeconnect/Plugins/TelepathyPlugin/TelepathyPlugin.java
#	src/org/kde/kdeconnect/Plugins/TelephonyPlugin/TelephonyPlugin.java
This commit is contained in:
Albert Vaca 2017-07-14 01:12:13 +02:00
commit a8842b189c
54 changed files with 1830 additions and 435 deletions

View File

@ -5,7 +5,7 @@
android:versionName="1.6.5">
<uses-sdk android:minSdkVersion="9"
android:targetSdkVersion="22" />
android:targetSdkVersion="25" />
<supports-screens
android:anyDensity="true"
@ -18,6 +18,8 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<!--<uses-permission android:name="android.permission.BLUETOOTH" />-->
<!--<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />-->
<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" />
@ -42,8 +44,6 @@
android:enabled="true" >
</service>
<!--Commented here and in PluginFactory until we release a desktop version with this feature, so we don't get bad "feature not working" reviews-->
<!--
<service android:name="org.kde.kdeconnect.Plugins.RemoteKeyboardPlugin.RemoteKeyboardService"
android:label="KDE Connect Remote Keyboard"
android:permission="android.permission.BIND_INPUT_METHOD">
@ -52,7 +52,7 @@
</intent-filter>
<meta-data android:name="android.view.im" android:resource="@xml/remotekeyboardplugin_method" />
</service>
-->
<activity
android:name="org.kde.kdeconnect.UserInterface.MaterialActivity"
android:label="KDE Connect"

View File

@ -14,7 +14,7 @@ android {
compileSdkVersion 25
defaultConfig {
minSdkVersion 9
targetSdkVersion 22 //Bumping to >22 means we have to support the new permissions model
targetSdkVersion 25
//multiDexEnabled true
//testInstrumentationRunner "com.android.test.runner.MultiDexTestRunner"
}
@ -57,7 +57,7 @@ android {
minifyEnabled false
useProguard false
}
release { //keep on 'releae', set to 'all' when testing to make sure proguard is not deleting important stuff
release { //keep on 'release', set to 'all' when testing to make sure proguard is not deleting important stuff
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'
@ -83,5 +83,6 @@ dependencies {
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'
}

View File

@ -0,0 +1,17 @@
<?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

@ -9,14 +9,6 @@
android:title="@string/refresh"
/>
<item
android:id="@+id/menu_progress"
android:orderInCategory="200"
android:visible="false"
kdeconnect:showAsAction="ifRoom"
kdeconnect:actionViewClass="android.widget.ProgressBar"
/>
<item
android:id="@+id/menu_rename"
android:orderInCategory="300"

View File

@ -5,16 +5,8 @@
android:id="@+id/menu_refresh"
android:icon="@drawable/ic_action_refresh"
android:orderInCategory="200"
kdeconnect:showAsAction="ifRoom"
kdeconnect:showAsAction="never"
android:title="@string/refresh"
/>
<item
android:id="@+id/menu_progress"
android:orderInCategory="200"
android:visible="false"
kdeconnect:showAsAction="ifRoom"
kdeconnect:actionViewClass="android.widget.ProgressBar"
/>
</menu>

View File

@ -5,13 +5,23 @@
<string name="pref_plugin_battery">تقرير البطّاريّة</string>
<string name="pref_plugin_battery_desc">بلّغ عن حالة البطّاريّة دوريًّا</string>
<string name="pref_plugin_sftp">اكشف نظام الملفّات</string>
<string name="pref_plugin_sftp_desc">تسمح بتصفّح نظام ملفّات هذا الهاتف عن بعد</string>
<string name="pref_plugin_clipboard">مزامنة الحافظة</string>
<string name="pref_plugin_clipboard_desc">شارك محتوى الحافظة</string>
<string name="pref_plugin_mousepad">الدَّخل البعيد</string>
<string name="pref_plugin_mousepad">الدّخل البعيد</string>
<string name="pref_plugin_mousepad_desc">استخدم الهاتف أو اللوحيّ كفأرة ولوحة مفاتيح</string>
<string name="pref_plugin_mpris">تحكّمات الوسائط المتعدّدة</string>
<string name="pref_plugin_mpris_desc">توفّر تحكّمًا بعيدًا لمشغّل الوسائط</string>
<string name="pref_plugin_runcommand">شغّل أمرًا</string>
<string name="pref_plugin_runcommand_desc">تحفّز أوامر عن بعد من الهاتف أو اللوحيّ</string>
<string name="pref_plugin_ping">وخزة</string>
<string name="pref_plugin_ping_desc">أرسل واستقبل وخزات</string>
<string name="pref_plugin_notifications">مزامنة الإخطارات</string>
<string name="pref_plugin_notifications_desc">انفذ إلى إخطاراتك من أجهزة أخرى</string>
<string name="pref_plugin_receive_notifications">استقبل الإخطارات</string>
<string name="pref_plugin_receive_notifications_desc">استقبل الإخطارات من الجهاز الآخر واعرضها على أندرويد</string>
<string name="pref_plugin_sharereceiver">شارك واستقبل</string>
<string name="pref_plugin_sharereceiver_desc">شارك الملفّات والعناوين بين الجهازين</string>
<string name="plugin_not_available">هذه الميزة غير متوفّرة في إصدار أندرويد لديك</string>
<string name="device_list_empty">لا أجهزة</string>
<string name="ok">حسنًا</string>
@ -19,24 +29,33 @@
<string name="open_settings">افتح الإعدادات</string>
<string name="no_permissions">عليك إعطاء التّطبيق صلاحيّات للنّفاذ إلى الإخطارات</string>
<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>
<string name="mousepad_scroll_direction_title">اعكس اتّجاه التّمرير</string>
<string-array name="mousepad_tap_entries">
<item/>
<item/>
<item>Nothing</item>
<item>النّقر باليمين</item>
<item>النّقر بالوسط</item>
<item>لا شيء</item>
</string-array>
<string-array name="mousepad_sensitivity_entries">
<item>Slowest</item>
<item>Above Slowest</item>
<item>Default</item>
<item>Above Default</item>
<item>Fastest</item>
<item>الأبطأ</item>
<item>الأقل بطئًا</item>
<item>الافتراضيّ</item>
<item>الأسرع قليلًا</item>
<item>الأسرع</item>
</string-array>
<string name="category_connected_devices">الأجهزة المقترن بها</string>
<string name="category_not_paired_devices">الأجهزة المتوفّرة</string>
<string name="category_remembered_devices">الأجهزة المتذكَّرة</string>
<string name="plugins_failed_to_load">فشل تحميل الملحقات (المس لمعلومات اكثر):</string>
<string name="device_menu_unpair">أزل الاقتران</string>
<string name="device_menu_plugins">إعدادات الملحقة</string>
<string name="device_menu_unpair">ألغِ الاقتران</string>
<string name="device_not_reachable">الجهاز المقترن غير قابل الوصول</string>
<string name="pair_new_device">اقرن جهازًا جديدًا</string>
<string name="unknown_device">جهاز مجهول</string>
<string name="error_not_reachable">الجهاز غير قابل الوصول</string>
<string name="error_already_requested">طُلب الاقتران بالفعل</string>
@ -46,14 +65,24 @@
<string name="error_canceled_by_user">ألغاه المستخدم</string>
<string name="error_canceled_by_other_peer">ألغاه ندّ آخر</string>
<string name="error_invalid_key">استُقبل مفتاح غير صالح</string>
<string name="encryption_info_title">معلومات التّعمية</string>
<string name="encryption_info_msg_no_ssl">لا يستخدم الجهاز الآخر إصدارة حديثة من «كدي المتّصل»، ستُستخدم طريقة التّعمية القديمة.</string>
<string name="my_device_fingerprint">بصمة SHA1 لشهادة جهازك هي:</string>
<string name="remote_device_fingerprint">بصمة SHA1 لشهادة الجهاز البعيد هي:</string>
<string name="pair_requested">طُلب الاقتران</string>
<string name="pairing_request_from">طلب اقتران من %1s</string>
<string name="received_url_title">استُلمت وصلة من %1s</string>
<string name="received_url_text">المس لفتح \'%1s\'</string>
<string name="incoming_file_title">ملفّ وارد من %1s</string>
<string name="incoming_file_text">%1s</string>
<string name="received_file_title">استُلم ملفّ من %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>
<string name="sent_file_title">أرسل ملفًّا إلى %1s</string>
<string name="sent_file_text">%1s</string>
<string name="sent_file_failed_text">%1s</string>
<string name="tap_to_answer">المس للإجابة</string>
<string name="reconnect">أعد الاتّصال</string>
<string name="right_click">أرسل نقرة باليمين</string>
@ -74,6 +103,8 @@
<string name="mpris_next">التّالي</string>
<string name="mpris_volume">المستوى</string>
<string name="mpris_settings">إعدادات الوسائط المتعدّدة</string>
<string name="mpris_time_settings_title">زرّا التّقدّم والإرجاع</string>
<string name="mpris_time_settings_summary">اضبط الوقت عند نقر زرّيّ التّقديم أو الإرجاع.</string>
<string-array name="mpris_time_entries">
<item>10 ثوان</item>
<item>20 ثانية</item>
@ -92,9 +123,13 @@
<string name="invalid_device_name">اسم جهاز غير صالح</string>
<string name="shareplugin_text_saved">استُقبل نصّ، حُفظ إلى الحافظة</string>
<string name="custom_devices_settings">قائمة أجهزة مخصّصة</string>
<string name="pair_device_action">اقرن جهازًا جديدًا</string>
<string name="unpair_device_action">ألغِ اقتران %s</string>
<string name="custom_device_list">أضف أجهزة بميفاق الإنترنت م​إ</string>
<string name="share_notification_preference">إخطارات مزعجة</string>
<string name="share_notification_preference_summary">اهتزّ وشغّل صوتًا عند استقبال ملفّ</string>
<string name="title_activity_notification_filter">مرشّح الإخطارات</string>
<string name="filter_apps_info">ستُزامن الإخطارات من التّطبيقات المحدّدة.</string>
<string name="sftp_internal_storage">التّخزين الدّاخليّ</string>
<string name="sftp_all_files">كلّ الملفّات</string>
<string name="sftp_sdcard_num">بطاقة SD %d</string>
@ -102,7 +137,26 @@
<string name="sftp_readonly">(للقراءة فقط)</string>
<string name="sftp_camera">صور الكاميرا</string>
<string name="add_host">أضف مضيفًا/م​إ</string>
<string name="add_host_hint">اسم المضيف أو عنوان IP</string>
<string name="no_players_connected">لم يُعثر على مشغّلات</string>
<string name="custom_dev_list_help">استخدم هذا الخيار فقط إن لم يُكتَشف جهازك آليًّا. أدخِل عنوان م​إ أو اسم المضيف أدناه والمس الزرّ لإضافته إلى القائمة. المس عنصرًا موجودًا لإزالته من القائمة.</string>
<string name="mpris_player_on_device">%1$s على %2$s</string>
<string name="send_files">أرسل ملفّات</string>
<string name="pairing_title">أجهزة «كدي المتّصل»</string>
<string name="pairing_description">الأجهزة الأخرى التي تشغّل «كدي المتّصل» وعلى نفس الشّبكة ستظهر هنا.</string>
<string name="device_paired">اقتُرن الجهاز</string>
<string name="device_rename_title">أعد تسمية الجهاز</string>
<string name="device_rename_confirm">أعد التّسمية</string>
<string name="refresh">أنعش</string>
<string name="unreachable_description">الجهاز المقترن هذا لا يمكن الوصول إليه. تأكّد من اتّصاله بنفس الشّبكة.</string>
<string name="no_file_browser">لا متصفّحات ملفّات مثبّتة.</string>
<string name="pref_plugin_telepathy">أرسل SMS</string>
<string name="pref_plugin_telepathy_desc">أرسل رسائل نصّيّة من سطح المكتب</string>
<string name="plugin_not_supported">لا يدعم جهازك هذه الملحقة</string>
<string name="findmyphone_title">جِد جهازي</string>
<string name="findmyphone_title_tablet">جِد جهازي اللوحيّ</string>
<string name="findmyphone_description">يرّن هذا الجهاز لتجده</string>
<string name="findmyphone_found">وُجد</string>
<string name="open">افتح</string>
<string name="close">أغلق</string>
</resources>

View File

@ -1,33 +1,39 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Notificador telefónicu</string>
<string name="pref_plugin_telephony">Avisador telefónicu</string>
<string name="pref_plugin_telephony_desc">Unvia avisos pa SMS y llamaes</string>
<string name="pref_plugin_battery">Informe de batería</string>
<string name="pref_plugin_battery_desc">Infoma davezu del estáu de la batería</string>
<string name="pref_plugin_battery_desc">Informe periódicu del estáu de la batería</string>
<string name="pref_plugin_sftp_desc">Permite restolar remotamente a esti preséu</string>
<string name="pref_plugin_clipboard">Sincronización del cartafueyu</string>
<string name="pref_plugin_clipboard_desc">Comparte\'l conteníu del cartafueyu</string>
<string name="pref_plugin_mousepad">Entrada remota</string>
<string name="pref_plugin_mpris">Controles remotos multimedia</string>
<string name="pref_plugin_mousepad_desc">Usa\'l to teléfonu o tableta como panel táutil y tecláu</string>
<string name="pref_plugin_remotekeyboard">Pulsaciones remotes</string>
<string name="pref_plugin_mpris">Controles multimedia</string>
<string name="pref_plugin_mpris_desc">Forne un control remotu pal to reproductor multimedia</string>
<string name="pref_plugin_runcommand">Execución de comandos</string>
<string name="pref_plugin_runcommand_desc">Aiciona comandos remotos del to teléfonu o tableta</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Unvia y recibi pings</string>
<string name="pref_plugin_ping_desc">Unvia y recibe pings</string>
<string name="pref_plugin_notifications">Sincronización d\'avisos</string>
<string name="pref_plugin_notifications_desc">Accede a los tos avisos dende otros preseos</string>
<string name="pref_plugin_sharereceiver">Unvia y recibi pings</string>
<string name="pref_plugin_notifications_desc">Accede a los tos avisos d\'otros preseos</string>
<string name="pref_plugin_receive_notifications">Recibir avisos</string>
<string name="pref_plugin_receive_notifications_desc">Recibe avisos d\'otros preseos y amuésalos n\'Android</string>
<string name="pref_plugin_sharereceiver">Compartir y recibir</string>
<string name="pref_plugin_sharereceiver_desc">Comparte ficheros y URLs ente preseos</string>
<string name="plugin_not_available">Esta carauterística nun ta disponible na to versión d\'Android</string>
<string name="device_list_empty">Ensin preseos</string>
<string name="ok">Aceutar</string>
<string name="cancel">Encaboxar</string>
<string name="open_settings">Abrir axustes</string>
<string name="no_permissions">Necesites garantizar l\'accesu a los avisos</string>
<string name="no_permissions">¡</string>
<string name="send_ping">Unviar ping</string>
<string name="open_mpris_controls">Controles multimedia</string>
<string name="open_mousepad">Entrada remota</string>
<string name="mousepad_info">Muevi un deu enriba la pantalla pa mover el mur. calca pa un clic y usa dos/tres deos pa los motones de drecha y mediu. Usa un primíu llargu pa arrastrar y soltar.</string>
<string name="open_mpris_controls">Control multimedia</string>
<string-array name="mousepad_tap_entries">
<item>Clic drechu</item>
<item>Clic d\'en mediu</item>
<item>Nada</item>
<item>Right click</item>
<item>Middle click</item>
<item>Nothing</item>
</string-array>
<string-array name="mousepad_sensitivity_entries">
<item>Slowest</item>
@ -36,101 +42,16 @@
<item>Above Default</item>
<item>Fastest</item>
</string-array>
<string name="category_connected_devices">Preseos coneutaos</string>
<string name="category_not_paired_devices">Preseos disponibles</string>
<string name="category_remembered_devices">Preseos recordaos</string>
<string name="device_not_reachable">El preséu empareyáu nun ye agamable</string>
<string name="unknown_device">Preséu desconocíu</string>
<string name="error_not_reachable">Nun ye algamable\'l preséu</string>
<string name="error_already_requested">Empareyamientu yá solicitáu</string>
<string name="error_already_paired">El preséu yá ta empareyáu</string>
<string name="error_could_not_send_package">Nun pudo unviase\'l paquete</string>
<string name="error_timed_out">Tiempu escosao</string>
<string name="error_canceled_by_user">Encaboxáu pol usuariu</string>
<string name="error_canceled_by_other_peer">Encaboxáu pola otra parte</string>
<string name="error_invalid_key">Recibióse una clave non válida</string>
<string name="pair_requested">Solicitóse l\'empareyamientu</string>
<string name="pairing_request_from">Solicitú d\'empareyamientu de %1s</string>
<string name="received_url_title">Recibióse l\'enllaz de %1s</string>
<string name="received_url_text">Calca p\'abrir «%1s»</string>
<string name="incoming_file_title">Ficheru entrante de %1s</string>
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Unviando ficheru a %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="received_file_title">Recibióse\'l ficheru de %1s</string>
<string name="received_file_fail_title">Fallu al recibir el ficheru de %1s</string>
<string name="received_file_text">Tap to open \'%1s\'</string>
<string name="sent_file_title">Unvióse\'l ficheru a %1s</string>
<string name="sent_file_text">%1s</string>
<string name="sent_file_failed_text">%1s</string>
<string name="tap_to_answer">Calca pa responder</string>
<string name="reconnect">Reconeutar</string>
<string name="show_keyboard">Amosar tecláu</string>
<string name="device_not_paired">Preséu non empareyáu</string>
<string name="request_pairing">Solicitar empareyamientu</string>
<string name="pairing_accept">Aceutar</string>
<string name="pairing_reject">Refugar</string>
<string name="device">Preséu</string>
<string name="pair_device">Empareyar preséu</string>
<string name="remote_control">Control remotu</string>
<string name="settings">Axustes KDE Connect</string>
<string name="mpris_play">Reproducir</string>
<string name="mpris_previous">Anterior</string>
<string name="mpris_rew">Rebobinar</string>
<string name="mpris_ff">Avance rápidu</string>
<string name="mpris_next">Siguiente</string>
<string name="mpris_volume">Volume</string>
<string name="mpris_settings">Axustes multimedia</string>
<string name="mpris_time_settings_title">Botones d\'avanzar/rebobinar</string>
<string name="mpris_time_settings_summary">Axusta\'l tiempu p\'avanzar/rebobinar al primise</string>
<string name="error_timed_out">Escosó\'l tiempu</string>
<string-array name="mpris_time_entries">
<item>10 segundos</item>
<item>20 segundos</item>
<item>30 segundos</item>
<item>1 minutu</item>
<item>2 minutos</item>
<item>10 seconds</item>
<item>20 seconds</item>
<item>30 seconds</item>
<item>1 minute</item>
<item>2 minutes</item>
</string-array>
<string name="protocol_version_older">Esti preséu usa una versión vieya del protocolu</string>
<string name="protocol_version_newer">Esti preséu usa una versión anovada del protocolu</string>
<string name="general_settings">Axustes xenerales</string>
<string name="plugin_settings">Axustes</string>
<string name="plugin_settings_with_name">Axustes de %s</string>
<string name="device_name">Nome de preséu</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Nome de preséu non válidu</string>
<string name="shareplugin_text_saved">Recibióse\'l testu y guardóse nel cartafueyu</string>
<string name="custom_devices_settings">Llista de preseos personalizada</string>
<string name="pair_device_action">Empareyar con un preséu nuevu</string>
<string name="unpair_device_action">Desempareyar %s</string>
<string name="custom_device_list">Amestar preseos pola IP</string>
<string name="share_notification_preference">Avisos sonoros</string>
<string name="share_notification_preference_summary">Fai vibrar y reproduz un soníu al recibir un ficheru</string>
<string name="title_activity_notification_filter">Peñera d\'avisos</string>
<string name="filter_apps_info">Los avisos sincronizaránse coles aplicaciones esbillaes.</string>
<string name="sftp_internal_storage">Almacenamientu internu</string>
<string name="sftp_all_files">Tolos ficheros</string>
<string name="sftp_sdcard_num">Tarxeta SD %d</string>
<string name="sftp_sdcard">Tarxeta SD</string>
<string name="sftp_readonly">(namai llectura)</string>
<string name="sftp_camera">Semeyes de cámara</string>
<string name="add_host">Amestar agospiu/IP</string>
<string name="add_host_hint">Nome d\'agospiu o IP</string>
<string name="no_players_connected">Nun s\'alcontraron reproductores</string>
<string name="custom_dev_list_help">Usa esta opción namái si\'l to preséu nun se deteuta automáticamente. Introduz la direición o\'l nome d\'agospiu y toca\'l botón p\'amestalu a la llista. Toca un elementu esistente pa desanicialu de la llista.</string>
<string name="mpris_player_on_device">%1$s en %2$s</string>
<string name="send_files">Unviar ficheros</string>
<string name="pairing_title">Preseos KDE Connect</string>
<string name="pairing_description">Deberíen apaecer equí otros preseos executando KDE Connect.</string>
<string name="device_paired">Preséu empareyáu</string>
<string name="device_rename_title">Renomar preséu</string>
<string name="device_rename_confirm">Renomar</string>
<string name="refresh">Refrescar</string>
<string name="unreachable_description">Esti preséu empareyáu nun ye algamable. Asegúrate que ta coneutáu a la to mesma rede.</string>
<string name="no_file_browser">Nun hai restoladores de ficheros instalaos.</string>
<string name="pref_plugin_telepathy">Unviar SMS</string>
<string name="no_file_browser">Nun hai restoladores de ficheros instalaos</string>
<string name="pref_plugin_telepathy_desc">Unvia mensaxes de testu dende\'l to escritoriu</string>
<string name="plugin_not_supported">Esti complementu nun ta sofitáu pol preséu</string>
<string name="findmyphone_found">Alcontrar</string>
<string name="open">Abrir</string>
<string name="close">Zarrar</string>
<string name="plugin_not_supported">Esti complementu nun lu sofita\'l preséu</string>
<string name="findmyphone_description">Fai sonar el teléfonu pa qu\'asina pueas alcontralu</string>
</resources>

View File

@ -27,8 +27,6 @@
<item>Srednji klik</item>
<item>Ništa</item>
</string-array>
<string name="mousepad_double_default">desno</string>
<string name="mousepad_triple_default">Srednje</string>
<string-array name="mousepad_sensitivity_entries">
<item>Slowest</item>
<item>Above Slowest</item>

View File

@ -10,8 +10,8 @@
<string name="pref_plugin_clipboard_desc">Comparteix el contingut del porta-retalls</string>
<string name="pref_plugin_mousepad">Entrada remota</string>
<string name="pref_plugin_mousepad_desc">Usa el vostre telèfon o tauleta com un ratolí i un teclat</string>
<string name="pref_plugin_remotekeyboard">Rep les pulsacions de tecla remotes</string>
<string name="pref_plugin_remotekeyboard_desc">Rep els esdeveniments de pulsacions de tecla des de dispositius remots</string>
<string name="pref_plugin_remotekeyboard">S\'estan rebent pulsacions de tecla remotes</string>
<string name="pref_plugin_remotekeyboard_desc">S\'estan rebent esdeveniments de pulsacions de tecla des de dispositius remots</string>
<string name="pref_plugin_mpris">Controls multimèdia</string>
<string name="pref_plugin_mpris_desc">Proporciona un comandament a distància pel reproductor multimèdia</string>
<string name="pref_plugin_runcommand">Executa una ordre</string>
@ -33,7 +33,7 @@
<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>
<string name="remotekeyboard_not_connected">No hi ha cap connexió activa amb el teclat remot, establiu-ne una al «kdeconnect»</string>
<string name="remotekeyboard_not_connected">No hi ha cap connexió activa amb el teclat remot, establiu-ne una al kde-connect</string>
<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>
@ -47,9 +47,6 @@
<item>Clic del mig</item>
<item>No fer res</item>
</string-array>
<string name="mousepad_double_default">dret</string>
<string name="mousepad_triple_default">mig</string>
<string name="mousepad_sensitivity_default">Predeterminada</string>
<string-array name="mousepad_sensitivity_entries">
<item>La més lenta</item>
<item>Lenta</item>
@ -176,4 +173,7 @@
<string name="findmyphone_found">L\'he trobat</string>
<string name="open">Obre</string>
<string name="close">Tanca</string>
<string name="no_permissions_storage">Us caldrà concedir permís per accedir a l\'emmagatzematge</string>
<string name="plugins_need_permission">Alguns connectors necessiten permisos per a funcionar (puntegeu per a més informació):</string>
<string name="permission_explanation">Aquest connector necessita permisos per a funcionar</string>
</resources>

View File

@ -47,9 +47,6 @@
<item>Kliknutí prostředním tlačítkem myši</item>
<item>Nic</item>
</string-array>
<string name="mousepad_double_default">pravé</string>
<string name="mousepad_triple_default">prostřední</string>
<string name="mousepad_sensitivity_default">výchozí</string>
<string-array name="mousepad_sensitivity_entries">
<item>Nejpomalejší</item>
<item>Méně pomalý</item>

View File

@ -47,15 +47,12 @@
<item>Midterklik</item>
<item>Intet</item>
</string-array>
<string name="mousepad_double_default">højre</string>
<string name="mousepad_triple_default">midter</string>
<string name="mousepad_sensitivity_default">standard</string>
<string-array name="mousepad_sensitivity_entries">
<item>Mest langsom</item>
<item>Over mest langsom</item>
<item>Standard</item>
<item>Over standard</item>
<item>Hurtigste</item>
<item>Hurtigst</item>
</string-array>
<string name="category_connected_devices">Forbundne enheder</string>
<string name="category_not_paired_devices">Tilgængelig enheder</string>
@ -85,12 +82,15 @@
<string name="incoming_file_title">Indkommende fil fra %1s</string>
<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>
<string name="sent_file_title">Fil sendt til %1s</string>
<string name="sent_file_text">%1s</string>
<string name="sent_file_failed_title">Kunne ikke sende filen til %1s</string>
<string name="sent_file_failed_text">%1s</string>
<string name="tap_to_answer">Tap for at svare</string>
<string name="reconnect">Forbind igen</string>
@ -137,6 +137,10 @@
<string name="custom_device_list">Tilføj enheder via IP</string>
<string name="share_notification_preference">Støjende bekendtgørelser</string>
<string name="share_notification_preference_summary">Vibrér og afspil en lyd når en fil modtages</string>
<string name="share_destination_customize">Tilpas destinationsmappe</string>
<string name="share_destination_customize_summary_disabled">Modtagne filer vil dukke op i Downloads</string>
<string name="share_destination_customize_summary_enabled">Filer vil blive gemt i mappen nedenfor</string>
<string name="share_destination_folder_preference">Destinationsmappe</string>
<string name="title_activity_notification_filter">Bekendtgørelsesfilter</string>
<string name="filter_apps_info">Bekendtgørelser vil blive synkroniseret for de valgte apps.</string>
<string name="sftp_internal_storage">Intern lagring</string>

View File

@ -13,7 +13,7 @@
<string name="pref_plugin_mpris">Multimedia-Bedienung</string>
<string name="pref_plugin_mpris_desc">Eine Fernbedienung für Ihre Medienwiedergabe</string>
<string name="pref_plugin_runcommand">Befehl ausführen</string>
<string name="pref_plugin_runcommand_desc">Von Ihrem Telefon oder Tablett Befehle auf anderen Geräten ausführen</string>
<string name="pref_plugin_runcommand_desc">Von Ihrem Telefon oder Tablet Befehle auf anderen Geräten ausführen</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Senden und Empfangen von Pings</string>
<string name="pref_plugin_notifications">Benachrichtigungs-Abgleich</string>
@ -41,9 +41,6 @@
<item>Mittelklick</item>
<item>Nichts</item>
</string-array>
<string name="mousepad_double_default">Rechts</string>
<string name="mousepad_triple_default">Mitte</string>
<string name="mousepad_sensitivity_default">Standard</string>
<string-array name="mousepad_sensitivity_entries">
<item>Langsamste</item>
<item>Langsam</item>
@ -95,7 +92,7 @@
<string name="middle_click">Mittelklick senden</string>
<string name="show_keyboard">Tastatur anzeigen</string>
<string name="device_not_paired">Das Gerät ist nicht verbunden</string>
<string name="request_pairing">Verbindung angefordert</string>
<string name="request_pairing">Verbindung anfordern</string>
<string name="pairing_accept">Annehmen</string>
<string name="pairing_reject">Ablehnen</string>
<string name="device">Gerät</string>
@ -164,8 +161,8 @@
<string name="pref_plugin_telepathy_desc">Text-Nachrichten von Ihrer Arbeitsfläche senden</string>
<string name="plugin_not_supported">Dieses Modul wird durch das Gerät nicht unterstützt</string>
<string name="findmyphone_title">Mein Telefon suchen</string>
<string name="findmyphone_title_tablet">Mein Tablett suchen</string>
<string name="findmyphone_description">Ruft dieses Gerät an, um es zu suchen.</string>
<string name="findmyphone_title_tablet">Mein Tablet suchen</string>
<string name="findmyphone_description">Ruft dieses Gerät an, damit sie es finden können</string>
<string name="findmyphone_found">Gefunden</string>
<string name="open">Öffnen</string>
<string name="close">Schließen</string>

View File

@ -41,9 +41,6 @@
<item>Μεσαίο κλικ</item>
<item>Τίποτα</item>
</string-array>
<string name="mousepad_double_default">δεξί</string>
<string name="mousepad_triple_default">μεσαίο</string>
<string name="mousepad_sensitivity_default">προκαθορισμένο</string>
<string-array name="mousepad_sensitivity_entries">
<item>Το πιο αργό</item>
<item>Πάνω από το πιο αργό</item>

View File

@ -47,9 +47,6 @@
<item>Middle click</item>
<item>Nothing</item>
</string-array>
<string name="mousepad_double_default">right</string>
<string name="mousepad_triple_default">middle</string>
<string name="mousepad_sensitivity_default">default</string>
<string-array name="mousepad_sensitivity_entries">
<item>Slowest</item>
<item>Above Slowest</item>

View File

@ -11,7 +11,7 @@
<string name="pref_plugin_mousepad">Entrada remota</string>
<string name="pref_plugin_mousepad_desc">Usar su teléfono o tableta como teclado y teclado táctil</string>
<string name="pref_plugin_remotekeyboard">Recibir pulsaciones de teclas remotas</string>
<string name="pref_plugin_remotekeyboard_desc">Reciba eventos de pulsación de teclas desde dispositivos remotos</string>
<string name="pref_plugin_remotekeyboard_desc">Recibir eventos de pulsación de teclas desde dispositivos remotos</string>
<string name="pref_plugin_mpris">Controles multimedia</string>
<string name="pref_plugin_mpris_desc">Proporciona un control remoto para su reproductor de medios</string>
<string name="pref_plugin_runcommand">Ejecutar orden</string>
@ -47,9 +47,6 @@
<item>Clic del botón central</item>
<item>Nada</item>
</string-array>
<string name="mousepad_double_default">derecho</string>
<string name="mousepad_triple_default">medio</string>
<string name="mousepad_sensitivity_default">por defecto</string>
<string-array name="mousepad_sensitivity_entries">
<item>Muy poco sensible</item>
<item>Poco sensible</item>
@ -176,4 +173,7 @@
<string name="findmyphone_found">Encontrado</string>
<string name="open">Abrir</string>
<string name="close">Cerrar</string>
<string name="no_permissions_storage">Debe otorgar permisos para acceder al almacenamiento</string>
<string name="plugins_need_permission">Algunos complementos necesitan permisos para funcionar (pulse para más información):</string>
<string name="permission_explanation">Este complemento necesita permisos para funcionar</string>
</resources>

View File

@ -41,9 +41,6 @@
<item>Keskklõps</item>
<item>Ei tee midagi</item>
</string-array>
<string name="mousepad_double_default">parem</string>
<string name="mousepad_triple_default">keskmine</string>
<string name="mousepad_sensitivity_default">vaikimisi</string>
<string-array name="mousepad_sensitivity_entries">
<item>Kõige aeglasem</item>
<item>Kõige aeglasemast kiirem</item>

View File

@ -41,9 +41,6 @@
<item>Keskinapsautus</item>
<item>Ei toimintoa</item>
</string-array>
<string name="mousepad_double_default">Oikea painike</string>
<string name="mousepad_triple_default">Keskipainike</string>
<string name="mousepad_sensitivity_default">oletus</string>
<string-array name="mousepad_sensitivity_entries">
<item>Hitain</item>
<item>Hitainta suurempi</item>

View File

@ -28,25 +28,25 @@
<string name="mousepad_info">Mova un dedo na pantalla para mover o cursor. 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_double_tap_settings_title">Definir a acción de tocar con dous dedos</string>
<string name="mousepad_triple_tap_settings_title">Definir a acción de tocar con tres dedos</string>
<string name="mousepad_sensitivity_settings_title">Definir a sensibilidade do punteiro táctil</string>
<string name="mousepad_scroll_direction_title">Inverter a dirección de desprazamento</string>
<string-array name="mousepad_tap_entries">
<item>Clic dereito</item>
<item>Clic central</item>
<item>Nada</item>
</string-array>
<string name="mousepad_double_default">dereita</string>
<string name="mousepad_triple_default">medio</string>
<string-array name="mousepad_sensitivity_entries">
<item>Slowest</item>
<item>Above Slowest</item>
<item>Default</item>
<item>Above Default</item>
<item>Fastest</item>
<item>O máis lento</item>
<item>Lento</item>
<item>Predeterminado</item>
<item>Rápido</item>
<item>O máis rápido</item>
</string-array>
<string name="category_connected_devices">Dispositivos conectados</string>
<string name="category_not_paired_devices">Dispositivos dispoñíbeis</string>
<string name="category_remembered_devices">Dispositivos coñecidos</string>
<string name="plugins_failed_to_load">Non foi posíbel cargar os seguintes complementos (toque para obter máis información):</string>
<string name="device_menu_plugins">Configuración do engadido</string>
<string name="device_menu_plugins">Configuración do complemento</string>
<string name="device_menu_unpair">Desemparellarse</string>
<string name="device_not_reachable">O dispositivo emparellado está fóra do alcance.</string>
<string name="pair_new_device">Emparellar cun novo dispositivo</string>
@ -136,7 +136,7 @@
<string name="pairing_description">Outros dispositivos que estean a executar KDE Connect na mesma rede deberían aparecer aquí.</string>
<string name="device_paired">Emparellouse co dispositivo</string>
<string name="device_rename_title">Cambiar o nome do dispositivo</string>
<string name="device_rename_confirm">Mudar o nome</string>
<string name="device_rename_confirm">Cambiar o nome</string>
<string name="refresh">Actualizar</string>
<string name="unreachable_description">Este dispositivo emparellado está fóra do alcance. Asegúrese de que está conectado á mesma rede.</string>
<string name="no_file_browser">Non hai navegadores de ficheiros instalados.</string>

View File

@ -5,15 +5,23 @@
<string name="pref_plugin_battery">דיווח סוללה</string>
<string name="pref_plugin_battery_desc">מדווח על אחוז הסוללה למחשב</string>
<string name="pref_plugin_sftp">גישה לקבצים</string>
<string name="pref_plugin_clipboard">סנכנרון לוח העתקה</string>
<string name="pref_plugin_clipboard_desc">שתף בין המחשבים את מה שמועתק</string>
<string name="pref_plugin_sftp_desc">אפשר להתקן המרוחק לדפדף בקבצים של הפלאפון מרחוק</string>
<string name="pref_plugin_clipboard">סנכרון לוח העתקה</string>
<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>
<string name="pref_plugin_runcommand_desc">הרץ פקודה במחשב מהמכשיר שלך</string>
<string name="pref_plugin_ping">פינג</string>
<string name="pref_plugin_ping_desc">שלח וקבל פינגים</string>
<string name="pref_plugin_notifications">סנכרון התראות</string>
<string name="pref_plugin_notifications_desc">הראה את ההתראות מהפלאפון בהתקן אחר</string>
<string name="pref_plugin_receive_notifications">קבלת התראות</string>
<string name="pref_plugin_receive_notifications_desc">קבל התראות מהתקן אחר והצג אותם במכשיר שלך</string>
<string name="pref_plugin_sharereceiver">שתף וקבל קבצים וכתובות</string>
<string name="pref_plugin_sharereceiver_desc">שתף וקבל קבצים וכתובת אינטרנט בין התקנים</string>
<string name="plugin_not_available">אפשרות זו אינה זמינה בגרסת האנדרואיד שלך</string>
@ -24,7 +32,11 @@
<string name="no_permissions">אתה צריך לתת הרשאות לגישה להתראות</string>
<string name="send_ping">שלח פינג</string>
<string name="open_mpris_controls">שליטה על המדיה</string>
<string name="open_mousepad">שלוט על המחשב</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_double_tap_settings_title">הגדר פעולה ללחיצת שתי אצבעות</string>
<string name="mousepad_triple_tap_settings_title">הגדר פעולה ללחיצת שלוש אצבעות</string>
@ -35,9 +47,6 @@
<item>לחיצה אצמעית (גלגלת)</item>
<item>שום דבר</item>
</string-array>
<string name="mousepad_double_default">ימין</string>
<string name="mousepad_triple_default">אמצע</string>
<string name="mousepad_sensitivity_default">ברירת מחדל</string>
<string-array name="mousepad_sensitivity_entries">
<item>הכי איטי</item>
<item>יותר מההכי איטי</item>
@ -59,9 +68,9 @@
<string name="error_already_paired">ההתקן כבר מותאם</string>
<string name="error_could_not_send_package">לא יכול לשלוח חבילה</string>
<string name="error_timed_out">נגמר הזמן</string>
<string name="error_canceled_by_user">בוטל ע\"י המשתמש</string>
<string name="error_canceled_by_other_peer">בוטל ע\"י מישהו אחר</string>
<string name="error_invalid_key">התקבל מפתח לא חוקי</string>
<string name="error_canceled_by_user">בוטל על ידי המשתמש</string>
<string name="error_canceled_by_other_peer">בוטל על ידי מישהו אחר</string>
<string name="error_invalid_key">התקבל מפתח לא תקין</string>
<string name="encryption_info_title">פרטי הצפנה</string>
<string name="encryption_info_msg_no_ssl">ההתקן השני אינו משתמש בגרסה האחרונה של KDE Connect, משתמש בשיטת ההצפנה הישנה.</string>
<string name="my_device_fingerprint">טביעת האצבע SHA1 של ההתקן היא:</string>
@ -69,16 +78,19 @@
<string name="pair_requested">בקשת התאמה</string>
<string name="pairing_request_from">בוקשה התאמה מ־%1s</string>
<string name="received_url_title">התקבל קישור מ־%1s</string>
<string name="received_url_text">לחץ כדי לפתוח את \'%1s\'</string>
<string name="incoming_file_title">התקבל קובץ ־%1s</string>
<string name="received_url_text">לחץ כדי לפתוח את \"%1s\"</string>
<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_title">שולח קובץ אל %1s</string>
<string name="outgoing_files_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>
<string name="sent_file_title">הקובץ נשלח ל־%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>
<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>
@ -109,22 +121,26 @@
<item>דקה</item>
<item>שתי דקות</item>
</string-array>
<string name="share_to">שתף ל...</string>
<string name="share_to">שתף אל...</string>
<string name="protocol_version_older">ההתקן משתמש בגרסה ישנה יותר</string>
<string name="protocol_version_newer">ההתקן משתמש בגרסה חדשה יותר</string>
<string name="general_settings">הגדרות כלליות</string>
<string name="plugin_settings">הגדרות</string>
<string name="plugin_settings_with_name">הגדרות %s</string>
<string name="device_name">שם המכשיר</string>
<string name="device_name">שם ההתקן</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">שם המכשיר לא תקין</string>
<string name="invalid_device_name">שם ההתקן לא תקין</string>
<string name="shareplugin_text_saved">התקבל טקסט, נשמר ללוח העתקה</string>
<string name="custom_devices_settings">רשימת התקנים מותאמת אישית</string>
<string name="pair_device_action">התאם התקן חדש</string>
<string name="unpair_device_action">בטל את ההתאמה עם %s</string>
<string name="custom_device_list">הוסף התקן ע\"י כתובת IP</string>
<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">קבצים שהתקבלו יהיו בהורדות</string>
<string name="share_destination_customize_summary_enabled">קבצים יאוכסנו בתיקיה למטה</string>
<string name="share_destination_folder_preference">תיקית יעד</string>
<string name="title_activity_notification_filter">סנן התראות</string>
<string name="filter_apps_info">התראות יסונכרנו רק לאפליקציות נבחרות</string>
<string name="sftp_internal_storage">זיכרון פנימי</string>
@ -133,11 +149,11 @@
<string name="sftp_sdcard">כרטיס זיכרון</string>
<string name="sftp_readonly">(לקריאה בלבד)</string>
<string name="sftp_camera">תמונות מצלמה</string>
<string name="add_host">הוסף כתובת שרת או IP</string>
<string name="add_host_hint">כתבות שרת או IP</string>
<string name="add_host">הוסף כתובת או IP</string>
<string name="add_host_hint">כתובת או IP</string>
<string name="no_players_connected">לא נמצא נגן</string>
<string name="custom_dev_list_help">השתמש באפשרות זו רק אם המכשיר שלך לא מזוהה באופן אוטומטי. הקלד את כתובת הIP או את כינוי ההתקן למטה ולחץ על הכפתור כדי להוסיף לרשימה. לחץ על פריט קיים כדי להסיר אותו מהרשימה.</string>
<string name="mpris_player_on_device">%1$s ב־%2$s</string>
<string name="mpris_player_on_device">%1$s אצל %2$s</string>
<string name="send_files">שלח קובץ</string>
<string name="pairing_title">מכשירי KDE Connect</string>
<string name="pairing_description">התקנים אחרים המריצים KDE Connect ברשת הנוכחית צריכים להופיע פה.</string>
@ -145,12 +161,15 @@
<string name="device_rename_title">שנה שם התקן</string>
<string name="device_rename_confirm">שנה שם</string>
<string name="refresh">רענן</string>
<string name="unreachable_description">ההתקן המתואם לא זמין, וודא שהוא מחובר לאותה רשת אליה התקן זה מחובר.</string>
<string name="unreachable_description">ההתקן המתואם לא זמין, וודא שהוא מחובר לאותה רשת אליה אתה מחובר.</string>
<string name="on_data_message">נראה שאתה מחובר דרך הרשת הסלולרית. KDE Connect עובד רק עם רשתות מקומיות.</string>
<string name="no_file_browser">לא נמצאו מנהלי קבצים מותקנים במכשיר זה.</string>
<string name="pref_plugin_telepathy">שלח SMS</string>
<string name="pref_plugin_telepathy">שליחת הודעת SMS</string>
<string name="pref_plugin_telepathy_desc">שלח הודעות מהמחשב שלך</string>
<string name="plugin_not_supported">התוסף הזה לא נתמך ע\"י המכשיר שלך</string>
<string name="findmyphone_title">מצא את המכשיר שלי</string>
<string name="plugin_not_supported">תוסף הזה לא נתמך על ידי המכשיר שלך</string>
<string name="findmyphone_title">מצא את הפלאפון שלי</string>
<string name="findmyphone_title_tablet">מצא את הטבלט שלי</string>
<string name="findmyphone_description">מפעיל רעש במכשיר כדי שתוכל למצוא אותו.</string>
<string name="findmyphone_found">נמצא</string>
<string name="open">פתח</string>
<string name="close">סגור</string>

View File

@ -47,9 +47,6 @@
<item>Clic centrale</item>
<item>Niente</item>
</string-array>
<string name="mousepad_double_default">destra</string>
<string name="mousepad_triple_default">centro</string>
<string name="mousepad_sensitivity_default">predefinita</string>
<string-array name="mousepad_sensitivity_entries">
<item>Minima</item>
<item>Più veloce</item>

View File

@ -41,9 +41,6 @@
<item>가운데 단추 누름</item>
<item>아무것도 안 함</item>
</string-array>
<string name="mousepad_double_default">오른쪽</string>
<string name="mousepad_triple_default">가운데</string>
<string name="mousepad_sensitivity_default">기본값</string>
<string-array name="mousepad_sensitivity_entries">
<item>느리게</item>
<item>느리게 이상</item>

View File

@ -41,14 +41,11 @@
<string name="error_already_requested">Jau paprašyta suporuoti</string>
<string name="error_already_paired">Įrenginys jau suporuotas</string>
<string name="error_could_not_send_package">Nepavyksta išsiųsti paketo</string>
<string name="error_timed_out">Skirtasis laikas baigėsi</string>
<string name="error_canceled_by_user">Naudotojas atšaukė užduotį</string>
<string name="error_canceled_by_other_peer">Porininkas atšaukė užduotį</string>
<string name="error_invalid_key">Gautas netinkamas raktas</string>
<string name="pair_requested">Paprašyta suporuoti</string>
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="sent_file_text">%1s</string>
<string name="sent_file_failed_text">%1s</string>
<string name="tap_to_answer">Norėdami atsakyti, palieskite</string>
<string name="reconnect">Prisijungti iš naujo</string>
<string name="show_keyboard">Rodyti klaviatūrą</string>
@ -86,7 +83,6 @@
<string name="pair_device_action">Suporuoti naują įrenginį</string>
<string name="unpair_device_action">Atrišti %s</string>
<string name="custom_device_list">Pridėti įrenginį pagal IP</string>
<string name="sftp_internal_storage">Vidinė saugykla</string>
<string name="sftp_all_files">Visi failai</string>
<string name="sftp_sdcard_num">SD kortelė %d</string>
<string name="sftp_sdcard">SD kortelė</string>
@ -100,9 +96,12 @@
<string name="pairing_description">Čia turėtų pasirodyti to kiti paties tinklo įrenginiai, kuriuose veikia „KDE Connect“</string>
<string name="device_paired">Įrenginys suporuotas</string>
<string name="device_rename_title">Pervadinti įrenginį</string>
<string name="device_rename_confirm">Pervadinti</string>
<string name="refresh">Atnaujinti</string>
<string name="unreachable_description">Šis suporuotas įrenginys nepasiekiamas. Patikrinkite, ar jis prisijungęs prie to paties tinklo.</string>
<string name="pref_plugin_telepathy">Siųsti SMS</string>
<string name="plugin_not_supported">Telefonas nepalaiko šio papildinio</string>
<string name="findmyphone_found">Radau</string>
<string name="open">Atverti</string>
<string name="close">Užverti</string>
</resources>

View File

@ -47,9 +47,6 @@
<item>Middelste muisklik</item>
<item>Niets</item>
</string-array>
<string name="mousepad_double_default">rechts</string>
<string name="mousepad_triple_default">midden</string>
<string name="mousepad_sensitivity_default">standaard</string>
<string-array name="mousepad_sensitivity_entries">
<item>Langzaamst</item>
<item>Langzaam</item>
@ -78,22 +75,22 @@
<string name="encryption_info_msg_no_ssl">Het andere apparaat gebruikt geen recente versie van KDE Connect, de verouderde versleutelingsmethode zal worden gebruikt.</string>
<string name="my_device_fingerprint">De SHA1 vingerafdruk van het certificaat van uw apparaat is:</string>
<string name="remote_device_fingerprint">De SHA1 vingerafdruk van het certificaat van het apparaat op afstand is:</string>
<string name="pair_requested">Paar gevraagd</string>
<string name="pair_requested">Paarvorming gevraagd</string>
<string name="pairing_request_from">Verzoek om een paar te maken van %1s</string>
<string name="received_url_title">Ontvangen koppeling van %1s</string>
<string name="received_url_text">Tap om \'%1s\' te openen</string>
<string name="incoming_file_title">Inkomend bestand van %1s</string>
<string name="incoming_file_text">%1s</string>
<string name="outgoing_file_title">Bezig bestand te verzenden naar %1s</string>
<string name="outgoing_files_title">Bestanden 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 van %2$d bestanden</string>
<string name="outgoing_files_text">Verzonden %1$d uit %2$d bestanden</string>
<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>
<string name="sent_file_title">Bestand verzonden naar %1s</string>
<string name="sent_file_text">%1s</string>
<string name="sent_file_failed_title">Verzenden van bestanden naar %1s is mislukt</string>
<string name="sent_file_failed_title">Verzenden van bestand naar %1s is mislukt</string>
<string name="sent_file_failed_text">%1s</string>
<string name="tap_to_answer">Tap om te antwoorden</string>
<string name="reconnect">Opnieuw verbinden</string>
@ -140,7 +137,7 @@
<string name="custom_device_list">Voeg apparaten toe per IP-adres</string>
<string name="share_notification_preference">Luidruchtige meldingen</string>
<string name="share_notification_preference_summary">Vibreer en speel een geluidje bij ontvangen van een bestand</string>
<string name="share_destination_customize">Pas bestemmingsmap aan</string>
<string name="share_destination_customize">De bestemmingsmap aanpassen</string>
<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>
@ -176,4 +173,7 @@
<string name="findmyphone_found">Gevonden</string>
<string name="open">Openen</string>
<string name="close">Sluiten</string>
<string name="no_permissions_storage">U moet toestemming geven voor toegang tot de opslag</string>
<string name="plugins_need_permission">Sommige plug-ins hebben toestemming nodig om te werken (tik voor meer informatie):</string>
<string name="permission_explanation">Deze plug-in heeft toestemming nodig om te werken</string>
</resources>

View File

@ -47,9 +47,6 @@
<item>Kliknięcie środkowym</item>
<item>Nic</item>
</string-array>
<string name="mousepad_double_default">prawo</string>
<string name="mousepad_triple_default">środek</string>
<string name="mousepad_sensitivity_default">domyślne</string>
<string-array name="mousepad_sensitivity_entries">
<item>Najmniejsza</item>
<item>Ponad najmniejszą</item>
@ -176,4 +173,7 @@
<string name="findmyphone_found">Znaleziony</string>
<string name="open">Otwórz</string>
<string name="close">Zamknij</string>
<string name="no_permissions_storage">Musisz nadać uprawnienia, aby uzyskać dostęp do pamięci masowej</string>
<string name="plugins_need_permission">Niektóre z wtyczek wymagają uprawnień do działania (stuknij po więcej informacji)</string>
<string name="permission_explanation">Ta wtyczka wymaga uprawnień do działania</string>
</resources>

View File

@ -39,9 +39,6 @@
<item>Botão do meio</item>
<item>Nada</item>
</string-array>
<string name="mousepad_double_default">direita</string>
<string name="mousepad_triple_default">meio</string>
<string name="mousepad_sensitivity_default">padrão</string>
<string-array name="mousepad_sensitivity_entries">
<item>Mais lento</item>
<item>Ainda mais lento</item>

View File

@ -47,9 +47,6 @@
<item>Botão do meio</item>
<item>Nada</item>
</string-array>
<string name="mousepad_double_default">direita</string>
<string name="mousepad_triple_default">meio</string>
<string name="mousepad_sensitivity_default">predefinição</string>
<string-array name="mousepad_sensitivity_entries">
<item>Mais Lento</item>
<item>Ainda Mais Lento</item>
@ -176,4 +173,7 @@
<string name="findmyphone_found">Encontrado</string>
<string name="open">Abrir</string>
<string name="close">Fechar</string>
<string name="no_permissions_storage">Precisa de dar permissões de acesso ao armazenamento</string>
<string name="plugins_need_permission">Alguns \'plugins\' precisam de permissões para funcionar (toque para mais informações):</string>
<string name="permission_explanation">Este \'plugin\' precisa de permissões para funcionar</string>
</resources>

View File

@ -10,8 +10,6 @@
<string name="pref_plugin_clipboard_desc">Zdieľať obsah schránky</string>
<string name="pref_plugin_mousepad">Vzdialený vstup</string>
<string name="pref_plugin_mousepad_desc">Použiť váš telefón alebo tablet ako touchpad a klávesnicu</string>
<string name="pref_plugin_remotekeyboard">Prijímať vzdialené stlačenia klávesov</string>
<string name="pref_plugin_remotekeyboard_desc">Prijímať udalosti stlačení klávesov od vzdialených zariadení</string>
<string name="pref_plugin_mpris">Multimediálne ovládače</string>
<string name="pref_plugin_mpris_desc">Poskytuje vzdialené ovládanie pre váš prehrávač médií</string>
<string name="pref_plugin_runcommand">Spustiť príkaz</string>
@ -32,10 +30,6 @@
<string name="no_permissions">Musíte povoliť oprávnenia na prístup k pripomienkam</string>
<string name="send_ping">Poslať ping</string>
<string name="open_mpris_controls">Multimediálny ovládač</string>
<string name="remotekeyboard_editing_only_title">Spracúva vzdialené klávesy len pri editácii</string>
<string name="remotekeyboard_not_connected">Nie sú žiadne aktívne pripojenia vzdialenej klávesnice, vytvorte nejaké v Kdeconnect</string>
<string name="remotekeyboard_connected">Vzdialené pripojenie klávesnice je aktívne</string>
<string name="remotekeyboard_multiple_connections">Je viac ako jedno vzdialené pripojenie klávesnice, vyberte zariadenie na nastavenie</string>
<string name="open_mousepad">Vzdialený vstup</string>
<string name="mousepad_info">Posúvajte prst na obrazovke na posun kurzora. Ťuknutie vyvolá klik a použite dva/tri prsty pre pravé a stredné tlačidlo. Použite dlhé stlačenie pre drag and drop.</string>
<string name="mousepad_double_tap_settings_title">Nastaviť akciu dvoch prstov</string>
@ -47,9 +41,6 @@
<item>Stredný klik</item>
<item>Nič</item>
</string-array>
<string name="mousepad_double_default">vpravo</string>
<string name="mousepad_triple_default">stred</string>
<string name="mousepad_sensitivity_default">predvolené</string>
<string-array name="mousepad_sensitivity_entries">
<item>Najpomalšie</item>
<item>Nad najpomalším</item>
@ -85,15 +76,12 @@
<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_files_title">Posielam súbor pre %1s</string>
<string name="outgoing_file_text">%1s</string>
<string name="outgoing_files_text">Poslať %1$d z %2$d súborov</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>
<string name="sent_file_title">Poslať súbor pre %1s</string>
<string name="sent_file_text">%1s</string>
<string name="sent_file_failed_title">Zlyhalo poslanie súboru %1s</string>
<string name="sent_file_failed_text">%1s</string>
<string name="tap_to_answer">Tapnite na odpoveď</string>
<string name="reconnect">Znovu pripojiť</string>
@ -140,10 +128,6 @@
<string name="custom_device_list">Pridať zariadenia podľa IP</string>
<string name="share_notification_preference">Hlučné pripomienky</string>
<string name="share_notification_preference_summary">Vibrovať a prehrať zvuk pri prijatí súboru</string>
<string name="share_destination_customize">Prispôsobiť cieľový adresár</string>
<string name="share_destination_customize_summary_disabled">Prijaté súbory sa objavia v Preberaniach</string>
<string name="share_destination_customize_summary_enabled">Súbory sa uložia v adresári dolu</string>
<string name="share_destination_folder_preference">Cieľový adresár</string>
<string name="title_activity_notification_filter">Filter upozornení</string>
<string name="filter_apps_info">Upozornenia budú synchronizované pre vybrané aplikácie.</string>
<string name="sftp_internal_storage">Interné úložisko</string>
@ -165,7 +149,6 @@
<string name="device_rename_confirm">Premenovať</string>
<string name="refresh">Obnoviť</string>
<string name="unreachable_description">Toto spárované zariadenie nie je dosiahnuteľné. Prosím, uistite sa, že je pripojené do rovnakej siete.</string>
<string name="on_data_message">Zdá sa, že ste na mobilom dátovom pripojení. KDE Connect funguje iba na lokálnej sieti.</string>
<string name="no_file_browser">Nie sú nainštalované žiadne prehliadače.</string>
<string name="pref_plugin_telepathy">Poslať SMS</string>
<string name="pref_plugin_telepathy_desc">Posielať textové správy z vášho počítača</string>

View File

@ -176,4 +176,7 @@
<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>
</resources>

View File

@ -8,10 +8,10 @@
<string name="pref_plugin_sftp_desc">Gör det möjligt att bläddra i apparatens filsystem från annan apparat</string>
<string name="pref_plugin_clipboard">Synkronisera klippbord</string>
<string name="pref_plugin_clipboard_desc">Dela klippbordets innehåll</string>
<string name="pref_plugin_mousepad">Fjärrinmatning</string>
<string name="pref_plugin_mousepad">Extern inmatning</string>
<string name="pref_plugin_mousepad_desc">Använd telefonen eller surfplattan som mus och tangentbord</string>
<string name="pref_plugin_remotekeyboard">Ta emot fjärrtangentnedtryckningar</string>
<string name="pref_plugin_remotekeyboard_desc">Ta emot tangentnedtryckningar från fjärrenheter</string>
<string name="pref_plugin_remotekeyboard">Ta emot externa tangentnedtryckningar</string>
<string name="pref_plugin_remotekeyboard_desc">Ta emot tangentnedtryckningar från externa enheter</string>
<string name="pref_plugin_mpris">Multimediakontroller</string>
<string name="pref_plugin_mpris_desc">Tillhandahåller en fjärrkontroll för mediaspelaren</string>
<string name="pref_plugin_runcommand">Kör kommando</string>
@ -32,11 +32,11 @@
<string name="no_permissions">Du måste ge rättighet att komma åt underrättelser</string>
<string name="send_ping">Skicka ping</string>
<string name="open_mpris_controls">Kontroll av multimedia</string>
<string name="remotekeyboard_editing_only_title">Hantera bara fjärrtangenter vid redigering</string>
<string name="remotekeyboard_not_connected">Det finns ingen aktiv fjärrtangentbordsanslutning, upprätta en i KDE-anslut</string>
<string name="remotekeyboard_connected">Fjärrtangentbordsanslutning är aktiv</string>
<string name="remotekeyboard_multiple_connections">Det finns mer än en fjärrtangentbordsanslutning, välj enhet att anpassa</string>
<string name="open_mousepad">Fjärrinmatning</string>
<string name="remotekeyboard_editing_only_title">Hantera bara externa tangenter vid redigering</string>
<string name="remotekeyboard_not_connected">Det finns ingen aktiv anslutning till externt tangentbord, upprätta en i KDE-anslut</string>
<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_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>
@ -47,9 +47,6 @@
<item>Mittenklick</item>
<item>Ingenting</item>
</string-array>
<string name="mousepad_double_default">höger</string>
<string name="mousepad_triple_default">mitten</string>
<string name="mousepad_sensitivity_default">normal</string>
<string-array name="mousepad_sensitivity_entries">
<item>Långsammaste</item>
<item>Ovanför långsammaste</item>
@ -176,4 +173,7 @@
<string name="findmyphone_found">Hittade den</string>
<string name="open">Öppna</string>
<string name="close">Stäng</string>
<string name="no_permissions_storage">Du måste ge rättighet att komma åt lagringen</string>
<string name="plugins_need_permission">Vissa insticksprogram kräver rättigheter för att fungera (rör för mer information):</string>
<string name="permission_explanation">Insticksprogrammet behöver rättigheter för att fungera</string>
</resources>

179
res/values-tr/strings.xml Normal file
View File

@ -0,0 +1,179 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<string name="pref_plugin_telephony">Telefon bildiricisi</string>
<string name="pref_plugin_telephony_desc">SMS ve çağrılar için bildirimler yolla</string>
<string name="pref_plugin_battery">Batarya raporu</string>
<string name="pref_plugin_battery_desc">Batarya durumunu belirli aralıklarla raporla</string>
<string name="pref_plugin_sftp">Dosya sistemi gösterme</string>
<string name="pref_plugin_sftp_desc">Bu aıygıtın dosya sistemine uzaktan gözatılmasına izin verir</string>
<string name="pref_plugin_clipboard">Pano eşitleme</string>
<string name="pref_plugin_clipboard_desc">Pano içeriğini paylaş</string>
<string name="pref_plugin_mousepad">Uzak girdi</string>
<string name="pref_plugin_mousepad_desc">Telefonunuzu veya tabletinizi, dokunmatik veya klavye olarak kullanın</string>
<string name="pref_plugin_remotekeyboard">Uzak tuşa basmaları getir</string>
<string name="pref_plugin_remotekeyboard_desc">Tuş basma eylemlerini, uzak aygıtlardan getir</string>
<string name="pref_plugin_mpris">Çoklu ortam denetimleri</string>
<string name="pref_plugin_mpris_desc">Ortam oynatıcınız için uzak denetim sağlar</string>
<string name="pref_plugin_runcommand">Komut Çalıştır</string>
<string name="pref_plugin_runcommand_desc">Uzak komutları, telefon veya tabletinizden tetikler</string>
<string name="pref_plugin_ping">Ping</string>
<string name="pref_plugin_ping_desc">Ping gönder ve al</string>
<string name="pref_plugin_notifications">Bildirim eşitleme</string>
<string name="pref_plugin_notifications_desc">Bildirimlerinize, diğer aygıtlardan erişin</string>
<string name="pref_plugin_receive_notifications">Bildirimleri al</string>
<string name="pref_plugin_receive_notifications_desc">Bildirimleri diğer aygıtlardan al ve Android üzerinde göster</string>
<string name="pref_plugin_sharereceiver">Paylaş ve al</string>
<string name="pref_plugin_sharereceiver_desc">Dosyaları ve URL\'leri aygıtlar arasında paylaş</string>
<string name="plugin_not_available">Bu özellik, sahip olduğunuz Android sürümünde kullanılabilir değil</string>
<string name="device_list_empty">Aygıt yok</string>
<string name="ok">Tamam</string>
<string name="cancel">İptal</string>
<string name="open_settings">Ayarları</string>
<string name="no_permissions">Bildirimler erişebilmek için izine ihtiyacınız var</string>
<string name="send_ping">Ping gönder</string>
<string name="open_mpris_controls">Çoklu ortam denetimi</string>
<string name="remotekeyboard_editing_only_title">Uzak tuşları, sadece düzenleme yaparken işle</string>
<string name="remotekeyboard_not_connected">Etkin bir uzak klavye bağlantısı yok, kdeconnect ile bir bağlantı kurun</string>
<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>
<string name="mousepad_scroll_direction_title">Ters Kaydırma Yönü</string>
<string-array name="mousepad_tap_entries">
<item>Sağ tık</item>
<item>Orta tık</item>
<item>Hiçbiri</item>
</string-array>
<string-array name="mousepad_sensitivity_entries">
<item>En Yavaş</item>
<item>En Yavaşın Üstü</item>
<item>Varsayıla</item>
<item>Varsayılan Üstü</item>
<item>En Hızlı</item>
</string-array>
<string name="category_connected_devices">Bağlı aygıtlar</string>
<string name="category_not_paired_devices">Kullanılabilir aygıtlar</string>
<string name="category_remembered_devices">Hatırlanan aygıtlar</string>
<string name="plugins_failed_to_load">Eklentiler yüklenemedi (daha fazla bilgi için dokunun):</string>
<string name="device_menu_plugins">Eklenti ayarları</string>
<string name="device_menu_unpair">Ayır</string>
<string name="device_not_reachable">Eşleşmiş aygıt ulaşılabilir değil</string>
<string name="pair_new_device">Yeni bir aygıt eşleştir</string>
<string name="unknown_device">Bİlinmeyen aygıt</string>
<string name="error_not_reachable">Aygıt ulaşılabilir değil</string>
<string name="error_already_requested">Eşleşme zaten talep edilmiş</string>
<string name="error_already_paired">Aygıt zaten eşleşmiş</string>
<string name="error_could_not_send_package">Paket gönderilemedi</string>
<string name="error_timed_out">Zaman aşımı</string>
<string name="error_canceled_by_user">Kullanıcı tarafından iptal edildi</string>
<string name="error_canceled_by_other_peer">Diğer eş tarafından iptal edildi</string>
<string name="error_invalid_key">Geçersiz anahtar alındı</string>
<string name="encryption_info_title">Şifreleme Bilgisi</string>
<string name="encryption_info_msg_no_ssl">Diğer aygıt, KDE Connect\'in son sürümünü kullanmıyor, eski şifreleme yöntemini kullanıyor.</string>
<string name="my_device_fingerprint">Aygıt sertifikanızın SHA1 parmak izi:</string>
<string name="remote_device_fingerprint">Uzak aygıt sertifikanızın SHA1 parmak izi:</string>
<string name="pair_requested">Eşleşme talep edildi</string>
<string name="pairing_request_from">%1s için eşleşme talebi</string>
<string name="received_url_title">%1s üzerinden bağlantı alındı</string>
<string name="received_url_text">\'%1s\' açmak için dokunun</string>
<string name="incoming_file_title">%1s üzerinden gelen dosya</string>
<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>
<string name="sent_file_title">Dosyayı şuraya gönder, %1s</string>
<string name="sent_file_text">%1s</string>
<string name="sent_file_failed_title">Dosyayı şuraya gönderme başarısız, %1s</string>
<string name="sent_file_failed_text">%1s</string>
<string name="tap_to_answer">Cevap için dokunun</string>
<string name="reconnect">Yeniden Bağlan</string>
<string name="right_click">Sağ Tık Gönder</string>
<string name="middle_click">Orta Tık Gönder</string>
<string name="show_keyboard">Klavyeyi Göster</string>
<string name="device_not_paired">Aygıt eşleşmemiş</string>
<string name="request_pairing">Eşleşme isteği</string>
<string name="pairing_accept">Onayla</string>
<string name="pairing_reject">Reddet</string>
<string name="device">Aygıt</string>
<string name="pair_device">Aygıt eşleştir</string>
<string name="remote_control">Uzak denetim</string>
<string name="settings">KDE Connect Ayarları</string>
<string name="mpris_play">Oynat</string>
<string name="mpris_previous">Önceki</string>
<string name="mpris_rew">Geri Sar</string>
<string name="mpris_ff">Hızlı İleri Sar</string>
<string name="mpris_next">Sonraki</string>
<string name="mpris_volume">Ses</string>
<string name="mpris_settings">Çoklu Ortam Ayarları</string>
<string name="mpris_time_settings_title">İleri/geri düğmeleri</string>
<string name="mpris_time_settings_summary">Basıldığında kullanılacak ileri/geri zamanını ayarlayın.</string>
<string-array name="mpris_time_entries">
<item>10 saniye</item>
<item>20 saniye</item>
<item>30 saniye</item>
<item>1 dakika</item>
<item>2 dakika</item>
</string-array>
<string name="share_to">Paylaş...</string>
<string name="protocol_version_older">Bu aygıt, eski bir protokol sürümü kullanıyor</string>
<string name="protocol_version_newer">Bu aygıt, daha yeni bir protokol sürümü kullanıyor</string>
<string name="general_settings">Genel Ayarlar</string>
<string name="plugin_settings">Ayarlar</string>
<string name="plugin_settings_with_name">%s ayarları</string>
<string name="device_name">Aygıt adı</string>
<string name="device_name_preference_summary">%s</string>
<string name="invalid_device_name">Geçersiz aygıt adı</string>
<string name="shareplugin_text_saved">Gelen ileti, panoya kaydet</string>
<string name="custom_devices_settings">Özel aygıt listesi</string>
<string name="pair_device_action">Yeni bir aygıt eşleştir</string>
<string name="unpair_device_action">Ayır %s</string>
<string name="custom_device_list">IP\'ye göre aygıtları ekle</string>
<string name="share_notification_preference">Sesli bildirimler</string>
<string name="share_notification_preference_summary">Bir dosya alırken, ses çıkar ve titret</string>
<string name="share_destination_customize">Hedef dizini özelleştir</string>
<string name="share_destination_customize_summary_disabled">Gelen dosyalar İndirilenler\'de gözükecektir</string>
<string name="share_destination_customize_summary_enabled">Dosyalar aşağıdaki dizinden depolanacaktır</string>
<string name="share_destination_folder_preference">Hedef dizin</string>
<string name="title_activity_notification_filter">Bildirim süzgeci</string>
<string name="filter_apps_info">Bildirimler, seçili uygulamalar için eşitlenecektir.</string>
<string name="sftp_internal_storage">Harici depolama</string>
<string name="sftp_all_files">Tüm dosyalar</string>
<string name="sftp_sdcard_num">SD kart %d</string>
<string name="sftp_sdcard">SD kart</string>
<string name="sftp_readonly">(salt okunur)</string>
<string name="sftp_camera">Kamera resimleri</string>
<string name="add_host">Makine/IP ekle</string>
<string name="add_host_hint">Makine adı veya IP</string>
<string name="no_players_connected">Onatıcı bulunamadı</string>
<string name="custom_dev_list_help">Bu seçeneği, sadece aygıtınız otomatik bulunamadıysa kullanın. Aşağıya IP adresini veya makine adının girin ve listeye eklemek için düğmeye dokunun. Listeden bir ögeyi silmek için, mevcut ögeye tıklayın.</string>
<string name="mpris_player_on_device">%2$s üzerindeki %1$s</string>
<string name="send_files">Dosyaları gönder</string>
<string name="pairing_title">KDE Connect Aygıtları</string>
<string name="pairing_description">KDE Connect\'te çalışan, aynı ağdaki diğer aygıtlar burada gözükmelidir.</string>
<string name="device_paired">Aygıt eşleştirildi</string>
<string name="device_rename_title">Aygıtı yeniden adlandır</string>
<string name="device_rename_confirm">Yeniden adlandır</string>
<string name="refresh">Tazele</string>
<string name="unreachable_description">Eşleştirilmiş aygıt ulaşılabilir değil. Aynı ağa bağlı olduğundan emin olun.</string>
<string name="on_data_message">Mobil veri bağlantısında olduğunuz gözüküyor. KDE Connect sadece yerel ağlarda çalışır.</string>
<string name="no_file_browser">Yüklü bir dosya tarayıcısı yok.</string>
<string name="pref_plugin_telepathy">SMS Gönder</string>
<string name="pref_plugin_telepathy_desc">Masaüstünden metin iletisi gönder</string>
<string name="plugin_not_supported">Eklenti, aygıt tarafından desteklenmiyor</string>
<string name="findmyphone_title">Telefonumu bul</string>
<string name="findmyphone_title_tablet">Tabletimi bul</string>
<string name="findmyphone_description">Aygıtı bulmak için onu çaldır</string>
<string name="findmyphone_found">Bulundu</string>
<string name="open"></string>
<string name="close">Kapat</string>
<string name="no_permissions_storage">Depolamaya erişim için izne ihtiyacınız var</string>
<string name="plugins_need_permission">Bazı Eklentiler çalışmak için izne ihtiyaç duyar (daha fazla bilgi için dokunun):</string>
<string name="permission_explanation">Bu eklenti, çalışmak için izne ihtiyaç duyuyor</string>
</resources>

View File

@ -47,9 +47,6 @@
<item>Клацання середньою</item>
<item>Нічого</item>
</string-array>
<string name="mousepad_double_default">права</string>
<string name="mousepad_triple_default">середня</string>
<string name="mousepad_sensitivity_default">типва</string>
<string-array name="mousepad_sensitivity_entries">
<item>Найповільніший</item>
<item>Швидший за найповільніший</item>
@ -176,4 +173,7 @@
<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>
</resources>

View File

@ -47,9 +47,6 @@
<item>中键点击</item>
<item></item>
</string-array>
<string name="mousepad_double_default"></string>
<string name="mousepad_triple_default"></string>
<string name="mousepad_sensitivity_default">默认</string>
<string-array name="mousepad_sensitivity_entries">
<item>最慢</item>
<item>高于最慢</item>
@ -170,6 +167,9 @@
<string name="pref_plugin_telepathy_desc">从桌面发送短消息</string>
<string name="plugin_not_supported">设备不支持此插件</string>
<string name="findmyphone_title">找到我的手机</string>
<string name="findmyphone_title_tablet">找到我的平板电脑</string>
<string name="findmyphone_description">让设备响铃从而找到它</string>
<string name="findmyphone_found">找到</string>
<string name="open">打开</string>
<string name="close">关闭</string>
</resources>

View File

@ -41,9 +41,6 @@
<item>中鍵點擊</item>
<item></item>
</string-array>
<string name="mousepad_double_default"></string>
<string name="mousepad_triple_default"></string>
<string name="mousepad_sensitivity_default">預設</string>
<string-array name="mousepad_sensitivity_entries">
<item></item>
<item>最慢</item>

View File

@ -53,9 +53,9 @@
<item>Middle click</item>
<item>Nothing</item>
</string-array>
<string name="mousepad_double_default">right</string>
<string name="mousepad_triple_default">middle</string>
<string name="mousepad_sensitivity_default">default</string>
<string name="mousepad_default_double" translatable="false">right</string>
<string name="mousepad_default_triple" translatable="false">middle</string>
<string name="mousepad_default_sensitivity" translatable="false">default</string>
<string-array name="mousepad_tap_values" translatable="false">
<item>right</item>
<item>middle</item>
@ -206,4 +206,8 @@
<string name="open">Open</string>
<string name="close">Close</string>
<string name="no_permissions_storage">You need to grant permissions to access the storage</string>
<string name="plugins_need_permission">Some Plugins need permissions to work (tap for more info):</string>
<string name="permission_explanation">This plugin needs permissions to work</string>
</resources>

View File

@ -5,30 +5,30 @@
<ListPreference
android:id="@+id/mousepad_double_tap_preference"
android:key="@string/mousepad_double_tap_key"
android:title="@string/mousepad_double_tap_settings_title"
android:summary="%s"
android:defaultValue="@string/mousepad_default_double"
android:entries="@array/mousepad_tap_entries"
android:entryValues="@array/mousepad_tap_values"
android:defaultValue="@string/mousepad_double_default" />
android:key="@string/mousepad_double_tap_key"
android:summary="%s"
android:title="@string/mousepad_double_tap_settings_title"/>
<ListPreference
android:id="@+id/mousepad_triple_tap_preference"
android:key="@string/mousepad_triple_tap_key"
android:title="@string/mousepad_triple_tap_settings_title"
android:summary="%s"
android:defaultValue="@string/mousepad_default_triple"
android:entries="@array/mousepad_tap_entries"
android:entryValues="@array/mousepad_tap_values"
android:defaultValue="@string/mousepad_triple_default" />
android:key="@string/mousepad_triple_tap_key"
android:summary="%s"
android:title="@string/mousepad_triple_tap_settings_title"/>
<ListPreference
android:id="@+id/mousepad_sensitivity_preference"
android:key="@string/mousepad_sensitivity_key"
android:title="@string/mousepad_sensitivity_settings_title"
android:summary="%s"
android:defaultValue="@string/mousepad_default_sensitivity"
android:entries="@array/mousepad_sensitivity_entries"
android:entryValues="@array/mousepad_sensitivity_values"
android:defaultValue="@string/mousepad_sensitivity_default" />
android:key="@string/mousepad_sensitivity_key"
android:summary="%s"
android:title="@string/mousepad_sensitivity_settings_title"/>
<CheckBoxPreference
android:id="@+id/mousepad_scroll_preference"

View File

@ -0,0 +1,248 @@
/*
* Copyright 2016 Saikrishna Arcot <saiarcot895@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.Backends.BluetoothBackend;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
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 java.io.*;
import java.nio.charset.Charset;
import java.security.PublicKey;
import java.util.UUID;
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class BluetoothLink extends BaseLink {
private final BluetoothSocket socket;
private final BluetoothLinkProvider linkProvider;
private boolean continueAccepting = true;
private Thread receivingThread = new Thread(new Runnable() {
@Override
public void run() {
StringBuilder sb = new StringBuilder();
try {
Reader reader = new InputStreamReader(socket.getInputStream(), "UTF-8");
char[] buf = new char[512];
while (continueAccepting) {
while (sb.indexOf("\n") == -1 && continueAccepting) {
int charsRead;
if ((charsRead = reader.read(buf)) > 0) {
sb.append(buf, 0, charsRead);
}
}
int endIndex = sb.indexOf("\n");
if (endIndex != -1) {
String message = sb.substring(0, endIndex + 1);
sb.delete(0, endIndex + 1);
processMessage(message);
}
}
} catch (IOException e) {
Log.e("BluetoothLink/receiving", "Connection to " + socket.getRemoteDevice().getAddress() + " likely broken.", e);
disconnect();
}
}
private void processMessage(String message) {
NetworkPackage np;
try {
np = NetworkPackage.unserialize(message);
} catch (JSONException e) {
Log.e("BluetoothLink/receiving", "Unable to parse message.", e);
return;
}
if (np.getType().equals(NetworkPackage.PACKAGE_TYPE_ENCRYPTED)) {
try {
np = RsaHelper.decrypt(np, privateKey);
} catch(Exception e) {
Log.e("BluetoothLink/receiving", "Exception decrypting the package", e);
}
}
if (np.hasPayloadTransferInfo()) {
BluetoothSocket transferSocket = null;
try {
UUID transferUuid = UUID.fromString(np.getPayloadTransferInfo().getString("uuid"));
transferSocket = socket.getRemoteDevice().createRfcommSocketToServiceRecord(transferUuid);
transferSocket.connect();
np.setPayload(transferSocket.getInputStream(), np.getPayloadSize());
} catch (Exception e) {
if (transferSocket != null) {
try { transferSocket.close(); } catch(IOException ignored) { }
}
Log.e("BluetoothLink/receiving", "Unable to get payload", e);
}
}
packageReceived(np);
}
});
public BluetoothLink(Context context, BluetoothSocket socket, String deviceId, BluetoothLinkProvider linkProvider) {
super(context, deviceId, linkProvider);
this.socket = socket;
this.linkProvider = linkProvider;
}
public void startListening() {
this.receivingThread.start();
}
@Override
public String getName() {
return "BluetoothLink";
}
@Override
public BasePairingHandler getPairingHandler(Device device, BasePairingHandler.PairingHandlerCallback callback) {
return new BluetoothPairingHandler(device, callback);
}
public void disconnect() {
if (socket == null) {
return;
}
continueAccepting = false;
try {
socket.close();
} catch (IOException e) {
}
linkProvider.disconnectedLink(this, getDeviceId(), socket);
}
private void sendMessage(NetworkPackage 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");
socket.write(message);
Log.i("BluetoothLink","Finished sending message");
}
@Override
public boolean sendPackage(NetworkPackage np, Device.SendPackageStatusCallback callback) {
return sendPackageInternal(np, callback, null);
}
@Override
public boolean sendPackageEncrypted(NetworkPackage np, Device.SendPackageStatusCallback callback, PublicKey key) {
return sendPackageInternal(np, callback, key);
}
private boolean sendPackageInternal(NetworkPackage np, final Device.SendPackageStatusCallback callback, PublicKey key) {
/*if (!isConnected()) {
Log.e("BluetoothLink", "sendPackageEncrypted failed: not connected");
callback.sendFailure(new Exception("Not connected"));
return;
}*/
try {
BluetoothServerSocket serverSocket = null;
if (np.hasPayload()) {
UUID transferUuid = UUID.randomUUID();
serverSocket = BluetoothAdapter.getDefaultAdapter()
.listenUsingRfcommWithServiceRecord("KDE Connect Transfer", transferUuid);
JSONObject payloadTransferInfo = new JSONObject();
payloadTransferInfo.put("uuid", transferUuid.toString());
np.setPayloadTransferInfo(payloadTransferInfo);
}
if (key != null) {
try {
np = RsaHelper.encrypt(np, key);
} catch (Exception e) {
callback.onFailure(e);
return false;
}
}
sendMessage(np);
if (serverSocket != null) {
BluetoothSocket transferSocket = serverSocket.accept();
try {
serverSocket.close();
int idealBufferLength = 4096;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& transferSocket.getMaxReceivePacketSize() > 0) {
idealBufferLength = transferSocket.getMaxReceivePacketSize();
}
byte[] buffer = new byte[idealBufferLength];
int bytesRead;
long progress = 0;
InputStream stream = np.getPayload();
while ((bytesRead = stream.read(buffer)) != -1) {
progress += bytesRead;
transferSocket.getOutputStream().write(buffer, 0, bytesRead);
if (np.getPayloadSize() > 0) {
callback.onProgressChanged((int) (100 * progress / np.getPayloadSize()));
}
}
transferSocket.getOutputStream().flush();
stream.close();
} catch (Exception e) {
callback.onFailure(e);
return false;
} finally {
try { transferSocket.close(); } catch (IOException ignored) { }
}
}
callback.onSuccess();
return true;
} catch (Exception e) {
callback.onFailure(e);
return false;
}
}
@Override
public boolean linkShouldBeKeptAlive() {
return receivingThread.isAlive();
}
/*
public boolean isConnected() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
return socket.isConnected();
} else {
return true;
}
}
*/
}

View File

@ -0,0 +1,378 @@
/*
* Copyright 2016 Saikrishna Arcot <saiarcot895@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.Backends.BluetoothBackend;
import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.bluetooth.BluetoothServerSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Parcelable;
import android.util.Log;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.Set;
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class BluetoothLinkProvider extends BaseLinkProvider {
private static final UUID SERVICE_UUID = UUID.fromString("185f3df4-3268-4e3f-9fca-d4d5059915bd");
private static final int REQUEST_ENABLE_BT = 48;
private final Context context;
private final Map<String, BluetoothLink> visibleComputers = new HashMap<>();
private final Map<BluetoothDevice, BluetoothSocket> sockets = new HashMap<>();
private BluetoothAdapter bluetoothAdapter = null;
private ServerRunnable serverRunnable;
private ClientRunnable clientRunnable;
private void addLink(NetworkPackage identityPackage, BluetoothLink link) {
String deviceId = identityPackage.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);
link.startListening();
if (oldLink != null) {
Log.i("BluetoothLinkProvider","Removing old connection to same device");
oldLink.disconnect();
}
}
public BluetoothLinkProvider(Context context) {
this.context = context;
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Log.e("BluetoothLinkProvider","No bluetooth adapter found.");
}
}
@Override
public void onStart() {
if (bluetoothAdapter == null) {
return;
}
if (!bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
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.
return;
}
//This handles the case when I'm the existing device in the network and receive a hello package
clientRunnable = new ClientRunnable();
new Thread(clientRunnable).start();
// I'm on a new network, let's be polite and introduce myself
serverRunnable = new ServerRunnable();
new Thread(serverRunnable).start();
}
@Override
public void onNetworkChange() {
onStop();
onStart();
}
@Override
public void onStop() {
if (bluetoothAdapter == null || clientRunnable == null || serverRunnable == null) {
return;
}
clientRunnable.stopProcessing();
serverRunnable.stopProcessing();
}
@Override
public String getName() {
return "BluetoothLinkProvider";
}
public void disconnectedLink(BluetoothLink link, String deviceId, BluetoothSocket socket) {
sockets.remove(socket.getRemoteDevice());
visibleComputers.remove(deviceId);
connectionLost(link);
}
private class ServerRunnable implements Runnable {
private boolean continueProcessing = true;
private BluetoothServerSocket serverSocket;
void stopProcessing() {
continueProcessing = false;
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
try {
serverSocket = bluetoothAdapter
.listenUsingRfcommWithServiceRecord("KDE Connect", SERVICE_UUID);
} catch (IOException e) {
e.printStackTrace();
return;
}
if (continueProcessing) {
try {
BluetoothSocket socket = serverSocket.accept();
connect(socket);
} catch (Exception ignored) {
}
}
}
private void connect(BluetoothSocket socket) throws Exception {
//socket.connect();
OutputStream outputStream = socket.getOutputStream();
if (sockets.containsKey(socket.getRemoteDevice())) {
Log.i("BTLinkProvider/Server", "Received duplicate connection from " + socket.getRemoteDevice().getAddress());
socket.close();
return;
} else {
sockets.put(socket.getRemoteDevice(), socket);
}
Log.i("BTLinkProvider/Server", "Received connection from " + socket.getRemoteDevice().getAddress());
NetworkPackage np = NetworkPackage.createIdentityPackage(context);
byte[] message = np.serialize().getBytes("UTF-8");
outputStream.write(message);
Log.i("BTLinkProvider/Server", "Sent identity package");
// Listen for the response
StringBuilder sb = new StringBuilder();
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) {
sb.append(buf, 0, charsRead);
}
String response = sb.toString();
final NetworkPackage identityPackage = NetworkPackage.unserialize(response);
if (!identityPackage.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
Log.e("BTLinkProvider/Server", "2 Expecting an identity package");
return;
}
Log.i("BTLinkProvider/Server", "Received identity package");
BluetoothLink link = new BluetoothLink(context, socket,
identityPackage.getString("deviceId"), BluetoothLinkProvider.this);
addLink(identityPackage, link);
}
}
private class ClientRunnable extends BroadcastReceiver implements Runnable {
private boolean continueProcessing = true;
private Map<BluetoothDevice, Thread> connectionThreads = new HashMap<>();
void stopProcessing() {
continueProcessing = false;
}
@Override
public void run() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_UUID);
context.registerReceiver(this, filter);
}
while (continueProcessing) {
connectToDevices();
try {
Thread.sleep(15000);
} catch (InterruptedException ignored) {
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
context.unregisterReceiver(this);
}
}
private void connectToDevices() {
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
Log.i("BluetoothLinkProvider", "Bluetooth adapter paired devices: " + pairedDevices.size());
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
if (sockets.containsKey(device)) {
continue;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
device.fetchUuidsWithSdp();
} else {
connectToDevice(device);
}
}
}
@Override
@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)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Parcelable[] activeUuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID);
if (sockets.containsKey(device)) {
return;
}
if (activeUuids == null) {
return;
}
for (Parcelable uuid: activeUuids) {
if (uuid.toString().equals(SERVICE_UUID.toString())) {
connectToDevice(device);
return;
}
}
}
}
private void connectToDevice(BluetoothDevice device) {
if (!connectionThreads.containsKey(device) || !connectionThreads.get(device).isAlive()) {
Thread connectionThread = new Thread(new ClientConnect(device));
connectionThread.start();
connectionThreads.put(device, connectionThread);
}
}
}
private class ClientConnect implements Runnable {
private final BluetoothDevice device;
public ClientConnect(BluetoothDevice device) {
this.device = device;
}
@Override
public void run() {
connectToDevice();
}
private void connectToDevice() {
BluetoothSocket socket;
try {
socket = device.createRfcommSocketToServiceRecord(SERVICE_UUID);
socket.connect();
sockets.put(device, socket);
} catch (IOException e) {
Log.e("BTLinkProvider/Client", "Could not connect to KDE Connect service on " + device.getAddress(), e);
return;
}
Log.i("BTLinkProvider/Client", "Connected to " + device.getAddress());
try {
int character;
StringBuilder sb = new StringBuilder();
while(sb.lastIndexOf("\n") == -1 && (character = socket.getInputStream().read()) != -1) {
sb.append((char)character);
}
String message = sb.toString();
final NetworkPackage identityPackage = NetworkPackage.unserialize(message);
if (!identityPackage.getType().equals(NetworkPackage.PACKAGE_TYPE_IDENTITY)) {
Log.e("BTLinkProvider/Client", "1 Expecting an identity package");
socket.close();
return;
}
Log.i("BTLinkProvider/Client", "Received identity package");
String myId = NetworkPackage.createIdentityPackage(context).getString("deviceId");
if (identityPackage.getString("deviceId").equals(myId)) {
// Probably won't happen, but just to be safe
socket.close();
return;
}
if (visibleComputers.containsKey(identityPackage.getString("deviceId"))) {
return;
}
Log.i("BTLinkProvider/Client", "Identity package received, creating link");
final BluetoothLink link = new BluetoothLink(context, socket,
identityPackage.getString("deviceId"), BluetoothLinkProvider.this);
NetworkPackage np2 = NetworkPackage.createIdentityPackage(context);
link.sendPackage(np2,new Device.SendPackageStatusCallback() {
@Override
public void onSuccess() {
addLink(identityPackage, link);
}
@Override
public void onFailure(Throwable e) {
}
});
} catch (Exception e) {
Log.e("BTLinkProvider/Client", "Connection lost/disconnected on " + device.getAddress(), e);
}
}
}
}

View File

@ -0,0 +1,193 @@
/*
* Copyright 2015 Vineet Garg <grg.vineet@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kde.kdeconnect.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_tp.R;
import java.util.Timer;
import java.util.TimerTask;
public class BluetoothPairingHandler extends BasePairingHandler {
Timer mPairingTimer;
public BluetoothPairingHandler(Device device, final PairingHandlerCallback callback) {
super(device, callback);
if (device.isPaired()) {
mPairStatus = PairStatus.Paired;
} else {
mPairStatus = PairStatus.NotPaired;
}
}
// @Override
public NetworkPackage createPairPackage() {
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);
np.set("pair", true);
return np;
}
@Override
public void packageReceived(NetworkPackage np) throws Exception{
boolean wantsPair = np.getBoolean("pair");
if (wantsPair == isPaired()) {
if (mPairStatus == PairStatus.Requested) {
//Log.e("Device","Unpairing (pair rejected)");
mPairStatus = PairStatus.NotPaired;
hidePairingNotification();
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_canceled_by_other_peer));
}
return;
}
if (wantsPair) {
if (mPairStatus == PairStatus.Requested) { //We started pairing
hidePairingNotification();
pairingDone();
} else {
// If device is already paired, accept pairing silently
if (mDevice.isPaired()) {
acceptPairing();
return;
}
// Pairing notifications are still managed by device as there is no other way to
// know about notificationId to cancel notification when PairActivity is started
// Even putting notificationId in intent does not work because PairActivity can be
// started from MainActivity too, so then notificationId cannot be set
hidePairingNotification();
mDevice.displayPairingNotification();
mPairingTimer = new Timer();
mPairingTimer.schedule(new TimerTask() {
@Override
public void run() {
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)
mPairStatus = PairStatus.RequestedByPeer;
mCallback.incomingRequest();
}
} else {
Log.i("KDE/Pairing", "Unpair request");
if (mPairStatus == PairStatus.Requested) {
hidePairingNotification();
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_canceled_by_other_peer));
} else if (mPairStatus == PairStatus.Paired) {
mCallback.unpaired();
}
mPairStatus = PairStatus.NotPaired;
}
}
@Override
public void requestPairing() {
Device.SendPackageStatusCallback statusCallback = new Device.SendPackageStatusCallback() {
@Override
public void onSuccess() {
hidePairingNotification(); //Will stop the pairingTimer if it was running
mPairingTimer = new Timer();
mPairingTimer.schedule(new TimerTask() {
@Override
public void run() {
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_timed_out));
Log.w("KDE/Device","Unpairing (timeout A)");
mPairStatus = PairStatus.NotPaired;
}
}, 30*1000); //Time to wait for the other to accept
mPairStatus = PairStatus.Requested;
}
@Override
public void onFailure(Throwable e) {
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_could_not_send_package));
}
};
mDevice.sendPackage(createPairPackage(), statusCallback);
}
public void hidePairingNotification() {
mDevice.hidePairingNotification();
if (mPairingTimer != null) {
mPairingTimer .cancel();
}
}
@Override
public void acceptPairing() {
hidePairingNotification();
Device.SendPackageStatusCallback statusCallback = new Device.SendPackageStatusCallback() {
@Override
public void onSuccess() {
pairingDone();
}
@Override
public void onFailure(Throwable e) {
mCallback.pairingFailed(mDevice.getContext().getString(R.string.error_not_reachable));
}
};
mDevice.sendPackage(createPairPackage(), statusCallback);
}
@Override
public void rejectPairing() {
hidePairingNotification();
mPairStatus = PairStatus.NotPaired;
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);
np.set("pair", false);
mDevice.sendPackage(np);
}
//@Override
public void pairingDone() {
// Store device information needed to create a Device object in a future
//Log.e("KDE/PairingDone", "Pairing Done");
mPairStatus = PairStatus.Paired;
mCallback.pairingDone();
}
@Override
public void unpair() {
mPairStatus = PairStatus.NotPaired;
NetworkPackage np = new NetworkPackage(NetworkPackage.PACKAGE_TYPE_PAIR);
np.set("pair", false);
mDevice.sendPackage(np);
}
}

View File

@ -26,11 +26,13 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import org.kde.kdeconnect.Backends.BaseLink;
import org.kde.kdeconnect.Backends.BaseLinkProvider;
//import org.kde.kdeconnect.Backends.BluetoothBackend.BluetoothLinkProvider;
import org.kde.kdeconnect.Backends.LanBackend.LanLinkProvider;
import org.kde.kdeconnect.Helpers.SecurityHelpers.RsaHelper;
import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper;
@ -140,11 +142,11 @@ public class BackgroundService extends Service {
}
private void registerLinkProviders() {
//linkProviders.add(new LoopbackLinkProvider(this));
linkProviders.add(new LanLinkProvider(this));
// linkProviders.add(new LoopbackLinkProvider(this));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
// linkProviders.add(new BluetoothLinkProvider(this));
}
}
public ArrayList<BaseLinkProvider> getLinkProviders() {

View File

@ -82,7 +82,8 @@ public class Device implements BaseLink.PackageReceiver {
private List<String> m_supportedPlugins = new ArrayList<>();
private final ConcurrentHashMap<String, Plugin> plugins = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, Plugin> failedPlugins = new ConcurrentHashMap<>();
private Map<String, ArrayList<String>> pluginsByIncomingInterface;
private final ConcurrentHashMap<String, Plugin> pluginsWithoutPermissions = new ConcurrentHashMap<>();
private Map<String, ArrayList<String>> pluginsByIncomingInterface = new HashMap<>();
private final SharedPreferences settings;
@ -722,6 +723,16 @@ public class Device implements BaseLink.PackageReceiver {
failedPlugins.put(pluginKey, plugin);
}
if(!plugin.checkRequiredPermissions()){
Log.e("KDE/addPlugin", "No permission " + pluginKey);
plugins.remove(pluginKey);
pluginsWithoutPermissions.put(pluginKey, plugin);
success = false;
} else {
Log.i("KDE/addPlugin", "Permission OK " + pluginKey);
pluginsWithoutPermissions.remove(pluginKey);
}
return success;
}
@ -812,6 +823,10 @@ public class Device implements BaseLink.PackageReceiver {
return failedPlugins;
}
public ConcurrentHashMap<String, Plugin> getPluginsWithoutPermissions() {
return pluginsWithoutPermissions;
}
public void addPluginsChangedListener(PluginsChangedListener listener) {
pluginsChangedListeners.add(listener);
}

View File

@ -97,11 +97,11 @@ public class MousePadActivity extends ActionBarActivity implements GestureDetect
scrollDirection = 1;
}
String doubleTapSetting = prefs.getString(getString(R.string.mousepad_double_tap_key),
getString(R.string.mousepad_double_default));
getString(R.string.mousepad_default_double));
String tripleTapSetting = prefs.getString(getString(R.string.mousepad_triple_tap_key),
getString(R.string.mousepad_triple_default));
getString(R.string.mousepad_default_triple));
String sensitivitySetting = prefs.getString(getString(R.string.mousepad_sensitivity_key),
getString(R.string.mousepad_sensitivity_default));
getString(R.string.mousepad_default_sensitivity));
doubleTapAction = ClickType.fromString(doubleTapSetting);
tripleTapAction = ClickType.fromString(tripleTapSetting);

View File

@ -24,14 +24,18 @@ import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import org.kde.kdeconnect.Helpers.AppsHelper;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.Plugins.Plugin;
@ -39,15 +43,27 @@ import org.kde.kdeconnect.UserInterface.MaterialActivity;
import org.kde.kdeconnect.UserInterface.SettingsActivity;
import org.kde.kdeconnect_tp.R;
import java.io.ByteArrayOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class NotificationsPlugin extends Plugin implements NotificationReceiver.NotificationListener {
public final static String PACKAGE_TYPE_NOTIFICATION = "kdeconnect.notification";
public final static String PACKAGE_TYPE_NOTIFICATION_REQUEST = "kdeconnect.notification.request";
public final static String PACKAGE_TYPE_NOTIFICATION_REPLY = "kdeconnect.notification.reply";
private boolean sendIcons = true;
private Map<String, RepliableNotification> pendingIntents;
/*
private boolean sendIcons = false;
*/
@Override
public String getDisplayName() {
@ -81,6 +97,8 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
@Override
public boolean onCreate() {
pendingIntents = new HashMap<String, RepliableNotification>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
if (hasPermission()) {
NotificationReceiver.RunCommand(context, new NotificationReceiver.InstanceCallback() {
@ -159,6 +177,8 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
String packageName = statusBarNotification.getPackageName();
String appName = AppsHelper.appNameLookup(context, packageName);
if ("com.facebook.orca".equals(packageName) &&
(statusBarNotification.getId() == 10012) &&
"Messenger".equals(appName) &&
@ -182,28 +202,41 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
np.set("silent", true);
np.set("requestAnswer", true); //For compatibility with old desktop versions of KDE Connect that don't support "silent"
}
/*
if (sendIcons) {
try {
Drawable drawableAppIcon = AppsHelper.appIconLookup(context, packageName);
Bitmap appIcon = ImagesHelper.drawableToBitmap(drawableAppIcon);
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
if (appIcon.getWidth() > 128) {
appIcon = Bitmap.createScaledBitmap(appIcon, 96, 96, true);
Bitmap appIcon = notification.largeIcon;
if (appIcon != null) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
if (appIcon.getWidth() > 128) {
appIcon = Bitmap.createScaledBitmap(appIcon, 96, 96, true);
}
appIcon.compress(Bitmap.CompressFormat.PNG, 90, outStream);
byte[] bitmapData = outStream.toByteArray();
np.setPayload(bitmapData);
np.set("payloadHash", getChecksum(bitmapData));
}
appIcon.compress(Bitmap.CompressFormat.PNG, 90, outStream);
byte[] bitmapData = outStream.toByteArray();
np.setPayload(bitmapData);
} catch (Exception e) {
} catch(Exception e){
e.printStackTrace();
Log.e("NotificationsPlugin", "Error retrieving icon");
}
}
*/
RepliableNotification rn = extractRepliableNotification(statusBarNotification);
if(rn.pendingIntent != null) {
np.set("requestReplyId", rn.id);
pendingIntents.put(rn.id, rn);
}
np.set("id", key);
np.set("appName", appName == null? packageName : appName);
np.set("isClearable", statusBarNotification.isClearable());
np.set("ticker", getTickerText(notification));
np.set("title", getNotificationTitle(notification));
np.set("text", getNotificationText(notification));
np.set("time", Long.toString(statusBarNotification.getPostTime()));
if (requestAnswer) {
np.set("requestAnswer", true);
@ -213,6 +246,127 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
device.sendPackage(np);
}
void replyToNotification(String id, String message){
if(pendingIntents.isEmpty() || !pendingIntents.containsKey(id)){
Log.e("NotificationsPlugin", "No such notification");
return;
}
RepliableNotification repliableNotification = pendingIntents.get(id);
if(repliableNotification == null) {
Log.e("NotificationsPlugin", "No such notification");
return;
}
RemoteInput[] remoteInputs = new RemoteInput[repliableNotification.remoteInputs.size()];
Intent localIntent = new Intent();
localIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle localBundle = new Bundle();
int i = 0;
for(RemoteInput remoteIn : repliableNotification.remoteInputs){
getDetailsOfNotification(remoteIn);
remoteInputs[i] = remoteIn;
localBundle.putCharSequence(remoteInputs[i].getResultKey(), message);
i++;
}
RemoteInput.addResultsToIntent(remoteInputs, localIntent, localBundle);
try {
repliableNotification.pendingIntent.send(context, 0, localIntent);
} catch (PendingIntent.CanceledException e) {
Log.e("NotificationPlugin", "replyToNotification error: " + e.getMessage());
}
pendingIntents.remove(id);
}
private void getDetailsOfNotification(RemoteInput remoteInput) {
//Some more details of RemoteInput... no idea what for but maybe it will be useful at some point
String resultKey = remoteInput.getResultKey();
String label = remoteInput.getLabel().toString();
Boolean canFreeForm = remoteInput.getAllowFreeFormInput();
if(remoteInput.getChoices() != null && remoteInput.getChoices().length > 0) {
String[] possibleChoices = new String[remoteInput.getChoices().length];
for(int i = 0; i < remoteInput.getChoices().length; i++){
possibleChoices[i] = remoteInput.getChoices()[i].toString();
}
}
}
private String getNotificationTitle(Notification notification) {
final String TITLE_KEY = "android.title";
final String TEXT_KEY = "android.text";
String title = "";
if(notification != null) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
Bundle extras = notification.extras;
title = extras.getCharSequence(TITLE_KEY).toString();
} catch(Exception e) {
Log.w("NotificationPlugin","problem parsing notification extras for " + notification.tickerText);
e.printStackTrace();
}
}
}
//TODO Add compat for under Kitkat devices
return title;
}
private RepliableNotification extractRepliableNotification(StatusBarNotification statusBarNotification) {
RepliableNotification repliableNotification = new RepliableNotification();
if(statusBarNotification != null) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
Boolean reply = false;
//works for WhatsApp, but not for Telegram
for(Notification.Action act : statusBarNotification.getNotification().actions) {
if(act != null && act.getRemoteInputs() != null) {
repliableNotification.remoteInputs.addAll(Arrays.asList(act.getRemoteInputs()));
repliableNotification.pendingIntent = act.actionIntent;
reply = true;
break;
}
}
repliableNotification.packageName = statusBarNotification.getPackageName();
repliableNotification.tag = statusBarNotification.getTag();//TODO find how to pass Tag with sending PendingIntent, might fix Hangout problem
} catch(Exception e) {
Log.w("NotificationPlugin","problem extracting notification wear for " + statusBarNotification.getNotification().tickerText);
e.printStackTrace();
}
}
}
return repliableNotification;
}
private String getNotificationText(Notification notification) {
final String TEXT_KEY = "android.text";
String text = "";
if(notification != null) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
Bundle extras = notification.extras;
Object extraTextExtra = extras.get(TEXT_KEY);
if (extraTextExtra != null) text = extraTextExtra.toString();
} catch(Exception e) {
Log.w("NotificationPlugin","problem parsing notification extras for " + notification.tickerText);
e.printStackTrace();
}
}
}
//TODO Add compat for under Kitkat devices
return text;
}
/**
* Returns the ticker text of the notification.
@ -234,7 +388,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
if (extraTextExtra != null) extraText = extraTextExtra.toString();
if (extraTitle != null && extraText != null && !extraText.isEmpty()) {
ticker = extraTitle + " " + extraText;
ticker = extraTitle + ": " + extraText;
} else if (extraTitle != null) {
ticker = extraTitle;
} else if (extraText != null) {
@ -309,6 +463,10 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
}
});
} else if (np.has("requestReplyId") && np.has("message")) {
replyToNotification(np.getString("requestReplyId"), np.getString("message"));
}
return true;
@ -352,7 +510,7 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
@Override
public String[] getSupportedPackageTypes() {
return new String[]{PACKAGE_TYPE_NOTIFICATION_REQUEST};
return new String[]{PACKAGE_TYPE_NOTIFICATION_REQUEST,PACKAGE_TYPE_NOTIFICATION_REPLY};
}
@Override
@ -402,4 +560,29 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver.
}
return result;
}
public String getChecksum(byte[] data){
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(data);
return bytesToHex(md.digest());
} catch (NoSuchAlgorithmException e) {
Log.e("KDEConenct", "Error while generating checksum", e);
}
return null;
}
public static String bytesToHex(byte[] bytes) {
char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars).toLowerCase();
}
}

View File

@ -0,0 +1,16 @@
package org.kde.kdeconnect.Plugins.NotificationsPlugin;
import android.app.Notification;
import android.app.PendingIntent;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.UUID;
public class RepliableNotification {
public String id = UUID.randomUUID().toString();
public PendingIntent pendingIntent;
public ArrayList<android.app.RemoteInput> remoteInputs = new ArrayList<>();
public String packageName;
public String tag;
}

View File

@ -20,23 +20,33 @@
package org.kde.kdeconnect.Plugins;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.support.annotation.StringRes;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.UserInterface.MaterialActivity;
import org.kde.kdeconnect.UserInterface.PluginSettingsActivity;
import org.kde.kdeconnect.UserInterface.SettingsActivity;
import org.kde.kdeconnect_tp.R;
public abstract class Plugin {
protected Device device;
protected Context context;
protected int permissionExplanation = R.string.permission_explanation;
public final void setContext(Context context, Device device) {
this.device = device;
@ -167,14 +177,6 @@ public abstract class Plugin {
*/
public boolean onPackageReceived(NetworkPackage np) { return false; }
/**
* If onCreate returns false, should create a dialog explaining
* the problem (and how to fix it, if possible) to the user.
*/
public AlertDialog getErrorDialog(Activity deviceActivity) {
return null;
}
/**
* Should return the list of NetworkPackage types that this plugin can handle
*/
@ -205,4 +207,70 @@ public abstract class Plugin {
return b;
}
public String[] getRequiredPermissions() {
return new String[0];
}
public String[] getOptionalPermissions() {
return new String[0];
}
//Permission from Manifest.permission.*
protected boolean isPermissionGranted(String permission) {
int result = ContextCompat.checkSelfPermission(context, permission);
return (result == PackageManager.PERMISSION_GRANTED);
}
protected boolean arePermissionsGranted(String[] permissions) {
for(String permission: permissions){
if(!isPermissionGranted(permission)){
return false;
}
}
return true;
}
protected AlertDialog requestPermissionDialog(Activity activity, String permissions, @StringRes int reason) {
return requestPermissionDialog(activity, new String[]{permissions}, reason);
}
protected AlertDialog requestPermissionDialog(final Activity activity, final String[] permissions, @StringRes int reason){
return new AlertDialog.Builder(activity)
.setTitle(getDisplayName())
.setMessage(reason)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCompat.requestPermissions(activity, permissions, 0);
}
})
.setNegativeButton(R.string.cancel,new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//Do nothing
}
})
.create();
}
/**
* If onCreate returns false, should create a dialog explaining
* the problem (and how to fix it, if possible) to the user.
*/
public AlertDialog getErrorDialog(Activity deviceActivity) {
return null;
}
public AlertDialog getPermissionExplanationDialog(Activity deviceActivity) {
return requestPermissionDialog(deviceActivity,getRequiredPermissions(), permissionExplanation);
}
public boolean checkRequiredPermissions(){
if (!arePermissionsGranted(getRequiredPermissions())) {
return false;
}
return true;
}
}

View File

@ -125,8 +125,7 @@ public class PluginFactory {
PluginFactory.registerPlugin(TelepathyPlugin.class);
PluginFactory.registerPlugin(FindMyPhonePlugin.class);
PluginFactory.registerPlugin(RunCommandPlugin.class);
//Commented here and in AndroidManifest until we release a desktop version with this feature, so we don't get bad "feature not working" reviews
//PluginFactory.registerPlugin(RemoteKeyboardPlugin.class);
PluginFactory.registerPlugin(RemoteKeyboardPlugin.class);
}
public static PluginInfo getPluginInfo(Context context, String pluginKey) {

View File

@ -20,8 +20,16 @@
package org.kde.kdeconnect.Plugins.SftpPlugin;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import org.json.JSONException;
import org.kde.kdeconnect.Helpers.StorageHelper;
import org.kde.kdeconnect.NetworkPackage;
import org.kde.kdeconnect.Plugins.Plugin;
@ -38,6 +46,9 @@ public class SftpPlugin extends Plugin {
private static final SimpleSftpServer server = new SimpleSftpServer();
@Override
public String getDisplayName() {
return context.getResources().getString(R.string.pref_plugin_sftp);
@ -94,6 +105,7 @@ public class SftpPlugin extends Plugin {
} else {
res.append(context.getString(R.string.sftp_all_files));
}
String pathName = res.toString();
if (storage.readonly) {
res.append(" ");
@ -127,6 +139,12 @@ public class SftpPlugin extends Plugin {
return false;
}
@Override
public String[] getRequiredPermissions() {
String[] perms = {Manifest.permission.READ_EXTERNAL_STORAGE};
return perms;
}
@Override
public String[] getSupportedPackageTypes() {
return new String[]{PACKAGE_TYPE_SFTP_REQUEST};

View File

@ -74,6 +74,9 @@ class NotificationUpdateCallback extends Device.SendPackageStatusCallback {
public void onFailure(Throwable e) {
updateDone(false);
NotificationHelper.notifyCompat(notificationManager, notificationId, builder.build());
if (e != null) {
e.printStackTrace();
}
}
private void updateText() {

View File

@ -23,8 +23,9 @@ package org.kde.kdeconnect.Plugins.SharePlugin;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
@ -32,7 +33,6 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Device;
import org.kde.kdeconnect.NetworkPackage;
@ -46,15 +46,14 @@ import java.util.ArrayList;
import java.util.Collection;
public class ShareActivity extends ActionBarActivity {
public class ShareActivity extends AppCompatActivity {
private MenuItem menuProgress;
private SwipeRefreshLayout mSwipeRefreshLayout;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.refresh, menu);
menuProgress = menu.findItem(R.id.menu_progress);
return true;
}
@ -62,28 +61,7 @@ public class ShareActivity extends ActionBarActivity {
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_refresh:
updateComputerList();
BackgroundService.RunCommand(ShareActivity.this, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.onNetworkChange();
}
});
item.setVisible(false);
menuProgress.setVisible(true);
new Thread(new Runnable() {
@Override
public void run() {
try { Thread.sleep(1500); } catch (InterruptedException e) { }
runOnUiThread(new Runnable() {
@Override
public void run() {
menuProgress.setVisible(false);
item.setVisible(true);
}
});
}
}).start();
updateComputerListAction();
break;
default:
break;
@ -91,6 +69,30 @@ public class ShareActivity extends ActionBarActivity {
return true;
}
private void updateComputerListAction() {
updateComputerList();
BackgroundService.RunCommand(ShareActivity.this, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.onNetworkChange();
}
});
mSwipeRefreshLayout.setRefreshing(true);
new Thread(new Runnable() {
@Override
public void run() {
try { Thread.sleep(1500); } catch (InterruptedException ignored) { }
runOnUiThread(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
}).start();
}
private void updateComputerList() {
final Intent intent = getIntent();
@ -179,7 +181,6 @@ public class ShareActivity extends ActionBarActivity {
device.sendPackage(np);
}
}
finish();
}
});
@ -193,13 +194,21 @@ public class ShareActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
setContentView(R.layout.activity_refresh_list);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
setContentView(R.layout.activity_list);
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.refresh_list_layout);
mSwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
updateComputerListAction();
}
}
);
if (actionBar != null) {
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
}
}

View File

@ -20,7 +20,9 @@
package org.kde.kdeconnect.Plugins.SharePlugin;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DownloadManager;
import android.app.Notification;
import android.app.NotificationManager;
@ -30,6 +32,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
@ -110,6 +113,17 @@ public class SharePlugin extends Plugin {
Log.i("SharePlugin", "hasPayload");
int permissionCheck = ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(permissionCheck == PackageManager.PERMISSION_GRANTED) {
} else if(permissionCheck == PackageManager.PERMISSION_DENIED){
// TODO Request Permission for storage
Log.i("SharePlugin", "no Permission for Storage");
return false;
}
final InputStream input = np.getPayload();
final long fileLength = np.getPayloadSize();
final String originalFilename = np.getString("filename", Long.toString(System.currentTimeMillis()));
@ -132,6 +146,8 @@ public class SharePlugin extends Plugin {
final OutputStream destinationOutput = context.getContentResolver().openOutputStream(destinationDocument.getUri());
final Uri destinationUri = destinationDocument.getUri();
final int notificationId = (int)System.currentTimeMillis();
Resources res = context.getResources();
final NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
@ -159,10 +175,10 @@ public class SharePlugin extends Plugin {
destinationOutput.write(data, 0, count);
if (fileLength > 0) {
if (progress >= fileLength) break;
long progressPercentage = (progress * 100 / fileLength);
long progressPercentage = (progress * 10 / fileLength);
if (progressPercentage != prevProgressPercentage) {
prevProgressPercentage = progressPercentage;
builder.setProgress(100, (int) progressPercentage, false);
builder.setProgress(100, (int) progressPercentage*10, false);
NotificationHelper.notifyCompat(notificationManager, notificationId, builder.build());
}
}
@ -186,25 +202,33 @@ public class SharePlugin extends Plugin {
//Update the notification and allow to open the file from it
Resources res = context.getResources();
String message = successful? res.getString(R.string.received_file_title, device.getName()) : res.getString(R.string.received_file_fail_title, device.getName());
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentTitle(message)
builder.setContentTitle(message)
.setTicker(message)
.setSmallIcon(android.R.drawable.stat_sys_download_done)
.setAutoCancel(true);
if (successful) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(destinationUri, mimeType);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntent(intent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentText(res.getString(R.string.received_file_text, destinationDocument.getName()))
.setContentIntent(resultPendingIntent);
.setAutoCancel(true)
.setProgress(100,100,false)
.setOngoing(false);
// Nougat requires share:// URIs instead of file:// URIs
// TODO use FileProvider for >Nougat
if(Build.VERSION.SDK_INT < 24) {
if (successful) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(destinationUri, mimeType);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntent(intent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentText(res.getString(R.string.received_file_text, destinationDocument.getName()))
.setContentIntent(resultPendingIntent);
}
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
if (prefs.getBoolean("share_notification_preference", true)) {
builder.setDefaults(Notification.DEFAULT_ALL);
}
NotificationHelper.notifyCompat(notificationManager, notificationId, builder.build());
if (successful) {
@ -408,5 +432,10 @@ public class SharePlugin extends Plugin {
return new String[]{PACKAGE_TYPE_SHARE_REQUEST};
}
@Override
public String[] getRequiredPermissions() {
String[] perms = {Manifest.permission.READ_EXTERNAL_STORAGE};
return perms;
}
}

View File

@ -20,6 +20,10 @@
package org.kde.kdeconnect.Plugins.TelepathyPlugin;
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.telephony.SmsManager;
import android.util.Log;
@ -45,11 +49,6 @@ public class TelepathyPlugin extends Plugin {
return context.getResources().getString(R.string.pref_plugin_telepathy_desc);
}
@Override
public boolean onCreate() {
return true;
}
@Override
public void onDestroy() {
}
@ -65,6 +64,10 @@ public class TelepathyPlugin extends Plugin {
String phoneNo = np.getString("phoneNumber");
String sms = np.getString("messageBody");
try {
int permissionCheck = ContextCompat.checkSelfPermission(context,
Manifest.permission.SEND_SMS);
if(permissionCheck == PackageManager.PERMISSION_GRANTED) {
SmsManager smsManager = SmsManager.getDefault();
ArrayList<String> parts = smsManager.divideMessage(sms);
@ -72,7 +75,9 @@ public class TelepathyPlugin extends Plugin {
// If this message turns out to fit in a single SMS, sendMultpartTextMessage
// properly handles that case
smsManager.sendMultipartTextMessage(phoneNo, null, parts, null, null);
} else if(permissionCheck == PackageManager.PERMISSION_DENIED){
// TODO Request Permission SEND_SMS
}
//TODO: Notify other end
} catch (Exception e) {
//TODO: Notify other end
@ -184,4 +189,8 @@ public class TelepathyPlugin extends Plugin {
return new String[]{};
}
@Override
public String[] getRequiredPermissions() {
return new String[]{Manifest.permission.SEND_SMS/*, Manifest.permission.READ_CONTACTS*/};
}
}

View File

@ -20,13 +20,16 @@
package org.kde.kdeconnect.Plugins.TelephonyPlugin;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.util.Log;
@ -112,32 +115,40 @@ public class TelephonyPlugin extends Plugin {
//Log.e("TelephonyPlugin", "callBroadcastReceived");
Map<String, String> contactInfo = ContactsHelper.phoneNumberLookup(context, phoneNumber);
NetworkPackage np = new NetworkPackage(PACKAGE_TYPE_TELEPHONY);
if (phoneNumber != null) {
np.set("phoneNumber", phoneNumber);
}
int permissionCheck = ContextCompat.checkSelfPermission(context,
Manifest.permission.READ_CONTACTS);
if(permissionCheck==PackageManager.PERMISSION_GRANTED) {
Map<String, String> contactInfo = ContactsHelper.phoneNumberLookup(context, phoneNumber);
if (contactInfo.containsKey("name")) {
np.set("contactName", contactInfo.get("name"));
}
if (contactInfo.containsKey("photoID")) {
String photoUri = contactInfo.get("photoID");
if (photoUri != null) {
try {
String base64photo = ContactsHelper.photoId64Encoded(context, photoUri);
if (base64photo != null && !base64photo.isEmpty()) {
np.set("phoneThumbnail", base64photo);
}
} catch (Exception e) {
Log.e("TelephonyPlugin", "Failed to get contact photo");
}
}
}
if (contactInfo.containsKey("name")) {
np.set("contactName", contactInfo.get("name"));
} else {
np.set("contactName", phoneNumber);
}
if (contactInfo.containsKey("photoID")) {
String photoUri = contactInfo.get("photoID");
if (photoUri != null) {
try {
String base64photo = ContactsHelper.photoId64Encoded(context, photoUri);
if (base64photo != null && !base64photo.isEmpty()) {
np.set("phoneThumbnail", base64photo);
}
} catch (Exception e) {
Log.e("TelephonyPlugin", "Failed to get contact photo");
}
}
if (phoneNumber != null) {
np.set("phoneNumber", phoneNumber);
}
switch (state) {
@ -231,18 +242,26 @@ public class TelephonyPlugin extends Plugin {
}
String phoneNumber = messages.get(0).getOriginatingAddress();
Map<String, String> contactInfo = ContactsHelper.phoneNumberLookup(context, phoneNumber);
int permissionCheck = ContextCompat.checkSelfPermission(context,
Manifest.permission.READ_CONTACTS);
if(permissionCheck==PackageManager.PERMISSION_GRANTED) {
Map<String, String> contactInfo = ContactsHelper.phoneNumberLookup(context, phoneNumber);
if (contactInfo.containsKey("name")) {
np.set("contactName", contactInfo.get("name"));
}
if (contactInfo.containsKey("photoID")) {
np.set("phoneThumbnail", ContactsHelper.photoId64Encoded(context, contactInfo.get("photoID")));
}
}
if (phoneNumber != null) {
np.set("phoneNumber", phoneNumber);
}
if (contactInfo.containsKey("name")) {
np.set("contactName", contactInfo.get("name"));
}
if (contactInfo.containsKey("photoID")) {
np.set("phoneThumbnail", ContactsHelper.photoId64Encoded(context, contactInfo.get("photoID")));
}
device.sendPackage(np);
}
@ -290,4 +309,9 @@ public class TelephonyPlugin extends Plugin {
return new String[]{PACKAGE_TYPE_TELEPHONY};
}
@Override
public String[] getRequiredPermissions() {
return new String[]{Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_CONTACTS, Manifest.permission.SEND_SMS};
}
}

View File

@ -68,6 +68,7 @@ public class DeviceFragment extends Fragment {
Device device;
TextView errorHeader;
TextView noPermissionsHeader;
MaterialActivity mActivity;
@ -389,6 +390,38 @@ public class DeviceFragment extends Fragment {
}
}
//Plugins without permissions List
final ConcurrentHashMap<String, Plugin> permissionsNeeded = device.getPluginsWithoutPermissions();
if (!permissionsNeeded.isEmpty()) {
if (noPermissionsHeader == null) {
noPermissionsHeader = new TextView(mActivity);
noPermissionsHeader.setPadding(
0,
((int) (28 * getResources().getDisplayMetrics().density)),
0,
((int) (8 * getResources().getDisplayMetrics().density))
);
noPermissionsHeader.setOnClickListener(null);
noPermissionsHeader.setOnLongClickListener(null);
noPermissionsHeader.setText(getResources().getString(R.string.plugins_need_permission));
}
items.add(new CustomItem(noPermissionsHeader));
for (Map.Entry<String, Plugin> entry : permissionsNeeded.entrySet()) {
String pluginKey = entry.getKey();
final Plugin plugin = entry.getValue();
if (plugin == null) {
items.add(new SmallEntryItem(pluginKey));
} else {
items.add(new SmallEntryItem(plugin.getDisplayName(), new View.OnClickListener() {
@Override
public void onClick(View v) {
plugin.getPermissionExplanationDialog(mActivity).show();
}
}));
}
}
}
ListView buttonsList = (ListView) rootView.findViewById(R.id.buttons_list);
ListAdapter adapter = new ListAdapter(mActivity, items);
buttonsList.setAdapter(adapter);

View File

@ -1,14 +1,17 @@
package org.kde.kdeconnect.UserInterface;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
@ -294,6 +297,22 @@ public class MaterialActivity extends AppCompatActivity {
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
for (int result : grantResults) {
if (result == PackageManager.PERMISSION_GRANTED) {
//New permission granted, reload plugins
BackgroundService.RunCommand(this, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
Device device = service.getDevice(mCurrentDevice);
device.reloadPluginsFromSettings();
}
});
}
}
}
public void renameDevice() {
final TextView nameView = (TextView) mNavigationView.findViewById(R.id.device_name);
final EditText deviceNameEdit = new EditText(MaterialActivity.this);

View File

@ -24,6 +24,7 @@ import android.app.Activity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.Menu;
@ -55,10 +56,10 @@ public class PairingFragment extends Fragment implements PairingDeviceItem.Callb
private static final int RESULT_PAIRING_SUCCESFUL = Activity.RESULT_FIRST_USER;
private View rootView;
private View listRootView;
private SwipeRefreshLayout mSwipeRefreshLayout;
private MaterialActivity mActivity;
private MenuItem menuProgress;
boolean listRefreshCalledThisFrame = false;
TextView headerText;
@ -75,12 +76,21 @@ public class PairingFragment extends Fragment implements PairingDeviceItem.Callb
setHasOptionsMenu(true);
rootView = inflater.inflate(R.layout.activity_list, container, false);
rootView = inflater.inflate(R.layout.activity_refresh_list, container, false);
listRootView = rootView.findViewById(R.id.listView1);
mSwipeRefreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_list_layout);
mSwipeRefreshLayout.setOnRefreshListener(
new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
updateComputerListAction();
}
}
);
headerText = new TextView(inflater.getContext());
headerText.setText(getString(R.string.pairing_description));
headerText.setPadding(0, (int) (16 * getResources().getDisplayMetrics().density), 0, (int) (12 * getResources().getDisplayMetrics().density));
((ListView) rootView).addHeaderView(headerText);
((ListView) listRootView).addHeaderView(headerText);
return rootView;
}
@ -91,7 +101,30 @@ public class PairingFragment extends Fragment implements PairingDeviceItem.Callb
mActivity = ((MaterialActivity) getActivity());
}
void updateComputerList() {
private void updateComputerListAction() {
updateComputerList();
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.onNetworkChange();
}
});
mSwipeRefreshLayout.setRefreshing(true);
new Thread(new Runnable() {
@Override
public void run() {
try { Thread.sleep(1500); } catch (InterruptedException ignored) { }
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
mSwipeRefreshLayout.setRefreshing(false);
}
});
}
}).start();
}
private void updateComputerList() {
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(final BackgroundService service) {
@ -232,33 +265,13 @@ public class PairingFragment extends Fragment implements PairingDeviceItem.Callb
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.pairing, menu);
menuProgress = menu.findItem(R.id.menu_progress);
}
@Override
public boolean onOptionsItemSelected(final MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_refresh:
updateComputerList();
BackgroundService.RunCommand(mActivity, new BackgroundService.InstanceCallback() {
@Override
public void onServiceStart(BackgroundService service) {
service.onNetworkChange();
}
});
menuProgress.setVisible(true);
new Thread(new Runnable() {
@Override
public void run() {
try { Thread.sleep(1500); } catch (InterruptedException e) { }
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
menuProgress.setVisible(false);
}
});
}
}).start();
updateComputerListAction();
break;
case R.id.menu_rename:
mActivity.renameDevice();