From 48ffde66da6306df7f4824cf0e58a9831704b1e5 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Sun, 5 Feb 2017 21:39:28 +0100 Subject: [PATCH 01/40] OPEN_DOCUMENT_TREE needs lollipop --- .../kdeconnect/Plugins/SharePlugin/ShareSettingsActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareSettingsActivity.java b/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareSettingsActivity.java index eea37eca..87b56565 100644 --- a/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareSettingsActivity.java +++ b/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareSettingsActivity.java @@ -35,7 +35,7 @@ public class ShareSettingsActivity extends PluginSettingsActivity { final CheckBoxPreference customDownloads = (CheckBoxPreference) findPreference("share_destination_custom"); filePicker = findPreference("share_destination_folder_preference"); - if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)) { + if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)) { customDownloads.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { From 7e8edda80807b55da300eff45b76fae82b7afaca Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Mon, 6 Feb 2017 03:54:31 +0100 Subject: [PATCH 02/40] GIT_SILENT made messages (after extraction) --- res/values-ar/strings.xml | 76 +++++++++++++++++++++---- res/values-ast/strings.xml | 102 +++------------------------------- res/values-da/strings.xml | 9 ++- res/values-es/strings.xml | 6 ++ res/values-gl/strings.xml | 3 + res/values-lt/strings.xml | 9 ++- res/values-nl/strings.xml | 8 +-- res/values-sk/strings.xml | 7 --- res/values-zh-rCN/strings.xml | 2 + 9 files changed, 99 insertions(+), 123 deletions(-) diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index 3d5c6bf7..8ac25088 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -5,13 +5,23 @@ تقرير البطّاريّة بلّغ عن حالة البطّاريّة دوريًّا اكشف نظام الملفّات + تسمح بتصفّح نظام ملفّات هذا الهاتف عن بعد مزامنة الحافظة شارك محتوى الحافظة - الدَّخل البعيد + الدّخل البعيد + استخدم الهاتف أو اللوحيّ كفأرة ولوحة مفاتيح + تحكّمات الوسائط المتعدّدة + توفّر تحكّمًا بعيدًا لمشغّل الوسائط + شغّل أمرًا + تحفّز أوامر عن بعد من الهاتف أو اللوحيّ وخزة أرسل واستقبل وخزات مزامنة الإخطارات انفذ إلى إخطاراتك من أجهزة أخرى + استقبل الإخطارات + استقبل الإخطارات من الجهاز الآخر واعرضها على أندرويد + شارك واستقبل + شارك الملفّات والعناوين بين الجهازين هذه الميزة غير متوفّرة في إصدار أندرويد لديك لا أجهزة حسنًا @@ -19,24 +29,33 @@ افتح الإعدادات عليك إعطاء التّطبيق صلاحيّات للنّفاذ إلى الإخطارات أرسل وخزة + تحكّمات الوسائط المتعدّدة + الدّخل البعيد + حرّك اصبعًا على الشّاشة لتحريك مؤشّر الفأرة. المس للنّقر واستخدم إصبعين أو ثلاث للزّرّين الأيمن والأوسط. انقر مطوّلًا للسّحب والإفلات. + اضبط إجراء اللمس بإصبعين + اضبط إجراء اللمس بثلاث أصابع + اضبط حساسيّة لوحة اللمس + اعكس اتّجاه التّمرير - - - Nothing + النّقر باليمين + النّقر بالوسط + لا شيء - Slowest - Above Slowest - Default - Above Default - Fastest + الأبطأ + الأقل بطئًا + الافتراضيّ + الأسرع قليلًا + الأسرع الأجهزة المقترن بها الأجهزة المتوفّرة الأجهزة المتذكَّرة فشل تحميل الملحقات (المس لمعلومات اكثر): - أزل الاقتران + إعدادات الملحقة + ألغِ الاقتران الجهاز المقترن غير قابل الوصول + اقرن جهازًا جديدًا جهاز مجهول الجهاز غير قابل الوصول طُلب الاقتران بالفعل @@ -46,14 +65,24 @@ ألغاه المستخدم ألغاه ندّ آخر استُقبل مفتاح غير صالح + معلومات التّعمية + لا يستخدم الجهاز الآخر إصدارة حديثة من «كدي المتّصل»، ستُستخدم طريقة التّعمية القديمة. + بصمة SHA1 لشهادة جهازك هي: + بصمة SHA1 لشهادة الجهاز البعيد هي: طُلب الاقتران طلب اقتران من %1s استُلمت وصلة من %1s المس لفتح \'%1s\' ملفّ وارد من %1s %1s - استُلم ملفّ من %1s + يرسل ملفًّا إلى %1s + %1s + استُقبل ملفّ من %1s + فشل استقبال الملفّ من %1s المس لفتح \'%1s\' + أرسل ملفًّا إلى %1s + %1s + %1s المس للإجابة أعد الاتّصال أرسل نقرة باليمين @@ -74,6 +103,8 @@ التّالي المستوى إعدادات الوسائط المتعدّدة + زرّا التّقدّم والإرجاع + اضبط الوقت عند نقر زرّيّ التّقديم أو الإرجاع. 10 ثوان 20 ثانية @@ -92,9 +123,13 @@ اسم جهاز غير صالح استُقبل نصّ، حُفظ إلى الحافظة قائمة أجهزة مخصّصة + اقرن جهازًا جديدًا + ألغِ اقتران %s أضف أجهزة بميفاق الإنترنت م​إ إخطارات مزعجة اهتزّ وشغّل صوتًا عند استقبال ملفّ + مرشّح الإخطارات + ستُزامن الإخطارات من التّطبيقات المحدّدة. التّخزين الدّاخليّ كلّ الملفّات بطاقة SD ‏%d @@ -102,7 +137,26 @@ (للقراءة فقط) صور الكاميرا أضف مضيفًا/م​إ + اسم المضيف أو عنوان IP لم يُعثر على مشغّلات استخدم هذا الخيار فقط إن لم يُكتَشف جهازك آليًّا. أدخِل عنوان م​إ أو اسم المضيف أدناه والمس الزرّ لإضافته إلى القائمة. المس عنصرًا موجودًا لإزالته من القائمة. %1$s على %2$s + أرسل ملفّات + أجهزة «كدي المتّصل» + الأجهزة الأخرى التي تشغّل «كدي المتّصل» وعلى نفس الشّبكة ستظهر هنا. + اقتُرن الجهاز + أعد تسمية الجهاز + أعد التّسمية + أنعش + الجهاز المقترن هذا لا يمكن الوصول إليه. تأكّد من اتّصاله بنفس الشّبكة. + لا متصفّحات ملفّات مثبّتة. + أرسل SMS + أرسل رسائل نصّيّة من سطح المكتب + لا يدعم جهازك هذه الملحقة + جِد جهازي + جِد جهازي اللوحيّ + يرّن هذا الجهاز لتجده + وُجد + افتح + أغلق diff --git a/res/values-ast/strings.xml b/res/values-ast/strings.xml index d90a1aae..a35388af 100644 --- a/res/values-ast/strings.xml +++ b/res/values-ast/strings.xml @@ -1,6 +1,6 @@ - Notificador telefónicu + Avisador telefónicu Unvia avisos pa SMS y llamaes Informe de batería Informe periódicu del estáu de la batería @@ -15,7 +15,7 @@ Execución de comandos Aiciona comandos remotos del to teléfonu o tableta Ping - Unvia y recibi pings + Unvia y recibe pings Sincronización d\'avisos Accede a los tos avisos d\'otros preseos Recibir avisos @@ -27,11 +27,9 @@ Aceutar Encaboxar Abrir axustes - Necesites garantizar l\'accesu a los avisos + ¡ Unviar ping - Controles multimedia - Entrada remota - 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. + Control multimedia Right click Middle click @@ -44,53 +42,7 @@ Above Default Fastest - Preseos coneutaos - Preseos disponibles - Preseos recordaos - El preséu empareyáu nun ye agamable - Preséu desconocíu - Nun ye algamable\'l preséu - Empareyamientu yá solicitáu - El preséu yá ta empareyáu - Nun pudo unviase\'l paquete Escosó\'l tiempu - Encaboxáu pol usuariu - Encaboxáu pola otra parte - Recibióse una clave non válida - Solicitóse l\'empareyamientu - Solicitú d\'empareyamientu de %1s - Recibióse l\'enllaz de %1s - Calca p\'abrir «%1s» - Ficheru entrante de %1s - %1s - Unviando ficheru a %1s - %1s - Recibióse\'l ficheru de %1s - Fallu al recibir el ficheru de %1s - Tap to open \'%1s\' - Unvióse\'l ficheru a %1s - %1s - %1s - Calca pa responder - Reconeutar - Amosar tecláu - Preséu non empareyáu - Solicitar empareyamientu - Aceutar - Refugar - Preséu - Empareyar preséu - Control remotu - Axustes KDE Connect - Reproducir - Anterior - Rebobinar - Avance rápidu - Siguiente - Volume - Axustes multimedia - Botones d\'avanzar/rebobinar - Axusta\'l tiempu p\'avanzar/rebobinar al primise 10 seconds 20 seconds @@ -98,48 +50,8 @@ 1 minute 2 minutes - Fai sonar el teléfonu pa qu\'asina pueas alcontralu - Esti preséu usa una versión vieya del protocolu - Esti preséu usa una versión anovada del protocolu - Axustes xenerales - Axustes - Axustes de %s - Nome de preséu - %s - Nome de preséu non válidu - Recibióse\'l testu y guardóse nel cartafueyu - Llista de preseos personalizada - Empareyar con un preséu nuevu - Desempareyar %s - Amestar preseos pola IP - Avisos sonoros - Fai vibrar y reproduz un soníu al recibir un ficheru - Peñera d\'avisos - Los avisos sincronizaránse coles aplicaciones esbillaes. - Almacenamientu internu - Tolos ficheros - Tarxeta SD %d - Tarxeta SD - (namai llectura) - Semeyes de cámara - Amestar agospiu/IP - Nome d\'agospiu o IP - Nun s\'alcontraron reproductores - 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. - %1$s en %2$s - Unviar ficheros - Preseos KDE Connect - Deberíen apaecer equí otros preseos executando KDE Connect. - Preséu empareyáu - Renomar preséu - Renomar - Refrescar - Esti preséu empareyáu nun ye algamable. Asegúrate que ta coneutáu a la to mesma rede. - Nun hai restoladores de ficheros instalaos. - Unviar SMS + Nun hai restoladores de ficheros instalaos Unvia mensaxes de testu dende\'l to escritoriu - Esti complementu nun ta sofitáu pol preséu - Alcontrar - Abrir - Zarrar + Esti complementu nun lu sofita\'l preséu + Fai sonar el teléfonu pa qu\'asina pueas alcontralu diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index e1a3712e..ca2d92b3 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -49,7 +49,7 @@ Over mest langsom Standard Over standard - Hurtigste + Hurtigst Forbundne enheder Tilgængelig enheder @@ -79,12 +79,15 @@ Indkommende fil fra %1s %1s Sender fil til %1s + Sender filer til %1s %1s + Sendte %1$d ud af %2$d filer Modtog fil fra %1s Kunne ikke modtage fil fra %1s Tap for at åbne \"%1s\" Fil sendt til %1s %1s + Kunne ikke sende filen til %1s %1s Tap for at svare Forbind igen @@ -131,6 +134,10 @@ Tilføj enheder via IP Støjende bekendtgørelser Vibrér og afspil en lyd når en fil modtages + Tilpas destinationsmappe + Modtagne filer vil dukke op i Downloads + Filer vil blive gemt i mappen nedenfor + Destinationsmappe Bekendtgørelsesfilter Bekendtgørelser vil blive synkroniseret for de valgte apps. Intern lagring diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 6aa2534f..4e5d1556 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -10,6 +10,8 @@ Compartir el contenido del portapapeles Entrada remota Usar su teléfono o tableta como teclado y teclado táctil + Recibir pulsaciones de teclas remotas + Recibir eventos de pulsación de teclas desde dispositivos remotos Controles multimedia Proporciona un control remoto para su reproductor de medios Ejecutar orden @@ -30,6 +32,10 @@ Debe otorgar permiso para acceder a las notificaciones Enviar ping Control multimedia + Manejar teclas remotas solo al editar + No hay ninguna conexión remota de teclado activa, establezca una en kdeconnect + La conexión remota de teclado está activa + Hay más de una conexión remota de teclado, seleccione el dispositivo a configurar Entrada remota Mueva un dedo sobre la pantalla para mover el cursor del ratón. Pulse para ejecutar un clic y use dos/tres dedos para emular los botones derecho y central. Use una pulsación larga para arrastrar y soltar. Establecer la acción al pulsar con dos dedos diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index dcd9b8c3..48b1c1c9 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -28,6 +28,8 @@ 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. Definir a acción de tocar con dous dedos Definir a acción de tocar con tres dedos + Definir a sensibilidade do punteiro táctil + Inverter a dirección de desprazamento Clic dereito Clic central @@ -35,6 +37,7 @@ dereita medio + predeterminado O máis lento Lento diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml index 307b9292..603c07a0 100644 --- a/res/values-lt/strings.xml +++ b/res/values-lt/strings.xml @@ -41,14 +41,11 @@ Jau paprašyta suporuoti Įrenginys jau suporuotas Nepavyksta išsiųsti paketo + Skirtasis laikas baigėsi Naudotojas atšaukė užduotį Porininkas atšaukė užduotį Gautas netinkamas raktas Paprašyta suporuoti - %1s - %1s - %1s - %1s Norėdami atsakyti, palieskite Prisijungti iš naujo Rodyti klaviatūrą @@ -86,7 +83,6 @@ Suporuoti naują įrenginį Atrišti %s Pridėti įrenginį pagal IP - Vidinė saugykla Visi failai SD kortelė %d SD kortelė @@ -100,9 +96,12 @@ Čia turėtų pasirodyti to kiti paties tinklo įrenginiai, kuriuose veikia „KDE Connect“ Įrenginys suporuotas Pervadinti įrenginį + Pervadinti Atnaujinti Šis suporuotas įrenginys nepasiekiamas. Patikrinkite, ar jis prisijungęs prie to paties tinklo. Siųsti SMS Telefonas nepalaiko šio papildinio Radau + Atverti + Užverti diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 66b62869..16b19a5e 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -85,15 +85,15 @@ Inkomend bestand van %1s %1s Bezig bestand te verzenden naar %1s - Bestanden verzenden naar %1s + Bezig bestanden te verzenden naar %1s %1s - Verzonden %1$d van %2$d bestanden + Verzonden %1$d uit %2$d bestanden Bestand ontvangen van %1s Bestand ontvangen van %1s is mislukt Tap om \'%1s\' te openen Bestand verzonden naar %1s %1s - Verzenden van bestanden naar %1s is mislukt + Verzenden van bestand naar %1s is mislukt %1s Tap om te antwoorden Opnieuw verbinden @@ -140,7 +140,7 @@ Voeg apparaten toe per IP-adres Luidruchtige meldingen Vibreer en speel een geluidje bij ontvangen van een bestand - Pas bestemmingsmap aan + De bestemmingsmap aanpassen Ontvangen bestanden zullen in Downloads verschijnen Bestanden zullen opgeslagen worden in de onderstaande map Bestemmingsmap diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 5f7f1d3a..a5d85f90 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -79,15 +79,12 @@ Prichádzajúci súbor od %s %1s Posielam súbor pre %1s - Posielam súbor pre %1s %1s - Poslať %1$d z %2$d súborov Prijatý súbor od %1s Zlyhalo prijatie súboru od %1s Ťuknite na otvorenie \'%1s\' Poslať súbor pre %1s %1s - Zlyhalo poslanie súboru %1s %1s Tapnite na odpoveď Znovu pripojiť @@ -134,10 +131,6 @@ Pridať zariadenia podľa IP Hlučné pripomienky Vibrovať a prehrať zvuk pri prijatí súboru - Prispôsobiť cieľový adresár - Prijaté súbory sa objavia v Preberaniach - Súbory sa uložia v adresári dolu - Cieľový adresár Filter upozornení Upozornenia budú synchronizované pre vybrané aplikácie. Interné úložisko diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index e6cd44ad..29e80f5b 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -144,4 +144,6 @@ 从桌面发送短消息 设备不支持此插件 找到 + 打开 + 关闭 From b73f5ad6a42bd16dc61324f5dfa5ca8cc9d6e3af Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Sat, 11 Feb 2017 03:47:01 +0100 Subject: [PATCH 03/40] GIT_SILENT made messages (after extraction) --- res/values-zh-rCN/strings.xml | 39 ++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 29e80f5b..7f5fc995 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -5,15 +5,23 @@ 电池报告 定期报告电池状态 开放文件系统 + 允许远程浏览设备的文件系统 剪贴板同步 共享剪贴板内容 远程输入 + 将您的手机用或平板电脑用作触摸板和键盘 + 接收远程按键 + 从远程设备接收按键事件 多媒体控制 + 媒体播放器的遥控器 执行命令 + 触发您的手机或平板电脑的远程命令 Ping 发送和接受ping 通知同步 从其他设备访问你的通知 + 接收通知 + 从其他设备接收通知并显示在 Android 上 分享和接收 在设备间共享文件和 URL 该特性不适用于您的Android版本 @@ -24,10 +32,16 @@ 你需要授予权限以便访问通知 发送ping 多媒体控制 + 只有在编辑时才接受远程按键 + 没有活动的远程键盘链接,请在 KDE Connect 中连接 + 远程键盘连接已启用 + 发现多个远程键盘连接,请选择设备进行配置 远程输入 在屏幕上移动手指来移动光标。轻击代表左键,双指或三指点击代表右键或中键。用长按来拖放。 设置双指点击动作 设置三指点击动作 + 设置触摸板灵敏度 + 滚动方向反向 右键点击 中键点击 @@ -35,12 +49,13 @@ + 默认 - Slowest - Above Slowest - Default - Above Default - Fastest + 最慢 + 高于最慢 + 默认 + 高于默认 + 最快 已连接设备 可用设备 @@ -59,6 +74,10 @@ 已被用户取消 已被另一方取消 收到无效密钥 + 加密信息 + 另一设备没有使用最新的 KDE Connect,使用旧版加密方法。 + 您的设备证书的 SHA1 指纹是: + 远程设备证书的 SHA1 指纹是: 已请求配对 来自%1s的配对请求 已从%1s接收链接 @@ -66,12 +85,15 @@ 来自%1s的文件 %1s 正在向%1s发送文件 + 正在向 %1s 发送文件 %1s + 已发送 %2$d 个文件中的 %1$d 个 已从%1s接收文件 未能从%1s接收文件 点击以打开“%1s” 发送文件到%1s %1s + 向 %1s 发送文件失败 %1s 点击以应答 重新连接 @@ -118,6 +140,10 @@ 通过IP增加设备 出声通知 当收到文件时震动并播放声音 + 配置目标目录 + 接收的文件会出现在“Downloads”中 + 文件将会被存储在以下目录中 + 目标目录 通知过滤器 所选软件的通知将会被同步。 内部存储 @@ -143,6 +169,9 @@ 发送短消息 从桌面发送短消息 设备不支持此插件 + 找到我的手机 + 找到我的平板电脑 + 让设备响铃从而找到它 找到 打开 关闭 From c8469b06b56941aa3627c0ddfa9ef187f7faa384 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Sun, 19 Feb 2017 03:48:16 +0100 Subject: [PATCH 04/40] GIT_SILENT made messages (after extraction) --- res/values-ast/strings.xml | 115 +++++++------------------------------ res/values-ca/strings.xml | 6 +- res/values-de/strings.xml | 32 ++++++++--- res/values-gl/strings.xml | 2 +- res/values-pl/strings.xml | 6 ++ res/values-sk/strings.xml | 6 -- res/values-sv/strings.xml | 10 +++- 7 files changed, 62 insertions(+), 115 deletions(-) diff --git a/res/values-ast/strings.xml b/res/values-ast/strings.xml index 51887e3c..a35388af 100644 --- a/res/values-ast/strings.xml +++ b/res/values-ast/strings.xml @@ -3,16 +3,24 @@ Avisador telefónicu Unvia avisos pa SMS y llamaes Informe de batería - Infoma davezu del estáu de la batería + Informe periódicu del estáu de la batería + Permite restolar remotamente a esti preséu Sincronización del cartafueyu Comparte\'l conteníu del cartafueyu Entrada remota - Controles remotos multimedia + Usa\'l to teléfonu o tableta como panel táutil y tecláu + Pulsaciones remotes + Controles multimedia + Forne un control remotu pal to reproductor multimedia + Execución de comandos + Aiciona comandos remotos del to teléfonu o tableta Ping Unvia y recibe pings Sincronización d\'avisos - Accede a los tos avisos dende otros preseos - Unvia y recibi pings + Accede a los tos avisos d\'otros preseos + Recibir avisos + Recibe avisos d\'otros preseos y amuésalos n\'Android + Compartir y recibir Comparte ficheros y URLs ente preseos Esta carauterística nun ta disponible na to versión d\'Android Ensin preseos @@ -23,9 +31,9 @@ Unviar ping Control multimedia - Clic drechu - Clic d\'en mediu - Nada + Right click + Middle click + Nothing Slowest @@ -35,97 +43,14 @@ Fastest Escosó\'l tiempu - Preseos coneutaos - Preseos disponibles - Preseos recordaos - El preséu empareyáu nun ye agamable - Preséu desconocíu - Nun ye algamable\'l preséu - Empareyamientu yá solicitáu - El preséu yá ta empareyáu - Nun pudo unviase\'l paquete - Encaboxáu pol usuariu - Encaboxáu pola otra parte - Recibióse una clave non válida - Solicitóse l\'empareyamientu - Solicitú d\'empareyamientu de %1s - Recibióse l\'enllaz de %1s - Calca p\'abrir «%1s» - Ficheru entrante de %1s - %1s - Unviando ficheru a %1s - %1s - Recibióse\'l ficheru de %1s - Fallu al recibir el ficheru de %1s - Tap to open \'%1s\' - Unvióse\'l ficheru a %1s - %1s - %1s - Calca pa responder - Reconeutar - Amosar tecláu - Preséu non empareyáu - Solicitar empareyamientu - Aceutar - Refugar - Preséu - Empareyar preséu - Control remotu - Axustes KDE Connect - Reproducir - Anterior - Rebobinar - Avance rápidu - Siguiente - Volume - Axustes multimedia - Botones d\'avanzar/rebobinar - Axusta\'l tiempu p\'avanzar/rebobinar al primise - 10 segundos - 20 segundos - 30 segundos - 1 minutu - 2 minutos + 10 seconds + 20 seconds + 30 seconds + 1 minute + 2 minutes Nun hai restoladores de ficheros instalaos - Esti preséu usa una versión vieya del protocolu - Esti preséu usa una versión anovada del protocolu - Axustes xenerales - Axustes - Axustes de %s - Nome de preséu - %s - Nome de preséu non válidu - Recibióse\'l testu y guardóse nel cartafueyu - Llista de preseos personalizada - Empareyar con un preséu nuevu - Desempareyar %s - Amestar preseos pola IP - Avisos sonoros - Fai vibrar y reproduz un soníu al recibir un ficheru - Peñera d\'avisos - Los avisos sincronizaránse coles aplicaciones esbillaes. - Almacenamientu internu - Tolos ficheros - Tarxeta SD %d - Tarxeta SD - (namai llectura) - Semeyes de cámara - Amestar agospiu/IP - Nome d\'agospiu o IP - Nun s\'alcontraron reproductores - 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. - %1$s en %2$s - Unviar ficheros - Preseos KDE Connect - Deberíen apaecer equí otros preseos executando KDE Connect. - Preséu empareyáu - Renomar preséu - Renomar - Refrescar - Esti preséu empareyáu nun ye algamable. Asegúrate que ta coneutáu a la to mesma rede. - Unviar SMS Unvia mensaxes de testu dende\'l to escritoriu Esti complementu nun lu sofita\'l preséu Fai sonar el teléfonu pa qu\'asina pueas alcontralu diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 6d090953..9856b85a 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -10,8 +10,8 @@ Comparteix el contingut del porta-retalls Entrada remota Usa el vostre telèfon o tauleta com un ratolí i un teclat - Rep les pulsacions de tecla remotes - Rep els esdeveniments de pulsacions de tecla des de dispositius remots + S\'estan rebent pulsacions de tecla remotes + S\'estan rebent esdeveniments de pulsacions de tecla des de dispositius remots Controls multimèdia Proporciona un comandament a distància pel reproductor multimèdia Executa una ordre @@ -33,7 +33,7 @@ Envia un ping Control multimèdia Fes servir les tecles remotes només en editar - No hi ha cap connexió activa amb el teclat remot, establiu-ne una al «kdeconnect» + No hi ha cap connexió activa amb el teclat remot, establiu-ne una al kde-connect La connexió amb el teclat remot està activa Hi ha més d\'una connexió amb un teclat remot, seleccioneu el dispositiu per configurar-lo Entrada remota diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 67062450..655b4eb3 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -9,15 +9,17 @@ Abgleich der Zwischenablage Inhalt der Zwischenablage freigeben Ferneingabe - Verwendet Ihr Handy als Tablett, Touchpad und Tastatur + Verwendet Ihr Handy als Tablet, Touchpad und Tastatur Multimedia-Bedienung + Eine Fernbedienung für Ihre Medienwiedergabe Befehl ausführen - Von Ihrem Telefon oder Tablett Befehle auf anderen Geräten ausführen + Von Ihrem Telefon oder Tablet Befehle auf anderen Geräten ausführen Ping Senden und Empfangen von Pings Benachrichtigungs-Abgleich Zugriff auf Ihre Benachrichtigungen von anderen Geräten Benachrichtigungen empfangen + Empfangen und Anzeigen von Benachrichtigungen des anderen Geräts Veröffentlichen und Empfangen Dateien und Adressen (URLs) zwischen Geräten teilen Diese Funktion ist in Ihrer Android-Version nicht verfügbar @@ -29,6 +31,7 @@ Ping senden Multimedia-Bedienung Ferneingabe + Bewegen Sie einen Finger auf dem Bildschirm um den Maus-Zeiger zu verschieben. Tippen zum Klicken, mit zwei oder drei Fingern für rechten bzw. mittleren Mausknopf. Tippen und Halten für Ziehen und Ablegen. Aktionsausführung bei Berührung mit zwei Fingern einstellen Aktionsausführung bei Berührung mit drei Fingern einstellen Empfindlichkeit des Touchpads einstellen @@ -43,9 +46,9 @@ Standard Langsamste - Above Slowest + Langsam Standard - Above Default + Schnell Schnellste Verbundene Geräte @@ -66,19 +69,25 @@ Abbruch durch Gegenstelle Ungültiger Schlüssel empfangen Verschlüsselungsinformationen + Das andere Gerät verwendet eine ältere Version von KDE-Connect, eine veraltete Verschlüsselungsmethode wird verwendet. Der SHA1-Fingerabdruck Ihres Gerätezertifikats lautet: Der SHA1-Fingerabdruck des Gerätezertifikats der Gegenstelle lautet: Verbindung angefordert Verbindungsanfrage von %1s Verknüpfung von %1s erhalten + Tippen um „%1s“ zu öffnen Eingehende Datei von %1s %1s Datei wird an %1s gesendet + Datei wird an %1s gesendet %1s + %1$d von %2$d Dateien gesendet Datei von %1s erhalten Der Empfang der Datei %1s ist fehlgeschlagen + Tippen um „%1s“ zu öffnen Datei an %1s gesendet %1s + Das Senden der Datei an %1s ist fehlgeschlagen %1s Tippen zum Antworten Erneut verbinden @@ -86,7 +95,7 @@ Mittelklick senden Tastatur anzeigen Das Gerät ist nicht verbunden - Verbindung angefordert + Verbindung anfordern Annehmen Ablehnen Gerät @@ -101,6 +110,7 @@ Lautstärke Multimedia-Einstellungen Knöpfe Vorwärts/Rückwärts + Sprungweite für Vorlauf/Rücklauf anpassen. 10 Sekunden 20 Sekunden @@ -124,6 +134,10 @@ Geräte nach IP hinzufügen Ausführliche Benachrichtigungen Beim Empfang einer Datei vibrieren und einen Sound abspielen + Zielverzeichnis anpassen + Empfangene Dateien werden in Downloads gespeichert + Dateien werden im folgenden Verzeichnis gespeichert + Zielverzeichnis Benachrichtigungs-Filter Benachrichtigungen werden zwischen den ausgewählten Anwendungen abgeglichen. Interner Speicher @@ -135,21 +149,23 @@ Rechner/IP hinzufügen Rechnername oder IP Keine Medienspieler gefunden + Benutzen Sie diese Funktion nur, wenn Ihr Gerät nicht automatisch erkannt wird. Geben hier Sie IP-Adresse oder Hostnamen ein und bestätigen Sie, um es zu der Liste hinzuzufügen. Tippen Sie ein bestehendes Gerät an, um es aus der Liste zu entfernen. %1$s auf %2$s Dateien senden KDE-Connect-Geräte - Andere Geräte, auf denen KDE-Connect läuft im gleichen Netzwerk,sollte hier angezeigt werden. + Andere Geräte im selben Netzwerk, auf denen KDE-Connect läuft, sollten hier angezeigt werden. Gerät verbunden Geräte umbenennen Umbenennen Aktualisieren + Das verbundene Gerät ist nicht erreichbar. Stellen Sie sicher daß es mit demselben Netzwerk verbunden ist. Es sind keine Dateiverwaltungsprogramme installiert. SMS senden Text-Nachrichten von Ihrer Arbeitsfläche senden Dieses Modul wird durch das Gerät nicht unterstützt Mein Telefon suchen - Mein Tablett suchen - Ruft dieses Gerät an, um es zu suchen. + Mein Tablet suchen + Ruft dieses Gerät an, damit sie es finden können Gefunden Öffnen Schließen diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 10c798e0..48b1c1c9 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -139,7 +139,7 @@ Outros dispositivos que estean a executar KDE Connect na mesma rede deberían aparecer aquí. Emparellouse co dispositivo Cambiar o nome do dispositivo - Mudar o nome + Cambiar o nome Actualizar Este dispositivo emparellado está fóra do alcance. Asegúrese de que está conectado á mesma rede. Non hai navegadores de ficheiros instalados. diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 33209741..aedc18d6 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -10,6 +10,8 @@ Udostępnij zawartość schowka Zdalne sterowanie Użyj swojego telefonu lub tabletu jako myszy i klawiatury + Odbieraj zdalne naciśnięcia klawiszy + Odbieraj naciśnięcia klawiszy od urządzeń zdalnych Sterowanie multimediami Zapewnia zdalne sterowanie twoim odtwarzaczem multimedialnym Wykonaj polecenie @@ -30,6 +32,10 @@ Musisz przydzielić uprawnienia, aby uzyskać dostęp do powiadomień Wyślij ping Sterowanie multimediami + Obsługuj zdalne naciśnięcia klawiszy tylko podczas edycji + Nie istnieje połączenie zdalnej klawiatury, nawiąż takie połączenie w kdeconnect + Połączenie zdalnej klawiatury jest nawiązane + Nawiązano więcej niż jedno połączenie zdalnej klawiatury, wybierz urządzenie do ustawienia Zdalne sterowanie Przesuń palcem po ekranie, aby przesunąć wskaźnik myszy. Stuknij, aby wywołać naciśniecie lewym przyciskiem myszy i użyj dwóch/trzech palców, aby wywołać naciśniecie prawym i środkowym przyciskiem myszy. Przyciśnij na dłużej, aby przeciągnąć i upuścić. Ustaw działanie po dwukrotnym stuknięciu palcem diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 13616b40..a5d85f90 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -10,8 +10,6 @@ Zdieľať obsah schránky Vzdialený vstup Použiť váš telefón alebo tablet ako touchpad a klávesnicu - Prijímať vzdialené stlačenia klávesov - Prijímať udalosti stlačení klávesov od vzdialených zariadení Multimediálne ovládače Poskytuje vzdialené ovládanie pre váš prehrávač médií Spustiť príkaz @@ -32,10 +30,6 @@ Musíte povoliť oprávnenia na prístup k pripomienkam Poslať ping Multimediálny ovládač - Spracúva vzdialené klávesy len pri editácii - Nie sú žiadne aktívne pripojenia vzdialenej klávesnice, vytvorte nejaké v Kdeconnect - Vzdialené pripojenie klávesnice je aktívne - Je viac ako jedno vzdialené pripojenie klávesnice, vyberte zariadenie na nastavenie Vzdialený vstup 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. Nastaviť akciu dvoch prstov diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 31311c26..a552cd56 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -8,8 +8,10 @@ Gör det möjligt att bläddra i apparatens filsystem från annan apparat Synkronisera klippbord Dela klippbordets innehåll - Fjärrinmatning + Extern inmatning Använd telefonen eller surfplattan som mus och tangentbord + Ta emot externa tangentnedtryckningar + Ta emot tangentnedtryckningar från externa enheter Multimediakontroller Tillhandahåller en fjärrkontroll för mediaspelaren Kör kommando @@ -30,7 +32,11 @@ Du måste ge rättighet att komma åt underrättelser Skicka ping Kontroll av multimedia - Fjärrinmatning + Hantera bara externa tangenter vid redigering + Det finns ingen aktiv anslutning till externt tangentbord, upprätta en i KDE-anslut + Anslutning till externt tangentbord är aktiv + Det finns mer än en anslutning till externt tangentbord, välj enhet att anpassa + Extern inmatning 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. Ställ in åtgärd vid två fingerberöringar Ställ in åtgärd vid tre fingerberöringar From 40b1caaf3a5f040e8ac0f1c69caef7c51999d17f Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Mon, 20 Feb 2017 03:50:57 +0100 Subject: [PATCH 05/40] GIT_SILENT made messages (after extraction) --- res/values-ca/strings.xml | 1 + res/values-en-rGB/strings.xml | 1 + res/values-nl/strings.xml | 1 + res/values-pl/strings.xml | 1 + res/values-pt/strings.xml | 1 + res/values-uk/strings.xml | 1 + 6 files changed, 6 insertions(+) diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 9856b85a..2eef61aa 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -165,6 +165,7 @@ Reanomena Refresca Aquest dispositiu aparellat no és accessible. Assegureu-vos que està connectat a la mateixa xarxa. + Sembla que esteu amb una connexió de dades mòbils. El KDE Connect només funciona amb xarxes locals. No hi ha instal·lat cap explorador de fitxers. Envia un SMS Envia missatges de text des de l\'escriptori diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 997ed5c8..de3f74d7 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -165,6 +165,7 @@ Rename Refresh This paired device is not reachable. Make sure it is connected to your same network. + It looks like you are on a mobile data connection. KDE Connect only works on local networks. There are no file browsers installed. Send SMS Send text messages from your desktop diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 16b19a5e..dd5b0364 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -165,6 +165,7 @@ Hernoemen Verversen Dit gepaarde apparaat is niet bereikbaar. Ga na dat het is verbonden met uw zelfde netwerk. + Het lijkt of op een mobiele gegevensverbinding zit. KDE Connect werkt alleen op locale netwerken. Er zijn geen bestandsbrowsers geïnstalleerd. SMS verzenden Stuur tekstberichten van uw bureaublad diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index aedc18d6..5e6630c0 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -165,6 +165,7 @@ Zmień nazwę Odśwież To sparowane urządzenie jest nieosiągalne. Upewnij się, że jest podłączone do tej samej sieci. + Wygląda na to, że korzystasz z internetu mobilnego. KDE Connect działa tylko na lokalnych sieciach. Nie wgrano żadanych przeglądarek plików. Wyślij SMS-a Wyślij wiadomość tekstową z komputera diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index cb5a9096..193d21a1 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -165,6 +165,7 @@ Mudar o Nome Actualizar Este dispositivo emparelhado não está acessível. Certifique-se que está ligado à mesma rede que você. + Parece que está com uma ligação de dados móveis. O KDE Connect só se liga em redes locais. Não existem gestores de ficheiros instalados. Enviar um SMS Enviar mensagens de texto a partir do seu ambiente de trabalho diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 1b999ace..70e55b1e 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -165,6 +165,7 @@ Перейменувати Оновити Цей пов’язаний пристрій недоступний. Переконайтеся, що його з’єднано з вашою мережею. + Здається, мережа працює у режимі мобільного з’єднання. KDE Connect може працювати лише у локальних мережах. Програм для навігації файловою системою не встановлено. Надіслати SMS Надсилати текстові повідомлення з вашої робочої станції From f9ca018e2af2b200a1e76a7072b689878b8fc6f8 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Tue, 21 Feb 2017 08:45:31 +0100 Subject: [PATCH 06/40] GIT_SILENT made messages (after extraction) --- res/values-sk/strings.xml | 1 - res/values-sv/strings.xml | 1 - 2 files changed, 2 deletions(-) diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 6efd6b47..a5d85f90 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -152,7 +152,6 @@ Premenovať Obnoviť Toto spárované zariadenie nie je dosiahnuteľné. Prosím, uistite sa, že je pripojené do rovnakej siete. - Zdá sa, že ste na mobilom dátovom pripojení. KDE Connect funguje iba na lokálnej sieti. Nie sú nainštalované žiadne prehliadače. Poslať SMS Posielať textové správy z vášho počítača diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 3b1b7035..a552cd56 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -165,7 +165,6 @@ Byt namn Uppdatera Den här ihopparade apparaten kan inte nås. Försäkra dig om att den är ansluten till samma nätverk. - Det verkar som om du använder en mobil dataanslutning. KDE-anslut fungerar bara på lokala nätverk. Det finns inga filbläddrare installerade. Skicka SMS Skicka textmeddelanden från skrivbordet From c91d84b635f36d91a99bcf904ee7547ca157b3a9 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Wed, 22 Feb 2017 03:45:42 +0100 Subject: [PATCH 07/40] GIT_SILENT made messages (after extraction) --- res/values-sv/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index a552cd56..3b1b7035 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -165,6 +165,7 @@ Byt namn Uppdatera Den här ihopparade apparaten kan inte nås. Försäkra dig om att den är ansluten till samma nätverk. + Det verkar som om du använder en mobil dataanslutning. KDE-anslut fungerar bara på lokala nätverk. Det finns inga filbläddrare installerade. Skicka SMS Skicka textmeddelanden från skrivbordet From 2a732645d2fcd9a9e5b81e4a50f98959b062431f Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Thu, 23 Feb 2017 03:58:04 +0100 Subject: [PATCH 08/40] GIT_SILENT made messages (after extraction) --- res/values-cs/strings.xml | 3 ++- res/values-nl/strings.xml | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index 506fcb12..f5944c9b 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -22,7 +22,7 @@ Zpřístupněte si upozornění z jiných zařízení Přijímat oznámení Přijímat oznámení z jiného zařízení a zobrazovat je v Androidu - Sdílet s přijmnout + Sdílet a přijmout Sdílet soubory a odkazy mezi zařízeními Tato vlastnost není pro vaši verzi Androidu platná Žádná zařízení @@ -165,6 +165,7 @@ Přejmenovat Obnovit Toto spárované zařízení je nedosažitelné. Ujistěte se, že běží ve stejné síti. + Vypadá to, že jste na mobilním internetovém připojení. KDE Connect funguje pouze na lokální síti. Není nainstalován žádný prohlížeč souborů. Poslat SMS Posílejte zprávy ze své pracovní plochy diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index dd5b0364..10c13a71 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -67,7 +67,7 @@ Nieuw apparaat paren Onbekend apparaat Apparaat niet bereikbaar - Paar maken is al gevraagd + Paarvorming is al gevraagd Apparaat is al gepaard Kon pakket niet verzenden Tijdslimiet overschreden @@ -78,7 +78,7 @@ Het andere apparaat gebruikt geen recente versie van KDE Connect, de verouderde versleutelingsmethode zal worden gebruikt. De SHA1 vingerafdruk van het certificaat van uw apparaat is: De SHA1 vingerafdruk van het certificaat van het apparaat op afstand is: - Paar gevraagd + Paarvorming gevraagd Verzoek om een paar te maken van %1s Ontvangen koppeling van %1s Tap om \'%1s\' te openen From 732206ac139886f3d4d638016a1a2146708e8034 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Mon, 20 Feb 2017 22:59:42 +0100 Subject: [PATCH 09/40] Fix crash on Android < 12 --- src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java index 0e83fd7c..fc2042e0 100644 --- a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java +++ b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java @@ -34,6 +34,7 @@ import android.content.res.Resources; import android.database.Cursor; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Build; import android.preference.PreferenceManager; import android.provider.MediaStore; import android.support.v4.app.NotificationCompat; @@ -207,7 +208,7 @@ public class SharePlugin extends Plugin { NotificationHelper.notifyCompat(notificationManager, notificationId, builder.build()); if (successful) { - if (!customDestination) { + if (!customDestination && Build.VERSION.SDK_INT >= 12) { Log.i("SharePlugin","Adding to downloads"); DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); manager.addCompletedDownload(destinationUri.getLastPathSegment(), device.getName(), true, mimeType, destinationUri.getPath(), fileLength, false); @@ -228,7 +229,7 @@ public class SharePlugin extends Plugin { Log.i("SharePlugin", "hasText"); String text = np.getString("text"); - if(android.os.Build.VERSION.SDK_INT >= 11) { + if(Build.VERSION.SDK_INT >= 11) { ClipboardManager cm = (ClipboardManager)context.getSystemService(Context.CLIPBOARD_SERVICE); cm.setText(text); } else { From e2a932558a0ef1df7afabe00b42c4119213a743c Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Sat, 25 Feb 2017 21:05:23 +0100 Subject: [PATCH 10/40] Revert "Do not broadcast in 3G + info message" As it couldn't be any other way, this broke somebody's workflow. This reverts commit 440a12f86c8db63cc3a85d3a4e05c3e62eb31f19. --- res/layout/activity_device.xml | 15 +-------------- res/values/strings.xml | 1 - .../Backends/LanBackend/LanLinkProvider.java | 6 ------ src/org/kde/kdeconnect/BackgroundService.java | 2 +- .../kde/kdeconnect/Helpers/NetworkHelper.java | 16 ---------------- .../kdeconnect/KdeConnectBroadcastReceiver.java | 1 - .../kdeconnect/UserInterface/DeviceFragment.java | 5 +---- .../UserInterface/PairingFragment.java | 13 ++++--------- 8 files changed, 7 insertions(+), 52 deletions(-) delete mode 100644 src/org/kde/kdeconnect/Helpers/NetworkHelper.java diff --git a/res/layout/activity_device.xml b/res/layout/activity_device.xml index 43028053..9bb47993 100644 --- a/res/layout/activity_device.xml +++ b/res/layout/activity_device.xml @@ -70,7 +70,7 @@ - - Rename Refresh This paired device is not reachable. Make sure it is connected to your same network. - It looks like you are on a mobile data connection. KDE Connect only works on local networks. There are no file browsers installed. Send SMS Send text messages from your desktop diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java index 867ce6db..f6f0583e 100644 --- a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java +++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java @@ -31,7 +31,6 @@ import org.kde.kdeconnect.Backends.BaseLinkProvider; import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.Device; import org.kde.kdeconnect.Helpers.DeviceHelper; -import org.kde.kdeconnect.Helpers.NetworkHelper; import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper; import org.kde.kdeconnect.Helpers.StringsHelper; import org.kde.kdeconnect.NetworkPackage; @@ -363,11 +362,6 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis private void broadcastUdpPackage() { - if (NetworkHelper.isOnMobileNetwork(context)) { - Log.w("LanLinkProvider", "On 3G network, not sending broadcast."); - return; - } - new Thread(new Runnable() { @Override public void run() { diff --git a/src/org/kde/kdeconnect/BackgroundService.java b/src/org/kde/kdeconnect/BackgroundService.java index ca6c2cca..7b5ef04a 100644 --- a/src/org/kde/kdeconnect/BackgroundService.java +++ b/src/org/kde/kdeconnect/BackgroundService.java @@ -119,7 +119,7 @@ public class BackgroundService extends Service { } }; - public void onDeviceListChanged() { + private void onDeviceListChanged() { for(DeviceListChangedCallback callback : deviceListChangedCallbacks.values()) { callback.onDeviceListChanged(); } diff --git a/src/org/kde/kdeconnect/Helpers/NetworkHelper.java b/src/org/kde/kdeconnect/Helpers/NetworkHelper.java deleted file mode 100644 index 0f6d17cd..00000000 --- a/src/org/kde/kdeconnect/Helpers/NetworkHelper.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.kde.kdeconnect.Helpers; - -import android.content.Context; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; -import android.util.Log; - -public class NetworkHelper { - - public static boolean isOnMobileNetwork(Context context) { - final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo info = connMgr.getActiveNetworkInfo(); - return (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE); - } - -} diff --git a/src/org/kde/kdeconnect/KdeConnectBroadcastReceiver.java b/src/org/kde/kdeconnect/KdeConnectBroadcastReceiver.java index 2cb73f34..e43afbab 100644 --- a/src/org/kde/kdeconnect/KdeConnectBroadcastReceiver.java +++ b/src/org/kde/kdeconnect/KdeConnectBroadcastReceiver.java @@ -67,7 +67,6 @@ public class KdeConnectBroadcastReceiver extends BroadcastReceiver BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() { @Override public void onServiceStart(BackgroundService service) { - service.onDeviceListChanged(); service.onNetworkChange(); } }); diff --git a/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java b/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java index 820e8deb..f3a7cde3 100644 --- a/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java +++ b/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java @@ -40,7 +40,6 @@ import android.widget.TextView; import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.Device; -import org.kde.kdeconnect.Helpers.NetworkHelper; import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper; import org.kde.kdeconnect.Plugins.Plugin; import org.kde.kdeconnect.UserInterface.List.CustomItem; @@ -334,11 +333,9 @@ public class DeviceFragment extends Fragment { boolean paired = device.isPaired(); boolean reachable = device.isReachable(); - boolean onData = NetworkHelper.isOnMobileNetwork(getContext()); rootView.findViewById(R.id.pairing_buttons).setVisibility(paired ? View.GONE : View.VISIBLE); - rootView.findViewById(R.id.not_reachable_message).setVisibility((paired && !reachable && !onData) ? View.VISIBLE : View.GONE); - rootView.findViewById(R.id.on_data_message).setVisibility((paired && !reachable && onData) ? View.VISIBLE : View.GONE); + rootView.findViewById(R.id.unpair_message).setVisibility((paired && !reachable) ? View.VISIBLE : View.GONE); try { ArrayList items = new ArrayList<>(); diff --git a/src/org/kde/kdeconnect/UserInterface/PairingFragment.java b/src/org/kde/kdeconnect/UserInterface/PairingFragment.java index c5fe6225..ecf65b0a 100644 --- a/src/org/kde/kdeconnect/UserInterface/PairingFragment.java +++ b/src/org/kde/kdeconnect/UserInterface/PairingFragment.java @@ -36,7 +36,6 @@ import android.widget.TextView; import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.Device; -import org.kde.kdeconnect.Helpers.NetworkHelper; import org.kde.kdeconnect.UserInterface.List.ListAdapter; import org.kde.kdeconnect.UserInterface.List.PairingDeviceItem; import org.kde.kdeconnect.UserInterface.List.SectionItem; @@ -61,8 +60,6 @@ public class PairingFragment extends Fragment implements PairingDeviceItem.Callb boolean listRefreshCalledThisFrame = false; - TextView headerText; - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -77,10 +74,10 @@ public class PairingFragment extends Fragment implements PairingDeviceItem.Callb rootView = inflater.inflate(R.layout.activity_list, container, false); - 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); + TextView text = new TextView(inflater.getContext()); + text.setText(getString(R.string.pairing_description)); + text.setPadding(0, (int) (16 * getResources().getDisplayMetrics().density), 0, (int) (12 * getResources().getDisplayMetrics().density)); + ((ListView) rootView).addHeaderView(text); return rootView; } @@ -107,8 +104,6 @@ public class PairingFragment extends Fragment implements PairingDeviceItem.Callb } listRefreshCalledThisFrame = true; - headerText.setText(getString(NetworkHelper.isOnMobileNetwork(getContext()) ? R.string.on_data_message : R.string.pairing_description)); - try { Collection devices = service.getDevices().values(); final ArrayList items = new ArrayList<>(); From b24010a86e0593ba44079d45110c815181e248f6 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Sat, 25 Feb 2017 21:12:32 +0100 Subject: [PATCH 11/40] Try a different approach to detect when on mobile data. --- res/layout/activity_device.xml | 15 ++++++++++- res/values/strings.xml | 1 + .../Backends/LanBackend/LanLinkProvider.java | 6 +++++ src/org/kde/kdeconnect/BackgroundService.java | 2 +- .../kde/kdeconnect/Helpers/NetworkHelper.java | 27 +++++++++++++++++++ .../KdeConnectBroadcastReceiver.java | 1 + .../UserInterface/DeviceFragment.java | 5 +++- .../UserInterface/PairingFragment.java | 13 ++++++--- 8 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 src/org/kde/kdeconnect/Helpers/NetworkHelper.java diff --git a/res/layout/activity_device.xml b/res/layout/activity_device.xml index 9bb47993..43028053 100644 --- a/res/layout/activity_device.xml +++ b/res/layout/activity_device.xml @@ -70,7 +70,7 @@ + + Rename Refresh This paired device is not reachable. Make sure it is connected to your same network. + It looks like you are on a mobile data connection. KDE Connect only works on local networks. There are no file browsers installed. Send SMS Send text messages from your desktop diff --git a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java index f6f0583e..867ce6db 100644 --- a/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java +++ b/src/org/kde/kdeconnect/Backends/LanBackend/LanLinkProvider.java @@ -31,6 +31,7 @@ import org.kde.kdeconnect.Backends.BaseLinkProvider; import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.Device; import org.kde.kdeconnect.Helpers.DeviceHelper; +import org.kde.kdeconnect.Helpers.NetworkHelper; import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper; import org.kde.kdeconnect.Helpers.StringsHelper; import org.kde.kdeconnect.NetworkPackage; @@ -362,6 +363,11 @@ public class LanLinkProvider extends BaseLinkProvider implements LanLink.LinkDis private void broadcastUdpPackage() { + if (NetworkHelper.isOnMobileNetwork(context)) { + Log.w("LanLinkProvider", "On 3G network, not sending broadcast."); + return; + } + new Thread(new Runnable() { @Override public void run() { diff --git a/src/org/kde/kdeconnect/BackgroundService.java b/src/org/kde/kdeconnect/BackgroundService.java index 7b5ef04a..ca6c2cca 100644 --- a/src/org/kde/kdeconnect/BackgroundService.java +++ b/src/org/kde/kdeconnect/BackgroundService.java @@ -119,7 +119,7 @@ public class BackgroundService extends Service { } }; - private void onDeviceListChanged() { + public void onDeviceListChanged() { for(DeviceListChangedCallback callback : deviceListChangedCallbacks.values()) { callback.onDeviceListChanged(); } diff --git a/src/org/kde/kdeconnect/Helpers/NetworkHelper.java b/src/org/kde/kdeconnect/Helpers/NetworkHelper.java new file mode 100644 index 00000000..cfd78ee4 --- /dev/null +++ b/src/org/kde/kdeconnect/Helpers/NetworkHelper.java @@ -0,0 +1,27 @@ +package org.kde.kdeconnect.Helpers; + +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkInfo; +import android.util.Log; + +public class NetworkHelper { + + public static boolean isOnMobileNetwork(Context context) { + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) { + return false; //No good way to know it + } + final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + Network[] networks = connMgr.getAllNetworks(); + for (Network network : networks) { + NetworkInfo info = connMgr.getNetworkInfo(network); + if (info.getType() == ConnectivityManager.TYPE_MOBILE) { + continue; + } + if (info.isConnected()) return false; //We are connected to at least one non-mobile network + } + return true; + } + +} diff --git a/src/org/kde/kdeconnect/KdeConnectBroadcastReceiver.java b/src/org/kde/kdeconnect/KdeConnectBroadcastReceiver.java index e43afbab..2cb73f34 100644 --- a/src/org/kde/kdeconnect/KdeConnectBroadcastReceiver.java +++ b/src/org/kde/kdeconnect/KdeConnectBroadcastReceiver.java @@ -67,6 +67,7 @@ public class KdeConnectBroadcastReceiver extends BroadcastReceiver BackgroundService.RunCommand(context, new BackgroundService.InstanceCallback() { @Override public void onServiceStart(BackgroundService service) { + service.onDeviceListChanged(); service.onNetworkChange(); } }); diff --git a/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java b/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java index f3a7cde3..820e8deb 100644 --- a/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java +++ b/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java @@ -40,6 +40,7 @@ import android.widget.TextView; import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.Device; +import org.kde.kdeconnect.Helpers.NetworkHelper; import org.kde.kdeconnect.Helpers.SecurityHelpers.SslHelper; import org.kde.kdeconnect.Plugins.Plugin; import org.kde.kdeconnect.UserInterface.List.CustomItem; @@ -333,9 +334,11 @@ public class DeviceFragment extends Fragment { boolean paired = device.isPaired(); boolean reachable = device.isReachable(); + boolean onData = NetworkHelper.isOnMobileNetwork(getContext()); rootView.findViewById(R.id.pairing_buttons).setVisibility(paired ? View.GONE : View.VISIBLE); - rootView.findViewById(R.id.unpair_message).setVisibility((paired && !reachable) ? View.VISIBLE : View.GONE); + rootView.findViewById(R.id.not_reachable_message).setVisibility((paired && !reachable && !onData) ? View.VISIBLE : View.GONE); + rootView.findViewById(R.id.on_data_message).setVisibility((paired && !reachable && onData) ? View.VISIBLE : View.GONE); try { ArrayList items = new ArrayList<>(); diff --git a/src/org/kde/kdeconnect/UserInterface/PairingFragment.java b/src/org/kde/kdeconnect/UserInterface/PairingFragment.java index ecf65b0a..c5fe6225 100644 --- a/src/org/kde/kdeconnect/UserInterface/PairingFragment.java +++ b/src/org/kde/kdeconnect/UserInterface/PairingFragment.java @@ -36,6 +36,7 @@ import android.widget.TextView; import org.kde.kdeconnect.BackgroundService; import org.kde.kdeconnect.Device; +import org.kde.kdeconnect.Helpers.NetworkHelper; import org.kde.kdeconnect.UserInterface.List.ListAdapter; import org.kde.kdeconnect.UserInterface.List.PairingDeviceItem; import org.kde.kdeconnect.UserInterface.List.SectionItem; @@ -60,6 +61,8 @@ public class PairingFragment extends Fragment implements PairingDeviceItem.Callb boolean listRefreshCalledThisFrame = false; + TextView headerText; + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -74,10 +77,10 @@ public class PairingFragment extends Fragment implements PairingDeviceItem.Callb rootView = inflater.inflate(R.layout.activity_list, container, false); - TextView text = new TextView(inflater.getContext()); - text.setText(getString(R.string.pairing_description)); - text.setPadding(0, (int) (16 * getResources().getDisplayMetrics().density), 0, (int) (12 * getResources().getDisplayMetrics().density)); - ((ListView) rootView).addHeaderView(text); + 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); return rootView; } @@ -104,6 +107,8 @@ public class PairingFragment extends Fragment implements PairingDeviceItem.Callb } listRefreshCalledThisFrame = true; + headerText.setText(getString(NetworkHelper.isOnMobileNetwork(getContext()) ? R.string.on_data_message : R.string.pairing_description)); + try { Collection devices = service.getDevices().values(); final ArrayList items = new ArrayList<>(); From 8935ab5d7fd492cfc96c77ca34307b72b5af0569 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Sat, 25 Feb 2017 21:41:55 +0100 Subject: [PATCH 12/40] Fix crash when fragment.getContext() was null --- AndroidManifest.xml | 2 +- src/org/kde/kdeconnect/Helpers/NetworkHelper.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 93ac647c..d88d9f0a 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,7 +1,7 @@ Date: Wed, 1 Mar 2017 03:45:22 +0100 Subject: [PATCH 13/40] GIT_SILENT made messages (after extraction) --- res/values-it/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index d902d6b7..c3298781 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -165,6 +165,7 @@ Rinomina Aggiorna Questo dispositivo associato non è raggiungibile. Assicurati che sia connesso alla tua stessa rete. + Sembra che tu stia utilizzando una connessione dati mobile. KDE Connect funziona solo su reti locali. Non ci sono navigatori di file installati. Invia SMS Invia messaggi di testo dal tuo desktop From d64452bbb687969749825306cd574bac75547dd1 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Sun, 5 Mar 2017 04:52:02 +0100 Subject: [PATCH 14/40] GIT_SILENT made messages (after extraction) --- res/values-da/strings.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index ca2d92b3..8ab792c5 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -10,6 +10,8 @@ Del indholdet af udklipsholderen Eksternt input Brug din telefon eller tablet som mus og tastatur + Modtag eksterne tastetryk + Modtag tastetryk-hændelser fra eksterne enheder Multimediekontroller Giver en fjernbetjening til din medieafspiller Kør kommando @@ -30,6 +32,10 @@ Du skal give tilladelse for at tilgå bekendtgørelser Send ping Multimediekontrol + Håndtér kun eksterne tastetryk under redigering + Der er ingen aktiv ekstern tastaturforbindelse. Opret en i kdeconnect + Ekstern tastaturforbindelse er aktiv + Der er mere end en ekstern tastaturforbindelse, vælg den enhed der skal konfigureres Eksternt input Bevæg en finger på skærmen for at flytte musemarkøren. Tap for at klikke og brug to/tre-fingre for højre og midterste museknap. Brug et langt tryk til at trække og slippe. Angiv handling for tap med to fingre @@ -159,6 +165,7 @@ Omdøb Genopfrisk Denne parrede enhed kan ikke nås. Sørg for at den er forbundet til samme netværk som dig. + Det lader til at du er på en mobil dataforbindelse. KDE Connect virker kun på lokale netværk. Der er ingen filhåndtering installeret. Send SMS Send SMS-beskeder fra din desktop From 64b124aefd20ae2c14d8ee5918725624893fac73 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Thu, 9 Mar 2017 03:53:11 +0100 Subject: [PATCH 15/40] GIT_SILENT made messages (after extraction) --- res/values-es/strings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 4e5d1556..1bb61b3d 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -159,12 +159,13 @@ %1$s en %2$s Enviar archivos Dispositivos de KDE Connect - Otros dispositivos ejecutando KDE Connect en su misma red deberían aparecer aquí. + Cualquier otro dispositivo ejecutando KDE Connect en su misma red debería aparecer aquí. Dispositivo vinculado Renombrar dispositivo Renombrar Actualizar Este dispositivo vinculado no está disponible. Asegúrese que está conectado a su misma red. + Parece que se encuentra en una conexión de datos móviles. KDE Connect solo funciona en redes locales. No hay navegadores de archivos instalados. Enviar SMS Enviar mensajes de texto desde el escritorio From 2ace4aaef19c3136b741b3adb13da02f5c2f32ce Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Wed, 15 Mar 2017 03:29:06 +0100 Subject: [PATCH 16/40] GIT_SILENT made messages (after extraction) --- res/values-de/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 655b4eb3..05b9b7fa 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -131,7 +131,7 @@ Benutzerdefinierte Geräteliste Ein neues Gerät verbinden Verbindung %s trennen - Geräte nach IP hinzufügen + Geräte nach IP-Adresse hinzufügen Ausführliche Benachrichtigungen Beim Empfang einer Datei vibrieren und einen Sound abspielen Zielverzeichnis anpassen @@ -146,8 +146,8 @@ SD-Karte (Nur lesen) Kamerabilder - Rechner/IP hinzufügen - Rechnername oder IP + Rechner/IP-Adresse hinzufügen + Rechnername oder IP-Adresse Keine Medienspieler gefunden Benutzen Sie diese Funktion nur, wenn Ihr Gerät nicht automatisch erkannt wird. Geben hier Sie IP-Adresse oder Hostnamen ein und bestätigen Sie, um es zu der Liste hinzuzufügen. Tippen Sie ein bestehendes Gerät an, um es aus der Liste zu entfernen. %1$s auf %2$s From 09cbd444e648e80c6ffee08e9b52aa4cb36b9657 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Sat, 18 Mar 2017 02:12:22 +0100 Subject: [PATCH 17/40] Update gradle plugin --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index aa0fcb03..8804a319 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.3' + classpath 'com.android.tools.build:gradle:2.3.0' } } From bf230509b86f09adda8b1c238dacb9463ee7a8e1 Mon Sep 17 00:00:00 2001 From: Zixing Liu Date: Sat, 18 Mar 2017 02:14:31 +0100 Subject: [PATCH 18/40] Add swipe to refresh to device pairing activity This makes it more conform to material design standard REVIEW: 129980 --- res/layout/activity_refresh_list.xml | 17 +++++ res/menu/pairing.xml | 8 -- res/menu/refresh.xml | 10 +-- .../Plugins/SharePlugin/ShareActivity.java | 75 +++++++++++-------- .../UserInterface/PairingFragment.java | 67 ++++++++++------- 5 files changed, 100 insertions(+), 77 deletions(-) create mode 100644 res/layout/activity_refresh_list.xml diff --git a/res/layout/activity_refresh_list.xml b/res/layout/activity_refresh_list.xml new file mode 100644 index 00000000..bdc9f5ef --- /dev/null +++ b/res/layout/activity_refresh_list.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/res/menu/pairing.xml b/res/menu/pairing.xml index ffc8c144..1589a7ab 100644 --- a/res/menu/pairing.xml +++ b/res/menu/pairing.xml @@ -9,14 +9,6 @@ android:title="@string/refresh" /> - - - - diff --git a/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareActivity.java b/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareActivity.java index c2fe9c79..ae94b465 100644 --- a/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareActivity.java +++ b/src/org/kde/kdeconnect/Plugins/SharePlugin/ShareActivity.java @@ -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); + } } diff --git a/src/org/kde/kdeconnect/UserInterface/PairingFragment.java b/src/org/kde/kdeconnect/UserInterface/PairingFragment.java index c5fe6225..2db9ecb2 100644 --- a/src/org/kde/kdeconnect/UserInterface/PairingFragment.java +++ b/src/org/kde/kdeconnect/UserInterface/PairingFragment.java @@ -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) { @@ -227,33 +260,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(); From dbf069cf85a97e1bf2693b0b84b230b29e573254 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Tue, 28 Feb 2017 21:21:31 +0100 Subject: [PATCH 19/40] Further refining the network detection --- src/org/kde/kdeconnect/Helpers/NetworkHelper.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/org/kde/kdeconnect/Helpers/NetworkHelper.java b/src/org/kde/kdeconnect/Helpers/NetworkHelper.java index 75f05b91..f6d37425 100644 --- a/src/org/kde/kdeconnect/Helpers/NetworkHelper.java +++ b/src/org/kde/kdeconnect/Helpers/NetworkHelper.java @@ -4,6 +4,7 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkInfo; +import android.util.Log; public class NetworkHelper { @@ -11,16 +12,19 @@ public class NetworkHelper { if (context == null || android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) { return false; //No good way to know it } + boolean mobile = false; final ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); Network[] networks = connMgr.getAllNetworks(); for (Network network : networks) { NetworkInfo info = connMgr.getNetworkInfo(network); if (info.getType() == ConnectivityManager.TYPE_MOBILE) { + mobile = info.isConnected(); continue; } - if (info.isConnected()) return false; //We are connected to at least one non-mobile network + Log.e(info.getTypeName(),""+info.isAvailable()); + if (info.isAvailable()) return false; //We are connected to at least one non-mobile network } - return true; + return mobile; } } From 2cdf743bbac696ab6400f2ffd73f84a6200f14dd Mon Sep 17 00:00:00 2001 From: Nicolas Fella Date: Thu, 13 Apr 2017 21:26:26 +0200 Subject: [PATCH 20/40] Added Notification icons Some additional fields are transferred in a network package. This includes the payloads MD5 checksum (which determines where the image file is stored) and the notifications title and text (which allows more flexibility in the desktop app, ticker is still transferred for compatibility) REVIEW: 130033 --- .../NotificationsPlugin.java | 113 +++++++++++++++--- 1 file changed, 98 insertions(+), 15 deletions(-) diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java index e983bc4f..0185d940 100644 --- a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java +++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java @@ -26,6 +26,7 @@ import android.app.AlertDialog; import android.app.Notification; import android.content.DialogInterface; import android.content.Intent; +import android.graphics.Bitmap; import android.os.Build; import android.os.Bundle; import android.provider.Settings; @@ -39,15 +40,19 @@ 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; + @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"; -/* - private boolean sendIcons = false; -*/ + + private boolean sendIcons = true; + @Override public String getDisplayName() { @@ -155,6 +160,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) && @@ -178,28 +185,35 @@ 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"); } } -*/ + 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); @@ -209,6 +223,50 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver. device.sendPackage(np); } + 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 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. @@ -230,7 +288,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) { @@ -398,4 +456,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(); + } + } From 5d7b0a976a2868bde053a8e040f7ef2c948b9a6c Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Mon, 15 May 2017 03:14:09 +0200 Subject: [PATCH 21/40] GIT_SILENT made messages (after extraction) --- res/values-ru/strings.xml | 49 ++++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 84d54db9..fd7a5b89 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -5,15 +5,23 @@ Состояние батареи Периодическое информирование о состоянии батареи Просмотр файловой системы + Позволяет удалённо просматривать файловую систему устройства Синхронизация буфера обмена Использование общего буфера обмена Удалённый ввод + Использование телефона или планшета в качестве сенсорной панели и клавиатуры + Получение удалённых нажатий клавиш + Получение нажатий клавиш с удалённых устройств Управление воспроизведением + Обеспечивает дистанционное управление медиапроигрывателем Запуск команд + Удалённый запуск команд с телефона или планшета Пинг Отправка и получение тестовых сигналов Синхронизация уведомлений Доступ к уведомлениям с других устройств + Получение уведомлений + Получение уведомлений с другого устройства и показ их на Android Отправка и приём данных Пересылка файлов и адресов URL между устройствами Эта функциональность недоступна в вашей версии Android @@ -24,10 +32,16 @@ Нужно разрешить доступ к уведомлениям Отправить тестовый сигнал Управление воспроизведением + Обрабатывать удалённые нажатия только при редактировании + Нет активного соединения с удалённой клавиатурой, установите его в KDE Connect + Соединение с удалённой клавиатурой активно + Подключено более одной удалённой клавиатуры, выберите устройство для настройки Удалённый ввод Перемещайте палец по экрану для перемещения курсора мыши. Коснитесь для нажатия, используйте два/три пальца для правой и средней кнопок. Используйте долгое нажатие для перетаскивания. Действие при нажатии двумя пальцами Действие при нажатии тремя пальцами + Чувствительность сенсорной панели + Инвертировать направление прокрутки Нажатие правой кнопки Нажатие средней кнопки @@ -35,12 +49,13 @@ Нажатие правой кнопки Нажатие средней кнопки + Обычная - Slowest - Above Slowest - Default - Above Default - Fastest + Самая низкая + Низкая + Обычная + Высокая + Самая высокая Подключённые устройства Доступные устройства @@ -49,15 +64,20 @@ Настройка модулей Снять сопряжение Сопряжённое устройство недоступно + Подключить новое устройство Неизвестное устройство Устройство недоступно Запрос на сопряжение уже был сделан Устройство уже сопряжено - Не удалось отправить пакет. + Не удалось отправить пакет Истекло время ожидания Отменено пользователем Отменено другим участником Получен недопустимый ключ + Информация о шифровании + На другом устройстве используется старая версия KDE Connect, используется старый метод шифрования. + Отпечаток SHA-1 сертификата вашего устройства: + Отпечаток SHA-1 сертификата удалённого устройства: Запрошено сопряжение Запрос на сопряжение от %1s Получена ссылка от %1s @@ -65,12 +85,15 @@ Входящий файл с %1s %1s Отправка файла на %1s + Отправка файлов на %1s %1s + Отправлено %1$d из %2$d файлов Получен файл с %1s Не удалось получить файл с %1s Нажмите, чтобы открыть «%1s» Файл отправлен на %1s %1s + Не удалось отправить файл на %1s %1s Нажмите, чтобы ответить Подключить заново @@ -102,8 +125,8 @@ 2 минуты Отправить на... - Это устройство использует старую версию протокола. - Это устройство использует более новую версию протокола. + Это устройство использует старую версию протокола + Это устройство использует более новую версию протокола Общие параметры Настройка Настройка %s @@ -116,7 +139,11 @@ Снять сопряжение с %s Добавить устройства по IP Звуковые уведомления - Использовать звуковой сигнал и вибрацию при получении файла. + Использовать вибрацию и звуковой сигнал при получении файла + Задать целевой каталог + Полученные файлы появятся в каталоге Загрузки + Файлы будут сохранены в указанном ниже каталоге + Целевой каталог Фильтр уведомлений Уведомления будут синхронизированы для выбранных приложений. Встроенная память @@ -138,10 +165,14 @@ Переименовать Обновить Это сопряжённое устройство недоступно. Проверьте, что оно подключено к той же локальной сети. + Похоже, вы подключены к мобильной сети. KDE Connect работает только в локальных сетях. Не удалось открыть диалог выбора файла. Отправка SMS Отправка SMS-сообщений с вашего компьютера Этот модуль не поддерживается устройством + Поиск телефона + Поиск планшета + Подача звукового сигнала на устройстве, чтобы вы могли его найти Найден Открыть Закрыть From 20455f74ab87486872b79564fb09fc74a6d7b3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Fiestas?= Date: Thu, 25 May 2017 00:08:29 +0200 Subject: [PATCH 22/40] Add Bluetooth support This is a ported version of the patch submited in review: https://git.reviewboard.kde.org/r/128270 It is disabled by default. REVIEW: 128270 --- AndroidManifest.xml | 2 + .../BluetoothBackend/BluetoothLink.java | 244 ++++++++++++ .../BluetoothLinkProvider.java | 377 ++++++++++++++++++ .../BluetoothPairingHandler.java | 193 +++++++++ src/org/kde/kdeconnect/BackgroundService.java | 8 +- 5 files changed, 820 insertions(+), 4 deletions(-) create mode 100644 src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java create mode 100644 src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLinkProvider.java create mode 100644 src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothPairingHandler.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index d88d9f0a..903ed8ab 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -18,6 +18,8 @@ + + diff --git a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java new file mode 100644 index 00000000..4f092b3b --- /dev/null +++ b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java @@ -0,0 +1,244 @@ +/* + * Copyright 2016 Saikrishna Arcot + * + * 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 . +*/ + +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; + 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) { + 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; + } + } +*/ +} diff --git a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLinkProvider.java b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLinkProvider.java new file mode 100644 index 00000000..20090ea7 --- /dev/null +++ b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLinkProvider.java @@ -0,0 +1,377 @@ +/* + * Copyright 2016 Saikrishna Arcot + * + * 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 . +*/ + +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 visibleComputers = new HashMap<>(); + private final Map 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("KDEConnect", "BluetoothLinkProvider: oldLink == link. This should not happen!"); + return; + } + visibleComputers.put(deviceId, link); + connectionAccepted(identityPackage, link); + 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 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 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); + } + } + } +} diff --git a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothPairingHandler.java b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothPairingHandler.java new file mode 100644 index 00000000..1d380e05 --- /dev/null +++ b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothPairingHandler.java @@ -0,0 +1,193 @@ +/* + * Copyright 2015 Vineet Garg + * + * 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 . +*/ + +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); + } +} diff --git a/src/org/kde/kdeconnect/BackgroundService.java b/src/org/kde/kdeconnect/BackgroundService.java index ca6c2cca..f10ac1d1 100644 --- a/src/org/kde/kdeconnect/BackgroundService.java +++ b/src/org/kde/kdeconnect/BackgroundService.java @@ -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,9 @@ public class BackgroundService extends Service { } private void registerLinkProviders() { - - //linkProviders.add(new LoopbackLinkProvider(this)); - linkProviders.add(new LanLinkProvider(this)); - +// linkProviders.add(new LoopbackLinkProvider(this)); +// linkProviders.add(new BluetoothLinkProvider(this)); } public ArrayList getLinkProviders() { From 63f8f86cd597a28f46363aa28a5e4f3e895c0a3b Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Thu, 25 May 2017 02:58:42 +0200 Subject: [PATCH 23/40] GIT_SILENT made messages (after extraction) --- res/values-he/strings.xml | 70 +++++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/res/values-he/strings.xml b/res/values-he/strings.xml index 63c91c95..e381949b 100644 --- a/res/values-he/strings.xml +++ b/res/values-he/strings.xml @@ -5,15 +5,23 @@ דיווח סוללה מדווח על אחוז הסוללה למחשב גישה לקבצים - סנכנרון לוח העתקה - שתף בין המחשבים את מה שמועתק + אפשר להתקן המרוחק לדפדף בקבצים של הפלאפון מרחוק + סנכרון לוח העתקה + שתף בין המחשבים את כל מה שמועתק שליטה מרחוק + השתמש בפלאפון כדי לשלוט בעכבר ובמקלדת של ההתקן המרוחק + קבלת לחיצות מרחוק + קבלת אירועי מקלדת מהתקן מרוחק שליטה במדיה + מספק שליטה מרוחקת על נגן המדיה שלך הרץ פקודה + הרץ פקודה במחשב מהמכשיר שלך פינג שלח וקבל פינגים סנכרון התראות הראה את ההתראות מהפלאפון בהתקן אחר + קבלת התראות + קבל התראות מהתקן אחר והצג אותם במכשיר שלך שתף וקבל קבצים וכתובות שתף וקבל קבצים וכתובת אינטרנט בין התקנים אפשרות זו אינה זמינה בגרסת האנדרואיד שלך @@ -24,7 +32,11 @@ אתה צריך לתת הרשאות לגישה להתראות שלח פינג שליטה על המדיה - שלוט על המחשב + השתמש במקשים מרוחקים רק בעת עריכה + אין מקלדת מרוחקת מופעלת, הוסף אחת ל־kdeconnect + חיבור המקדלת המרוחקת פעיל + ישנם כמה מקלדות מרוחקות מחוברות, בחר את ההתקן להגדרה + שליטה מרחוק הזז את האצבע על המסך כדי להזיז את סמן העכבר במחשב. לחץ כדי ללחוץ במחשב, השתמש בשנים או שלוש אצבעות כדי ללחוץ על המקש הימני או האמצעי. השתמש בליחצה ארוכה לגרירה ושחרור. הגדר פעולה ללחיצת שתי אצבעות הגדר פעולה ללחיצת שלוש אצבעות @@ -59,9 +71,9 @@ ההתקן כבר מותאם לא יכול לשלוח חבילה נגמר הזמן - בוטל ע\"י המשתמש - בוטל ע\"י מישהו אחר - התקבל מפתח לא חוקי + בוטל על ידי המשתמש + בוטל על ידי מישהו אחר + התקבל מפתח לא תקין פרטי הצפנה ההתקן השני אינו משתמש בגרסה האחרונה של KDE Connect, משתמש בשיטת ההצפנה הישנה. טביעת האצבע SHA1 של ההתקן היא: @@ -69,16 +81,19 @@ בקשת התאמה בוקשה התאמה מ־%1s התקבל קישור מ־%1s - לחץ כדי לפתוח את \'%1s\' - התקבל קובץ ־%1s + לחץ כדי לפתוח את \"%1s\" + התקבל קובץ מאת %1s %1s - שולח קובץ ל־%1s + שולח קובץ אל %1s + שולח קובצים אל %1s %1s - התקבל קובץ מ־%1s - נכשל בקבלת קובץ מ־%1s - לחץ כדי לפתוח את %1s - הקובץ נשלח ל־%1s + "שולח %1$d מתוך %2$d קבצים " + התקבל קובץ מאת %1s + נכשל בקבלת קובץ מאת %1s + לחץ כדי לפתוח את \"%1s\" + הקובץ נשלח אל %1s %1s + נכשל בשליחת הקובץ אל %1s %1s לחץ כדי לענות התחבר מחדש @@ -109,22 +124,26 @@ דקה שתי דקות - שתף ל... + שתף אל... ההתקן משתמש בגרסה ישנה יותר ההתקן משתמש בגרסה חדשה יותר הגדרות כלליות הגדרות הגדרות %s - שם המכשיר + שם ההתקן %s - שם המכשיר לא תקין + שם ההתקן לא תקין התקבל טקסט, נשמר ללוח העתקה רשימת התקנים מותאמת אישית התאם התקן חדש בטל את ההתאמה עם %s - הוסף התקן ע\"י כתובת IP + הוסף התקן על ידי כתובת IP התראות רועשות רטוט ונגן צליל בעת קבלת קובץ + שנה תקיית יעד + קבצים שהתקבלו יהיו בהורדות + קבצים יאוכסנו בתיקיה למטה + תיקית יעד סנן התראות התראות יסונכרנו רק לאפליקציות נבחרות זיכרון פנימי @@ -133,11 +152,11 @@ כרטיס זיכרון (לקריאה בלבד) תמונות מצלמה - הוסף כתובת שרת או IP - כתבות שרת או IP + הוסף כתובת או IP + כתובת או IP לא נמצא נגן השתמש באפשרות זו רק אם המכשיר שלך לא מזוהה באופן אוטומטי. הקלד את כתובת הIP או את כינוי ההתקן למטה ולחץ על הכפתור כדי להוסיף לרשימה. לחץ על פריט קיים כדי להסיר אותו מהרשימה. - %1$s ב־%2$s + ‏%1$s אצל %2$s שלח קובץ מכשירי KDE Connect התקנים אחרים המריצים KDE Connect ברשת הנוכחית צריכים להופיע פה. @@ -145,12 +164,15 @@ שנה שם התקן שנה שם רענן - ההתקן המתואם לא זמין, וודא שהוא מחובר לאותה רשת אליה התקן זה מחובר. + ההתקן המתואם לא זמין, וודא שהוא מחובר לאותה רשת אליה אתה מחובר. + נראה שאתה מחובר דרך הרשת הסלולרית. KDE Connect עובד רק עם רשתות מקומיות. לא נמצאו מנהלי קבצים מותקנים במכשיר זה. - שלח SMS + שליחת הודעת SMS שלח הודעות מהמחשב שלך - התוסף הזה לא נתמך ע\"י המכשיר שלך - מצא את המכשיר שלי + תוסף הזה לא נתמך על ידי המכשיר שלך + מצא את הפלאפון שלי + מצא את הטבלט שלי + מפעיל רעש במכשיר כדי שתוכל למצוא אותו. נמצא פתח סגור From 981685e926dbeb0239f2bef5903d4c71a1c430c1 Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Thu, 25 May 2017 22:18:32 +0200 Subject: [PATCH 24/40] Avoid NPE when pluginList is still getting updated, by starting the receiving thread after the pluginList is updated. Also have the pluginList be initialized to an empty map. REVIEW: 130140 --- .../Backends/BluetoothBackend/BluetoothLink.java | 8 ++++++-- .../Backends/BluetoothBackend/BluetoothLinkProvider.java | 3 ++- src/org/kde/kdeconnect/BackgroundService.java | 4 +++- src/org/kde/kdeconnect/Device.java | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java index 4f092b3b..83879142 100644 --- a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java +++ b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLink.java @@ -116,7 +116,10 @@ public class BluetoothLink extends BaseLink { super(context, deviceId, linkProvider); this.socket = socket; this.linkProvider = linkProvider; - receivingThread.start(); + } + + public void startListening() { + this.receivingThread.start(); } @Override @@ -195,7 +198,8 @@ public class BluetoothLink extends BaseLink { serverSocket.close(); int idealBufferLength = 4096; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M + && transferSocket.getMaxReceivePacketSize() > 0) { idealBufferLength = transferSocket.getMaxReceivePacketSize(); } byte[] buffer = new byte[idealBufferLength]; diff --git a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLinkProvider.java b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLinkProvider.java index 20090ea7..629b1c6e 100644 --- a/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLinkProvider.java +++ b/src/org/kde/kdeconnect/Backends/BluetoothBackend/BluetoothLinkProvider.java @@ -63,11 +63,12 @@ public class BluetoothLinkProvider extends BaseLinkProvider { Log.i("BluetoothLinkProvider","addLink to "+deviceId); BluetoothLink oldLink = visibleComputers.get(deviceId); if (oldLink == link) { - Log.e("KDEConnect", "BluetoothLinkProvider: oldLink == link. This should not happen!"); + 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(); diff --git a/src/org/kde/kdeconnect/BackgroundService.java b/src/org/kde/kdeconnect/BackgroundService.java index f10ac1d1..16c5efc1 100644 --- a/src/org/kde/kdeconnect/BackgroundService.java +++ b/src/org/kde/kdeconnect/BackgroundService.java @@ -144,7 +144,9 @@ public class BackgroundService extends Service { private void registerLinkProviders() { linkProviders.add(new LanLinkProvider(this)); // linkProviders.add(new LoopbackLinkProvider(this)); -// linkProviders.add(new BluetoothLinkProvider(this)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { +// linkProviders.add(new BluetoothLinkProvider(this)); + } } public ArrayList getLinkProviders() { diff --git a/src/org/kde/kdeconnect/Device.java b/src/org/kde/kdeconnect/Device.java index 3da45204..ba91436a 100644 --- a/src/org/kde/kdeconnect/Device.java +++ b/src/org/kde/kdeconnect/Device.java @@ -82,7 +82,7 @@ public class Device implements BaseLink.PackageReceiver { private List m_supportedPlugins = new ArrayList<>(); private final ConcurrentHashMap plugins = new ConcurrentHashMap<>(); private final ConcurrentHashMap failedPlugins = new ConcurrentHashMap<>(); - private Map> pluginsByIncomingInterface; + private Map> pluginsByIncomingInterface = new HashMap<>(); private final SharedPreferences settings; From f392505d21d51d141567c951ee14c692698f1508 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Sat, 27 May 2017 03:02:08 +0200 Subject: [PATCH 25/40] GIT_SILENT Add new file (after extraction) --- res/values-sr/strings.xml | 178 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 res/values-sr/strings.xml diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml new file mode 100644 index 00000000..e551a350 --- /dev/null +++ b/res/values-sr/strings.xml @@ -0,0 +1,178 @@ + + + Обавештења телефона + Шаље обавештења за СМС и позиве + Извештај о батерији + Периодично извештава о стању батерије + Приступ фајл систему + Дозвољава даљински приступ фајл систему уређаја + Усклађени клипборд + Дељење садржаја клипборда + Даљински унос + Користите телефон или таблет као додирник и тастатуру + Пријем даљинских тастера + Примање тастерских догађаја са удаљених уређаја + Управљање мултимедијом + Омогућава даљинско управљање медија плејером + Извршавање наредбе + Даљински окида наредбе са телефона или таблета + Пинг + Шаље и прима пингове + Усклађена обавештења + Приступа вашим обавештењима са другог уређаја + Пријем обавештења + Прима обавештења са других уређаја и приказује их на Андроиду + Дели и примај + Дели фајлове и УРЛ‑ове између уређаја + Ова могућност није доступна на вашој верзији Андроида + Нема уређаја + У реду + Откажи + Отвори поставке + Морате дати дозволу за приступ обавештењима + Пошаљи пинг + Контрола мултимедије + Користи даљинске дугмиће само при уређивању + Нема активне везе даљинске тастатуре. Успоставите је у КДЕ‑конекцији + Веза даљинске тастатуре је активна + Постоји више од једне везе даљинске тастатуре. Изаберите уређај да бисте подесили + Даљински унос + Померајте прст по екрану да бисте померали показивач миша. Тапните за клик или користите два/три прста за десни или средњи клик. Задржите за превуци и пусти. + Радња за додир са два прста + Радња за додир са три прста + Постави осетљивост додирника + Обрни смер клизања + + десни клик + средњи клик + ништа + + десни + средњи + подразумевано + + најспорије + мало спорије + подразумевано + мало брже + најбрже + + Повезани уређаји + Доступни уређаји + Упамћени уређаји + Неуспело учитавање прикључка (тапните за више информација): + Поставке прикључака + Распари + Упарени уређај није доступан + Упари нов уређај + Непознат уређај + Уређај није доступан + Упаривање је већ тражено + Уређај је већ упарен + Не могу да пошаљем пакет + Истекло је време + Корисник отказао + Отказала друга страна + Примљен је неисправан кључ + Подаци о шифровању + Друга страна не користи најновију верзију, стога се користи старији метод шифровања. + СХА‑1 отисак сертификата вашег уређаја је: + СХА‑1 отисак сертификата удаљеног уређаја је: + Упаривање је тражено + Захтев за упаривање са %1s + Примљена веза са %1s + Тапните да отворите „%1s“ + Долазни фајл са %1s + %1s + Шаљем фајл на %1s + Шаљем фајлове на %1s + %1s + Примљен фајл са %1s + Неуспео пријем фајла са %1s + Тапните да отворите „%1s“ + Послат фајл на %1s + %1s + Неуспело слање фајла на %1s + %1s + Тапните да одговорите + Поново повежи + Пошаљи десни клик + Пошаљи средњи клик + Прикажи тастатуру + Уређај није упарен + Тражи упаривање + Прихвати + Одбаци + Уређај + Упари уређај + Даљинско управљање + Поставке за КДЕ‑конекцију + Пусти + Претходно + Премотај + Брзо унапред + Следеће + Јачина + Поставке мултимедије + Напред/назад дугмад + Подесите време прескакања за напред/назад дугмад. + + 10 секунди + 20 секунди + 30 секунди + 1 минут + 2 минута + + Дели... + Овај уређај користи стару верзију протокола + Овај уређај користи новију верзију протокола + Опште поставке + Поставке + %s — поставке + Назив уређаја + %s + Неисправан назив уређаја + Примљен текст, сачуван у клипборд + Списак посебних уређаја + Упари нови уређај + Распари %s + Додај уређај по ИП адреси + Бучна обавештења + Вибрирај и пусти звук кад примаш фајл + Прилагоди одредишну фасциклу + Фајлови се смештају у Downloads + Фајлови се смештају у фасциклу испод + Одредишна фасцикла + Филтер обавештења + Обавештења ће се синхронизовати за изабране апликације. + Унутрашња меморија + сви фајлови + СД картица %d + СД картица + (само за читање) + Слике са камере + Додај домаћина/ИП + Име домаћина или ИП + Нисам нашао плејере + Користите ову опцију само ако се ваши уређаји не приказују аутоматски. Унесите ИП адресу или име домаћина и додирните дугме да га додате на листу. Додирните постојећу ставку да бисте је уклонили. + %1$s на %2$s + Пошаљи фајлове + Уређаји КДЕ‑конекције + Други уређаји на вашој мрежи на којима ради КДЕ‑конекција, појавиће се овде. + Уређај упарен + Преименовање уређаја + Преименуј + Освежи + Овај упарени уређај није доступан. Проверите да ли је повезан на исту мрежу. + Чини се да сте на мобилној мрежи. КДЕ‑конекција ради само на локалној мрежи. + Нема инсталираних прегледача фајлова. + Шаљи СМС + Шаљите текстуалне поруке помоћу рачунара + Уређај не подржава овај прикључак + Нађи мој телефон + Нађи мој таблет + Активира звоно уређаја како бисте га пронашли + Нађен + Отвори + Затвори + From d0f3c8eb22054520c70b2098c8ccf4d4dc51c448 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Tue, 30 May 2017 02:56:10 +0200 Subject: [PATCH 26/40] GIT_SILENT made messages (after extraction) --- res/values-ca/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 2eef61aa..1d1a7d89 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -91,7 +91,7 @@ Fitxer rebut des de %1s Ha fallat en rebre el fitxer des de %1s Puntegeu per obrir «%1s» - Envia el fitxer a %1s + Fitxer enviat a %1s %1s Ha fallat en enviar el fitxer a %1s %1s From 05d728b846a3b03e1f66fe0eedb34d1046e32622 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Wed, 31 May 2017 00:01:42 +0200 Subject: [PATCH 27/40] Don't lose the stacktrace. --- .../Plugins/SharePlugin/NotificationUpdateCallback.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/org/kde/kdeconnect/Plugins/SharePlugin/NotificationUpdateCallback.java b/src/org/kde/kdeconnect/Plugins/SharePlugin/NotificationUpdateCallback.java index 78219de1..2b0a987e 100644 --- a/src/org/kde/kdeconnect/Plugins/SharePlugin/NotificationUpdateCallback.java +++ b/src/org/kde/kdeconnect/Plugins/SharePlugin/NotificationUpdateCallback.java @@ -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() { From 6d216b2766bbd399b846ec0f43b4628fd384e913 Mon Sep 17 00:00:00 2001 From: Julian Wolff Date: Wed, 31 May 2017 00:08:38 +0200 Subject: [PATCH 28/40] reply to notifications Summary: These changes allow replying to any notifications that offer quick reply text fields (like WhatsApp). Does work for WhatsApp. Does not work for Telegram. Reviewers: #kde_connect, albertvaka Reviewed By: #kde_connect, albertvaka Subscribers: albertvaka Maniphest Tasks: T4674 Differential Revision: https://phabricator.kde.org/D5991 --- .../NotificationsPlugin.java | 102 +++++++++++++++++- .../RepliableNotification.java | 16 +++ 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/org/kde/kdeconnect/Plugins/NotificationsPlugin/RepliableNotification.java diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java index 0185d940..d2643c09 100644 --- a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java +++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/NotificationsPlugin.java @@ -24,6 +24,8 @@ 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; @@ -33,6 +35,7 @@ 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; @@ -43,15 +46,23 @@ 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 pendingIntents; @Override @@ -86,6 +97,8 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver. @Override public boolean onCreate() { + pendingIntents = new HashMap(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { if (hasPermission()) { NotificationReceiver.RunCommand(context, new NotificationReceiver.InstanceCallback() { @@ -207,6 +220,12 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver. 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); @@ -223,6 +242,52 @@ 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"; @@ -244,6 +309,37 @@ public class NotificationsPlugin extends Plugin implements NotificationReceiver. 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"; @@ -363,6 +459,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; @@ -406,7 +506,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 diff --git a/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/RepliableNotification.java b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/RepliableNotification.java new file mode 100644 index 00000000..f0dd1e56 --- /dev/null +++ b/src/org/kde/kdeconnect/Plugins/NotificationsPlugin/RepliableNotification.java @@ -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 remoteInputs = new ArrayList<>(); + public String packageName; + public String tag; +} From f8bb5d4dd48bf9c9339cb9815dd271de6bed9213 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Tue, 30 May 2017 23:50:46 +0200 Subject: [PATCH 29/40] Reuse the same builder --- src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java index fc2042e0..318d4982 100644 --- a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java +++ b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java @@ -186,8 +186,7 @@ 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); From 07ec3f213250ba11ab28bc8c00a593d78601f268 Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Tue, 30 May 2017 23:51:18 +0200 Subject: [PATCH 30/40] Mark the notification as not ongoing when it's done --- src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java index 318d4982..6ea79fd1 100644 --- a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java +++ b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java @@ -189,7 +189,9 @@ public class SharePlugin extends Plugin { builder.setContentTitle(message) .setTicker(message) .setSmallIcon(android.R.drawable.stat_sys_download_done) - .setAutoCancel(true); + .setAutoCancel(true) + .setProgress(100,100,false) + .setOngoing(false); if (successful) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(destinationUri, mimeType); From e13090066c27315f91bad2800d570a5c80b9cfab Mon Sep 17 00:00:00 2001 From: Albert Vaca Date: Tue, 30 May 2017 23:48:58 +0200 Subject: [PATCH 31/40] Update the notification less often Otherwise, for some reason it stops allowing further updates afterwards and looks like the download never completed (even though it did). --- src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java index 6ea79fd1..62195aa6 100644 --- a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java +++ b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java @@ -159,10 +159,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()); } } From 0b83cfe06d263fb4af5fcd1dcb5b70010568dc27 Mon Sep 17 00:00:00 2001 From: Nicolas Fella Date: Wed, 31 May 2017 15:51:07 +0200 Subject: [PATCH 32/40] Implement Android 6 Runtime Permissions Differential Revision: https://phabricator.kde.org/D5876 --- AndroidManifest.xml | 2 +- build.gradle | 7 +- res/values/strings.xml | 4 + src/org/kde/kdeconnect/Device.java | 15 ++++ src/org/kde/kdeconnect/Plugins/Plugin.java | 84 ++++++++++++++++-- .../Plugins/SftpPlugin/SftpPlugin.java | 87 +++++++++++-------- .../Plugins/SharePlugin/SharePlugin.java | 46 ++++++++-- .../TelepathyPlugin/TelepathyPlugin.java | 27 ++++-- .../TelephonyPlugin/TelephonyPlugin.java | 76 ++++++++++------ .../UserInterface/DeviceFragment.java | 33 +++++++ .../UserInterface/MaterialActivity.java | 19 ++++ 11 files changed, 310 insertions(+), 90 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 903ed8ab..72fc9271 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -5,7 +5,7 @@ android:versionName="1.6.2"> + android:targetSdkVersion="25" /> 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' } diff --git a/res/values/strings.xml b/res/values/strings.xml index f78801be..9d949646 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -206,4 +206,8 @@ Open Close + You need to grant permissions to access the storage + Some Plugins need permissions to work (tap for more info): + This plugin needs permissions to work + diff --git a/src/org/kde/kdeconnect/Device.java b/src/org/kde/kdeconnect/Device.java index ba91436a..cb234c8e 100644 --- a/src/org/kde/kdeconnect/Device.java +++ b/src/org/kde/kdeconnect/Device.java @@ -82,6 +82,7 @@ public class Device implements BaseLink.PackageReceiver { private List m_supportedPlugins = new ArrayList<>(); private final ConcurrentHashMap plugins = new ConcurrentHashMap<>(); private final ConcurrentHashMap failedPlugins = new ConcurrentHashMap<>(); + private final ConcurrentHashMap pluginsWithoutPermissions = new ConcurrentHashMap<>(); private Map> 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 getPluginsWithoutPermissions() { + return pluginsWithoutPermissions; + } + public void addPluginsChangedListener(PluginsChangedListener listener) { pluginsChangedListeners.add(listener); } diff --git a/src/org/kde/kdeconnect/Plugins/Plugin.java b/src/org/kde/kdeconnect/Plugins/Plugin.java index 67650e7f..00b0c68b 100644 --- a/src/org/kde/kdeconnect/Plugins/Plugin.java +++ b/src/org/kde/kdeconnect/Plugins/Plugin.java @@ -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; + } + } diff --git a/src/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java b/src/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java index 6842c00a..ee002070 100644 --- a/src/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java +++ b/src/org/kde/kdeconnect/Plugins/SftpPlugin/SftpPlugin.java @@ -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); @@ -75,50 +86,48 @@ public class SftpPlugin extends Plugin { //Kept for compatibility, in case "multiPaths" is not possible or the other end does not support it np2.set("path", Environment.getExternalStorageDirectory().getAbsolutePath()); - File root = new File("/"); - if (root.canExecute() && root.canRead()) { - List storageList = StorageHelper.getStorageList(); - ArrayList paths = new ArrayList<>(); - ArrayList pathNames = new ArrayList<>(); + List storageList = StorageHelper.getStorageList(); + ArrayList paths = new ArrayList<>(); + ArrayList pathNames = new ArrayList<>(); - for (StorageHelper.StorageInfo storage : storageList) { - paths.add(storage.path); - StringBuilder res = new StringBuilder(); + for (StorageHelper.StorageInfo storage : storageList) { + paths.add(storage.path); + StringBuilder res = new StringBuilder(); - if (storageList.size() > 1) { - if (!storage.removable) { - res.append(context.getString(R.string.sftp_internal_storage)); - } else if (storage.number > 1) { - res.append(context.getString(R.string.sftp_sdcard_num, storage.number)); - } else { - res.append(context.getString(R.string.sftp_sdcard)); - } + if (storageList.size() > 1) { + if (!storage.removable) { + res.append(context.getString(R.string.sftp_internal_storage)); + } else if (storage.number > 1) { + res.append(context.getString(R.string.sftp_sdcard_num, storage.number)); } else { - res.append(context.getString(R.string.sftp_all_files)); + res.append(context.getString(R.string.sftp_sdcard)); } - String pathName = res.toString(); - if (storage.readonly) { - res.append(" "); - res.append(context.getString(R.string.sftp_readonly)); - } - pathNames.add(res.toString()); + } else { + res.append(context.getString(R.string.sftp_all_files)); + } + String pathName = res.toString(); + if (storage.readonly) { + res.append(" "); + res.append(context.getString(R.string.sftp_readonly)); + } + pathNames.add(res.toString()); - //Shortcut for users that only want to browse camera pictures - String dcim = storage.path + "/DCIM/Camera"; - if (new File(dcim).exists()) { - paths.add(dcim); - if (storageList.size() > 1) { - pathNames.add(context.getString(R.string.sftp_camera) + "(" + pathName + ")"); - } else { - pathNames.add(context.getString(R.string.sftp_camera)); - } + //Shortcut for users that only want to browse camera pictures + String dcim = storage.path + "/DCIM/Camera"; + if (new File(dcim).exists()) { + paths.add(dcim); + if (storageList.size() > 1) { + pathNames.add(context.getString(R.string.sftp_camera) + "(" + pathName + ")"); + } else { + pathNames.add(context.getString(R.string.sftp_camera)); } } + } + + if (paths.size() > 0) { + np2.set("multiPaths", paths); + np2.set("pathNames", pathNames); - if (paths.size() > 0) { - np2.set("multiPaths", paths); - np2.set("pathNames", pathNames); - } } device.sendPackage(np2); @@ -129,6 +138,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}; diff --git a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java index 62195aa6..8be61db0 100644 --- a/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java +++ b/src/org/kde/kdeconnect/Plugins/SharePlugin/SharePlugin.java @@ -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) @@ -192,20 +208,27 @@ public class SharePlugin extends Plugin { .setAutoCancel(true) .setProgress(100,100,false) .setOngoing(false); - 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); + + // 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) { @@ -409,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; + } } diff --git a/src/org/kde/kdeconnect/Plugins/TelepathyPlugin/TelepathyPlugin.java b/src/org/kde/kdeconnect/Plugins/TelepathyPlugin/TelepathyPlugin.java index 3ebf282f..a3610e1b 100644 --- a/src/org/kde/kdeconnect/Plugins/TelepathyPlugin/TelepathyPlugin.java +++ b/src/org/kde/kdeconnect/Plugins/TelepathyPlugin/TelepathyPlugin.java @@ -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; @@ -43,11 +47,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() { } @@ -63,8 +62,18 @@ public class TelepathyPlugin extends Plugin { String phoneNo = np.getString("phoneNumber"); String sms = np.getString("messageBody"); try { - SmsManager smsManager = SmsManager.getDefault(); - smsManager.sendTextMessage(phoneNo, null, sms, null, null); + + int permissionCheck = ContextCompat.checkSelfPermission(context, + Manifest.permission.SEND_SMS); + + if(permissionCheck == PackageManager.PERMISSION_GRANTED) { + SmsManager smsManager = SmsManager.getDefault(); + smsManager.sendTextMessage(phoneNo, null, sms, null, null); + Log.d("TelepathyPlugin", "SMS sent"); + } else if(permissionCheck == PackageManager.PERMISSION_DENIED){ + // TODO Request Permission SEND_SMS + } + //TODO: Notify other end } catch (Exception e) { //TODO: Notify other end @@ -176,4 +185,8 @@ public class TelepathyPlugin extends Plugin { return new String[]{}; } + @Override + public String[] getRequiredPermissions() { + return new String[]{Manifest.permission.SEND_SMS/*, Manifest.permission.READ_CONTACTS*/}; + } } diff --git a/src/org/kde/kdeconnect/Plugins/TelephonyPlugin/TelephonyPlugin.java b/src/org/kde/kdeconnect/Plugins/TelephonyPlugin/TelephonyPlugin.java index 40cbd0b1..fcc04ee8 100644 --- a/src/org/kde/kdeconnect/Plugins/TelephonyPlugin/TelephonyPlugin.java +++ b/src/org/kde/kdeconnect/Plugins/TelephonyPlugin/TelephonyPlugin.java @@ -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; @@ -102,32 +105,40 @@ public class TelephonyPlugin extends Plugin { //Log.e("TelephonyPlugin", "callBroadcastReceived"); - Map 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 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) { @@ -208,18 +219,26 @@ public class TelephonyPlugin extends Plugin { } String phoneNumber = message.getOriginatingAddress(); - Map contactInfo = ContactsHelper.phoneNumberLookup(context, phoneNumber); + + int permissionCheck = ContextCompat.checkSelfPermission(context, + Manifest.permission.READ_CONTACTS); + + if(permissionCheck==PackageManager.PERMISSION_GRANTED) { + Map 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); } @@ -267,4 +286,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}; + } + } diff --git a/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java b/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java index 820e8deb..b8332ba0 100644 --- a/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java +++ b/src/org/kde/kdeconnect/UserInterface/DeviceFragment.java @@ -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 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 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); diff --git a/src/org/kde/kdeconnect/UserInterface/MaterialActivity.java b/src/org/kde/kdeconnect/UserInterface/MaterialActivity.java index 4eeed193..d8201032 100644 --- a/src/org/kde/kdeconnect/UserInterface/MaterialActivity.java +++ b/src/org/kde/kdeconnect/UserInterface/MaterialActivity.java @@ -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); From d0482f1e813059d8f069400d388935289f91dbe6 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Fri, 2 Jun 2017 02:59:51 +0200 Subject: [PATCH 33/40] GIT_SILENT made messages (after extraction) --- res/values-ca/strings.xml | 3 +++ res/values-nl/strings.xml | 3 +++ res/values-pt/strings.xml | 3 +++ res/values-sv/strings.xml | 3 +++ res/values-uk/strings.xml | 3 +++ 5 files changed, 15 insertions(+) diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 1d1a7d89..227c7483 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -176,4 +176,7 @@ L\'he trobat Obre Tanca + Us caldrà concedir permís per accedir a l\'emmagatzematge + Alguns connectors necessiten permisos per a funcionar (puntegeu per a més informació): + Aquest connector necessita permisos per a funcionar diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index 10c13a71..ffa924a5 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -176,4 +176,7 @@ Gevonden Openen Sluiten + U moet toestemming geven voor toegang tot de opslag + Sommige plug-ins hebben toestemming nodig om te werken (tik voor meer informatie): + Deze plug-in heeft toestemming nodig om te werken diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 193d21a1..83e84b29 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -176,4 +176,7 @@ Encontrado Abrir Fechar + Precisa de dar permissões de acesso ao armazenamento + Alguns \'plugins\' precisam de permissões para funcionar (toque para mais informações): + Este \'plugin\' precisa de permissões para funcionar diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index 3b1b7035..cec6efbe 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -176,4 +176,7 @@ Hittade den Öppna Stäng + Du måste ge rättighet att komma åt lagringen + Vissa insticksprogram kräver rättigheter för att fungera (rör för mer information): + Insticksprogrammet behöver rättigheter för att fungera diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 70e55b1e..8149411f 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -176,4 +176,7 @@ Знайдено Відкрити Закрити + Для доступу до сховища даних вам слід надати програмі права доступу + Для роботи деяких додатків потрібні додаткові права доступу (натисніть, щоб дізнатися більше): + Для роботи цього додатка потрібні додаткові права доступу From f223fe0812fe001cfd4213b34e2b9cabb3ba1da2 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Sun, 4 Jun 2017 02:56:42 +0200 Subject: [PATCH 34/40] GIT_SILENT made messages (after extraction) --- res/values-fr/strings.xml | 80 ++++++++++++++++++++++++++++++++------- res/values-pl/strings.xml | 3 ++ 2 files changed, 69 insertions(+), 14 deletions(-) diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index f392306e..928b0379 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -1,18 +1,27 @@ - Notifications du téléphonie + Notifications de téléphonie Envoie des notifications pour les SMS et les appels Rapport sur la batterie Rapport périodique sur l\'état de la batterie Exposer le système de fichiers + Permettre de parcourir le système de fichiers du périphérique à distance Synchronisation avec le presse-papiers Partage le contenu du presse-papiers Contrôle distant + Utilisez votre téléphone ou tablette comme un pavé tactile et un clavier + Recevoir les appuis de touches distants + Recevoir les appuis de touches des périphériques distants Contrôles multimédia + Fournit une télécommande pour votre lecteur multimédia + Exécuter une commande + Exécuter des commandes à distance sur votre téléphone ou tablette Commande « Ping » Envoie et reçoit des commandes « Ping » Synchronisation des notifications Accédez à vos notifications depuis d\'autres périphériques + Recevoir les notifications + Recevoir les notifications du périphérique et les afficher dans Android Partager et recevoir Partagez des URLs et des fichiers entre périphériques Cette fonctionnalité n\'est pas disponible dans votre version de Android @@ -23,10 +32,16 @@ Vous devez accorder la permission d\'accéder aux notifications Envoyer un « Ping » Contrôles multimédia + Gérer les appuis de touches à distance uniquement lors de l\'édition + Aucune connexion active d\'un clavier sans fil disponible, établissez-en une dans KDE Connect + La connexion au clavier sans fil est active + Plusieurs claviers sans fil sont disponibles, sélectionnez le périphérique à configurer Contrôle distant Déplacer le doigt sur l\'écran pour bouger le pointeur de la souris. Appuyez pour cliquer et utiliser deux/trois doigts pour les clic droit et centre. Appuyez longtemps pour faire un glisser déplacer. Action pour l\'appui à deux doigts Action pour l\'appui à trois doigts + Définir la sensibilité du pavé tactile + Inverser la direction du défilement Clic droit Clic central @@ -34,54 +49,63 @@ Droite Milieu + par défaut - Slowest - Above Slowest - Default - Above Default - Fastest + Le plus lent + Assez lent + Par défaut + Assez rapide + Le plus rapide Périphériques connectés Périphériques disponibles Périphériques mémorisés Le chargement des modules externes a échoué (cliquez pour plus d\'informations) : Paramètres du module externe - Désapparier + Dissocier Périphérique inaccessible + Associer un nouveau périphérique Périphérique inconnu Périphérique inaccessible - L\'appariement a déjà été demandé - Périphérique déjà apparié + L\'association a déjà été demandée + Périphérique déjà associé Il est impossible d\'envoyer un paquet Délai expiré Annulé par l\'utilisateur Annulé par un autre homologue Clé reçue non valable + Informations de chiffrement + Ce périphérique n\'utilise pas une version récente de KDE Connect et utilise l\'ancienne méthode de chiffrement. + L\'empreinte SHA1 du certificat de votre appareil est : + L\'empreinte SHA1 du certificat du périphérique distant est : Paire demandée - Demande d\'appariement provenant de %1s + Demande d\'association provenant de %1s Lien reçu de %1s Appuyez pour ouvrir %1s Réception d\'un fichier en cours depuis %1s %1s Envoi d\'un fichier à %1s + Envoi de fichiers à %1s %1s + Envoi de %1$d sur %2$d fichiers Fichier reçu de %1s Impossible de recevoir le fichier depuis : %1s Appuyez pour ouvrir %1s Fichier envoyé à %1s %1s + Impossible d\'envoyer le fichier à %1s %1s Cliquer pour répondre Reconnecter Envoyer un clic droit Envoyer un clic central Afficher le clavier - Périphérique non apparié - Demande d\'appariement + Périphérique non associé + Demande d\'association Accepter Rejeter Périphérique - Apparier un périphérique + Associer un périphérique Contrôle distant Paramètres de connexion de KDE Lire @@ -111,9 +135,15 @@ Nom de périphérique non valable Texte reçu et enregistré dans le presse-papiers Liste personnalisée de périphériques + Associer un nouveau périphérique + Dissocier %s Ajouter des périphériques par IP Notifications sonores Vibrer et jouer un son quand un fichier est reçu + Personnaliser le dossier de destination + Les fichiers reçus apparaîtront dans le dossier de téléchargement + Les fichiers seront enregistrés dans le dossier ci-dessous + Dossier de destination Filtre des notifications Les notifications seront synchronisées pour les applications sélectionnées. Stockage interne @@ -123,8 +153,30 @@ (lecture seule) Images de l\'appareil photo Ajouter hôte/IP - Nom d\'hôte ou adresse IP  + "Nom d\'hôte ou adresse IP " Aucun lecteur trouvé N\'utilisez cette option que si votre périphérique n\'est pas détecté automatiquement. Saisissez l\'adresse IP ou le nom d\'hôte ci-dessous et appuyez sur le bouton pour l\'ajouter à la liste. Appuyez sur un élément existant pour le retirer de la liste. %1$s sur %2$s + Envoyer des fichiers + Périphériques KDE Connect + Les autres périphériques utilisant KDE Connect dans votre réseau apparaissent ici. + Périphérique associé + Renommer le périphérique + Renommer + Mettre à jour + Ce périphérique associé n\'est pas joignable. Assurez-vous qu\'il est bien connecté au même réseau. + Il semble que vous utilisiez une connexion de données mobile. KDE Connect fonctionne uniquement sur un réseau local. + Aucun navigateur de fichiers installé. + Envoyer un SMS + Envoyer des SMS depuis votre bureau + Ce module externe n\'est pas géré par le périphérique + Trouver mon téléphone + Trouver ma tablette + Fait sonner le périphérique pour vous aider à le retrouver + Trouvé + Ouvrir + Fermer + Vous devez accorder la permission d\'accéder à l\'espace de stockage + Certains modules externes nécessitent des permissions pour fonctionner (tapez pour plus d\'informations) : + Ce module externe nécessite des permissions pour fonctionner diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 5e6630c0..3b280af1 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -176,4 +176,7 @@ Znaleziony Otwórz Zamknij + Musisz nadać uprawnienia, aby uzyskać dostęp do pamięci masowej + Niektóre z wtyczek wymagają uprawnień do działania (stuknij po więcej informacji) + Ta wtyczka wymaga uprawnień do działania From 1d7594d83b40ea558306d97131063f9f1bb2aaa5 Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Mon, 5 Jun 2017 02:53:14 +0200 Subject: [PATCH 35/40] GIT_SILENT made messages (after extraction) --- res/values-es/strings.xml | 3 +++ res/values-fr/strings.xml | 2 +- res/values-sr/strings.xml | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 1bb61b3d..88e03dcc 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -176,4 +176,7 @@ Encontrado Abrir Cerrar + Debe otorgar permisos para acceder al almacenamiento + Algunos complementos necesitan permisos para funcionar (pulse para más información): + Este complemento necesita permisos para funcionar diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 928b0379..891b5959 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -61,7 +61,7 @@ Périphériques disponibles Périphériques mémorisés Le chargement des modules externes a échoué (cliquez pour plus d\'informations) : - Paramètres du module externe + Paramètres des modules externes Dissocier Périphérique inaccessible Associer un nouveau périphérique diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index e551a350..c05ba613 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -87,6 +87,7 @@ Шаљем фајл на %1s Шаљем фајлове на %1s %1s + Послато %1$d од %2$d фајлова Примљен фајл са %1s Неуспео пријем фајла са %1s Тапните да отворите „%1s“ @@ -175,4 +176,7 @@ Нађен Отвори Затвори + Морате дати дозволе за приступ унутрашњој меморији + Неки прикључци траже дозволе да би радили (тапните за више информација): + Овај прикључак тражи дозволе да би радио From 09570ec34c90a0e5158d3ac1b32feb081fc21bfb Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Thu, 8 Jun 2017 03:00:19 +0200 Subject: [PATCH 36/40] GIT_SILENT made messages (after extraction) --- res/values-fr/strings.xml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 891b5959..a1097e4d 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -35,7 +35,7 @@ Gérer les appuis de touches à distance uniquement lors de l\'édition Aucune connexion active d\'un clavier sans fil disponible, établissez-en une dans KDE Connect La connexion au clavier sans fil est active - Plusieurs claviers sans fil sont disponibles, sélectionnez le périphérique à configurer + Plusieurs connexions à des claviers sans fil sont disponibles, sélectionnez le périphérique à configurer Contrôle distant Déplacer le doigt sur l\'écran pour bouger le pointeur de la souris. Appuyez pour cliquer et utiliser deux/trois doigts pour les clic droit et centre. Appuyez longtemps pour faire un glisser déplacer. Action pour l\'appui à deux doigts @@ -61,7 +61,7 @@ Périphériques disponibles Périphériques mémorisés Le chargement des modules externes a échoué (cliquez pour plus d\'informations) : - Paramètres des modules externes + Paramètres du module externe Dissocier Périphérique inaccessible Associer un nouveau périphérique @@ -75,7 +75,7 @@ Annulé par un autre homologue Clé reçue non valable Informations de chiffrement - Ce périphérique n\'utilise pas une version récente de KDE Connect et utilise l\'ancienne méthode de chiffrement. + Ce périphérique n\'utilise pas une version récente de KDE Connect qui utilise l\'ancienne méthode de chiffrement. L\'empreinte SHA1 du certificat de votre appareil est : L\'empreinte SHA1 du certificat du périphérique distant est : Paire demandée @@ -176,7 +176,4 @@ Trouvé Ouvrir Fermer - Vous devez accorder la permission d\'accéder à l\'espace de stockage - Certains modules externes nécessitent des permissions pour fonctionner (tapez pour plus d\'informations) : - Ce module externe nécessite des permissions pour fonctionner From 5886422d72ee60722fe26e21107f63ba1f8797c1 Mon Sep 17 00:00:00 2001 From: Nicolas Fella Date: Mon, 5 Jun 2017 00:26:22 +0200 Subject: [PATCH 37/40] Fixed a bug in MousepadPlugin Summary: Some values in the mousepad plugin had no default values because some strings were translated but shouldn't. Reviewers: #kde_connect, albertvaka Reviewed By: #kde_connect, albertvaka Subscribers: #kde_connect Tags: #kde_connect Differential Revision: https://phabricator.kde.org/D6097 --- res/values/strings.xml | 6 ++--- res/xml/mousepadplugin_preferences.xml | 24 +++++++++---------- .../MousePadPlugin/MousePadActivity.java | 6 ++--- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 9d949646..8934a81d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -53,9 +53,9 @@ Middle click Nothing - right - middle - default + right + middle + default right middle diff --git a/res/xml/mousepadplugin_preferences.xml b/res/xml/mousepadplugin_preferences.xml index f5b8f5d6..dbafa886 100644 --- a/res/xml/mousepadplugin_preferences.xml +++ b/res/xml/mousepadplugin_preferences.xml @@ -5,30 +5,30 @@ + android:key="@string/mousepad_double_tap_key" + android:summary="%s" + android:title="@string/mousepad_double_tap_settings_title"/> + android:key="@string/mousepad_triple_tap_key" + android:summary="%s" + android:title="@string/mousepad_triple_tap_settings_title"/> + android:key="@string/mousepad_sensitivity_key" + android:summary="%s" + android:title="@string/mousepad_sensitivity_settings_title"/> Date: Sat, 10 Jun 2017 02:57:53 +0200 Subject: [PATCH 38/40] GIT_SILENT made messages (after extraction) --- res/values-bs/strings.xml | 2 -- res/values-ca/strings.xml | 3 --- res/values-cs/strings.xml | 3 --- res/values-da/strings.xml | 3 --- res/values-de/strings.xml | 3 --- res/values-el/strings.xml | 3 --- res/values-en-rGB/strings.xml | 3 --- res/values-es/strings.xml | 3 --- res/values-et/strings.xml | 3 --- res/values-fi/strings.xml | 3 --- res/values-fr/strings.xml | 3 --- res/values-gl/strings.xml | 3 --- res/values-he/strings.xml | 3 --- res/values-it/strings.xml | 3 --- res/values-ko/strings.xml | 3 --- res/values-nl/strings.xml | 3 --- res/values-pl/strings.xml | 3 --- res/values-pt-rBR/strings.xml | 3 --- res/values-pt/strings.xml | 3 --- res/values-ru/strings.xml | 3 --- res/values-sk/strings.xml | 3 --- res/values-sr/strings.xml | 3 --- res/values-sv/strings.xml | 3 --- res/values-uk/strings.xml | 3 --- res/values-zh-rCN/strings.xml | 3 --- res/values-zh-rTW/strings.xml | 3 --- 26 files changed, 77 deletions(-) diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index dad48dd2..ec035e67 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -27,8 +27,6 @@ Srednji klik Ništa - desno - Srednje Slowest Above Slowest diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index 227c7483..6312ea16 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -47,9 +47,6 @@ Clic del mig No fer res - dret - mig - Predeterminada La més lenta Lenta diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml index f5944c9b..f0c10f52 100644 --- a/res/values-cs/strings.xml +++ b/res/values-cs/strings.xml @@ -47,9 +47,6 @@ Kliknutí prostředním tlačítkem myši Nic - pravé - prostřední - výchozí Nejpomalejší Méně pomalý diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 8ab792c5..e49cef4b 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -47,9 +47,6 @@ Midterklik Intet - højre - midter - standard Mest langsom Over mest langsom diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index 05b9b7fa..b650ac64 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -41,9 +41,6 @@ Mittelklick Nichts - Rechts - Mitte - Standard Langsamste Langsam diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml index 0f4e75f5..086b790c 100644 --- a/res/values-el/strings.xml +++ b/res/values-el/strings.xml @@ -41,9 +41,6 @@ Μεσαίο κλικ Τίποτα - δεξί - μεσαίο - προκαθορισμένο Το πιο αργό Πάνω από το πιο αργό diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index de3f74d7..ccd6ff51 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -47,9 +47,6 @@ Middle click Nothing - right - middle - default Slowest Above Slowest diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 88e03dcc..987c62cd 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -47,9 +47,6 @@ Clic del botón central Nada - derecho - medio - por defecto Muy poco sensible Poco sensible diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index 18bd240d..849539a6 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -41,9 +41,6 @@ Keskklõps Ei tee midagi - parem - keskmine - vaikimisi Kõige aeglasem Kõige aeglasemast kiirem diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml index ac9b3e10..a70d95e3 100644 --- a/res/values-fi/strings.xml +++ b/res/values-fi/strings.xml @@ -41,9 +41,6 @@ Keskinapsautus Ei toimintoa - Oikea painike - Keskipainike - oletus Hitain Hitainta suurempi diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index a1097e4d..4cef83b3 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -47,9 +47,6 @@ Clic central Rien - Droite - Milieu - par défaut Le plus lent Assez lent diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 48b1c1c9..2fce829a 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -35,9 +35,6 @@ Clic central Nada - dereita - medio - predeterminado O máis lento Lento diff --git a/res/values-he/strings.xml b/res/values-he/strings.xml index e381949b..82726e88 100644 --- a/res/values-he/strings.xml +++ b/res/values-he/strings.xml @@ -47,9 +47,6 @@ לחיצה אצמעית (גלגלת) שום דבר - ימין - אמצע - ברירת מחדל הכי איטי יותר מההכי איטי diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml index c3298781..fbc2f613 100644 --- a/res/values-it/strings.xml +++ b/res/values-it/strings.xml @@ -47,9 +47,6 @@ Clic centrale Niente - destra - centro - predefinita Minima Più veloce diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml index 55b661aa..2a89b9ea 100644 --- a/res/values-ko/strings.xml +++ b/res/values-ko/strings.xml @@ -41,9 +41,6 @@ 가운데 단추 누름 아무것도 안 함 - 오른쪽 - 가운데 - 기본값 느리게 느리게 이상 diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index ffa924a5..61f1fce6 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -47,9 +47,6 @@ Middelste muisklik Niets - rechts - midden - standaard Langzaamst Langzaam diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 3b280af1..84682a04 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -47,9 +47,6 @@ Kliknięcie środkowym Nic - prawo - środek - domyślne Najmniejsza Ponad najmniejszą diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml index c688b029..816dc563 100644 --- a/res/values-pt-rBR/strings.xml +++ b/res/values-pt-rBR/strings.xml @@ -39,9 +39,6 @@ Botão do meio Nada - direita - meio - padrão Mais lento Ainda mais lento diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index 83e84b29..9c053dee 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -47,9 +47,6 @@ Botão do meio Nada - direita - meio - predefinição Mais Lento Ainda Mais Lento diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index fd7a5b89..06f4ea8f 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -47,9 +47,6 @@ Нажатие средней кнопки Ничего не делать - Нажатие правой кнопки - Нажатие средней кнопки - Обычная Самая низкая Низкая diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index a5d85f90..54222404 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -41,9 +41,6 @@ Stredný klik Nič - vpravo - stred - predvolené Najpomalšie Nad najpomalším diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index c05ba613..17b6d542 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -47,9 +47,6 @@ средњи клик ништа - десни - средњи - подразумевано најспорије мало спорије diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml index cec6efbe..8ceaee0b 100644 --- a/res/values-sv/strings.xml +++ b/res/values-sv/strings.xml @@ -47,9 +47,6 @@ Mittenklick Ingenting - höger - mitten - normal Långsammaste Ovanför långsammaste diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 8149411f..99648101 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -47,9 +47,6 @@ Клацання середньою Нічого - права - середня - типва Найповільніший Швидший за найповільніший diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index 7f5fc995..78bd446e 100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml @@ -47,9 +47,6 @@ 中键点击 - - - 默认 最慢 高于最慢 diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index abcc34a6..715ae130 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -41,9 +41,6 @@ 中鍵點擊 - - - 預設 最慢 From 510000541c98db1c892845ab5096b9754df5889d Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Sun, 11 Jun 2017 03:04:13 +0200 Subject: [PATCH 39/40] GIT_SILENT made messages (after extraction) --- res/values-gl/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index 2fce829a..28c97681 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -46,7 +46,7 @@ Dispositivos dispoñíbeis Dispositivos coñecidos Non foi posíbel cargar os seguintes complementos (toque para obter máis información): - Configuración do engadido + Configuración do complemento Desemparellarse O dispositivo emparellado está fóra do alcance. Emparellar cun novo dispositivo From 569ae488a024d063126491871ba0c266664a263c Mon Sep 17 00:00:00 2001 From: l10n daemon script Date: Tue, 20 Jun 2017 03:02:09 +0200 Subject: [PATCH 40/40] GIT_SILENT Add new file (after extraction) --- res/values-tr/strings.xml | 179 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 res/values-tr/strings.xml diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml new file mode 100644 index 00000000..ab4776d8 --- /dev/null +++ b/res/values-tr/strings.xml @@ -0,0 +1,179 @@ + + + Telefon bildiricisi + SMS ve çağrılar için bildirimler yolla + Batarya raporu + Batarya durumunu belirli aralıklarla raporla + Dosya sistemi gösterme + Bu aıygıtın dosya sistemine uzaktan gözatılmasına izin verir + Pano eşitleme + Pano içeriğini paylaş + Uzak girdi + Telefonunuzu veya tabletinizi, dokunmatik veya klavye olarak kullanın + Uzak tuşa basmaları getir + Tuş basma eylemlerini, uzak aygıtlardan getir + Çoklu ortam denetimleri + Ortam oynatıcınız için uzak denetim sağlar + Komut Çalıştır + Uzak komutları, telefon veya tabletinizden tetikler + Ping + Ping gönder ve al + Bildirim eşitleme + Bildirimlerinize, diğer aygıtlardan erişin + Bildirimleri al + Bildirimleri diğer aygıtlardan al ve Android üzerinde göster + Paylaş ve al + Dosyaları ve URL\'leri aygıtlar arasında paylaş + Bu özellik, sahip olduğunuz Android sürümünde kullanılabilir değil + Aygıt yok + Tamam + İptal + Ayarları aç + Bildirimler erişebilmek için izine ihtiyacınız var + Ping gönder + Çoklu ortam denetimi + Uzak tuşları, sadece düzenleme yaparken işle + Etkin bir uzak klavye bağlantısı yok, kdeconnect ile bir bağlantı kurun + Uzak klavye bağlantısı etkin + Birden çok uzak klavye bağlantısı mevcut, yapılandırmak istediğiniz aygıtı seçin + Girdi sil + 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. + İki parmak dokunma eylemini ayarla + Üç parmak dokunma eylemini ayarla + Dokunmatik yüzey hassasiyetini ayarla + Ters Kaydırma Yönü + + Sağ tık + Orta tık + Hiçbiri + + + En Yavaş + En Yavaşın Üstü + Varsayıla + Varsayılan Üstü + En Hızlı + + Bağlı aygıtlar + Kullanılabilir aygıtlar + Hatırlanan aygıtlar + Eklentiler yüklenemedi (daha fazla bilgi için dokunun): + Eklenti ayarları + Ayır + Eşleşmiş aygıt ulaşılabilir değil + Yeni bir aygıt eşleştir + Bİlinmeyen aygıt + Aygıt ulaşılabilir değil + Eşleşme zaten talep edilmiş + Aygıt zaten eşleşmiş + Paket gönderilemedi + Zaman aşımı + Kullanıcı tarafından iptal edildi + Diğer eş tarafından iptal edildi + Geçersiz anahtar alındı + Şifreleme Bilgisi + Diğer aygıt, KDE Connect\'in son sürümünü kullanmıyor, eski şifreleme yöntemini kullanıyor. + Aygıt sertifikanızın SHA1 parmak izi: + Uzak aygıt sertifikanızın SHA1 parmak izi: + Eşleşme talep edildi + %1s için eşleşme talebi + %1s üzerinden bağlantı alındı + \'%1s\' açmak için dokunun + %1s üzerinden gelen dosya + %1s + Dosya şuraya gönderiliyor, %1s + Dosyalar şuraya gönderiliyor, %1s + %1s + %2$d dosyadan %1$d dosya gönderildi + Şuradan dosya alındı, %1s + Şuradan dosya alma başarısız, %1s + \'%1s\' açmak için dokunun + Dosyayı şuraya gönder, %1s + %1s + Dosyayı şuraya gönderme başarısız, %1s + %1s + Cevap için dokunun + Yeniden Bağlan + Sağ Tık Gönder + Orta Tık Gönder + Klavyeyi Göster + Aygıt eşleşmemiş + Eşleşme isteği + Onayla + Reddet + Aygıt + Aygıt eşleştir + Uzak denetim + KDE Connect Ayarları + Oynat + Önceki + Geri Sar + Hızlı İleri Sar + Sonraki + Ses + Çoklu Ortam Ayarları + İleri/geri düğmeleri + Basıldığında kullanılacak ileri/geri zamanını ayarlayın. + + 10 saniye + 20 saniye + 30 saniye + 1 dakika + 2 dakika + + Paylaş... + Bu aygıt, eski bir protokol sürümü kullanıyor + Bu aygıt, daha yeni bir protokol sürümü kullanıyor + Genel Ayarlar + Ayarlar + %s ayarları + Aygıt adı + %s + Geçersiz aygıt adı + Gelen ileti, panoya kaydet + Özel aygıt listesi + Yeni bir aygıt eşleştir + Ayır %s + IP\'ye göre aygıtları ekle + Sesli bildirimler + Bir dosya alırken, ses çıkar ve titret + Hedef dizini özelleştir + Gelen dosyalar İndirilenler\'de gözükecektir + Dosyalar aşağıdaki dizinden depolanacaktır + Hedef dizin + Bildirim süzgeci + Bildirimler, seçili uygulamalar için eşitlenecektir. + Harici depolama + Tüm dosyalar + SD kart %d + SD kart + (salt okunur) + Kamera resimleri + Makine/IP ekle + Makine adı veya IP + Onatıcı bulunamadı + 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. + %2$s üzerindeki %1$s + Dosyaları gönder + KDE Connect Aygıtları + KDE Connect\'te çalışan, aynı ağdaki diğer aygıtlar burada gözükmelidir. + Aygıt eşleştirildi + Aygıtı yeniden adlandır + Yeniden adlandır + Tazele + Eşleştirilmiş aygıt ulaşılabilir değil. Aynı ağa bağlı olduğundan emin olun. + Mobil veri bağlantısında olduğunuz gözüküyor. KDE Connect sadece yerel ağlarda çalışır. + Yüklü bir dosya tarayıcısı yok. + SMS Gönder + Masaüstünden metin iletisi gönder + Eklenti, aygıt tarafından desteklenmiyor + Telefonumu bul + Tabletimi bul + Aygıtı bulmak için onu çaldır + Bulundu + + Kapat + Depolamaya erişim için izne ihtiyacınız var + Bazı Eklentiler çalışmak için izne ihtiyaç duyar (daha fazla bilgi için dokunun): + Bu eklenti, çalışmak için izne ihtiyaç duyuyor +