diff --git a/.travis.yml b/.travis.yml
index d205021d0d..50b73d1b98 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,15 +1,20 @@
-language: java
+language: android
+android:
+ components:
+ - build-tools-20.0.0
+ - android-19
+ - android-17
+ - android-14
+ - extra-android-support
+ licenses:
+ - 'android-sdk-license-5be876d5'
+ - 'android-sdk-license-598b93a6'
+
jdk: oraclejdk7
+
before_install:
- # Install base Android SDK
- - sudo apt-get update -qq
- - sudo apt-get install -qq libstdc++6:i386 lib32z1 expect
- - export COMPONENTS="build-tools-20.0.0,android-14,android-17,android-19,sysimg-19,extra-android-support"
- - export LICENSES="android-sdk-license-5be876d5|android-sdk-license-598b93a6"
- - curl -3L https://raw.github.com/embarkmobile/android-sdk-installer/version-2/android-sdk-installer | bash /dev/stdin --install=$COMPONENTS --accept=$LICENSES
- - source ~/.android-sdk-installer/env
- - rm pom.xml
- - ./setup_env.sh
+ - rm pom.xml
+ - ./setup_env.sh
script:
- ant clean
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2671cce211..910ea787f7 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -18,8 +18,8 @@
along with this program. If not, see .
-->
+ android:versionCode="10600000"
+ android:versionName="1.6.0" xmlns:android="http://schemas.android.com/apk/res/android">
diff --git a/SETUP.md b/SETUP.md
index a965064413..39539038e9 100644
--- a/SETUP.md
+++ b/SETUP.md
@@ -1,10 +1,14 @@
-If you want to start help developing ownCloud please follow the [contribution guidelines][0] and observe these instructions:
-
-### 1. Fork and download android/develop repository:
+If you want to start help developing ownCloud please follow the [contribution guidelines][0] and observe these instructions.
-NOTE: You must have git in your environment path variable to perform the next operations.
+If you have any problems, start again with 1) and work your way down. If something still does not work as described here, please open a new issue describing exactly what you did, what happened, and what should have happened.
+### 1) Fork and download android/develop repository:
+
+NOTE: Android SDK with platforms 8, 14 and 19 (and maybe others) need to be installed.
+ You must have the Android SDK 'tools/', and 'platforms-tools/' folders in your environment path variable.
+ "git" need to be installed and in your environment path variable.
+
* Navigate to https://github.com/owncloud/android, click fork.
* Clone your new repo: "git clone git@github.com:YOURGITHUBNAME/android.git"
* Move to the project folder with "cd android"
@@ -14,16 +18,16 @@ NOTE: You must have git in your environment path variable to perform the next op
* Make sure to get the latest changes from official android/develop branch: "git pull upstream develop"
* Complete the setup of project properties and resolve pending dependencies running "setup_env.bat" or "./setup_env.sh" .
-At this point you can continue using different tools to build the project. Section 2, 3 and 4 describe some of the existing alternatives.
+At this point you can continue using different tools to build the project. Sections 2a), 2b), and 2c) describe some of the existing alternatives.
-### 2. Building with Ant:
+### 2a) Building with Ant:
NOTE: You must have the Android SDK 'tools/', and 'platforms-tools/' folders in your environment path variable.
* Run "ant clean" .
* Run "ant debug" to generate a debuggable version of the ownCloud app.
-### 3. Building with console/maven:
+### 2b) Building with console/maven:
NOTE: You must have mvn (version >= 3.1.1) in your environment path. Current Android 'platforms-tools' need to be installed.
@@ -39,7 +43,7 @@ Download/install Android plugin for Maven, install owncloud-android-library, the
Now you can create ownCloud APK using "mvn package"
-### 4. Building with Eclipse:
+### 2c) Building with Eclipse:
NOTE: You must have the Android SDK 'tools/', and 'platforms-tools/' folders in your environment path variable.
@@ -47,11 +51,12 @@ NOTE: You must have the Android SDK 'tools/', and 'platforms-tools/' folders in
* Open Eclipse and create new "Android Project from Existing Code". Choose android/actionbarsherlock/library as root.
* Clean project and compile.
* If any error appear, check the project properties; in the 'Android' section, API Level should be greater or equal than 14.
+* If "error loading libz.so.1" appears, try "sudo apt-get install lib32z1"
* Make sure android/actionbarsherlock/library/bin/library.jar was created.
-* Create a new "Android Project from Existing Code". Choose android/owncloud-android-library as root.
+* Create a new "Android Project from Existing Code". Choose android/owncloud-android-library as root. (test and sample clients are not required.)
* Clean project and compile.
* If any error appear, check the project properties; in the 'Android' section, API Level should be 19 or greater.
-* Make sure android/owncloud-android-library/bin/classes.jar was created.
+* Make sure 'android/owncloud-android-library/bin/owncloud android library.jar' was created.
* Import ownCloud Android project.
* Clean project and compile.
* If any error appears, check the project properties of owncloud-android project; in the 'Android' section:
@@ -61,7 +66,7 @@ NOTE: You must have the Android SDK 'tools/', and 'platforms-tools/' folders in
NOTE: Even though API level is set to 19, APK also runs on older devices because in AndroidManifest.xml minSdkVersion is set to 8.
-### 5. Create pull request:
+### 3) Create pull request:
NOTE: You must sign the [Contributor Agreement][1] before your changes can be accepted!
@@ -72,7 +77,7 @@ NOTE: You must sign the [Contributor Agreement][1] before your changes can be ac
* Again, click "Edit" and set "compare:develop"
* Enter description and send pull request.
-### 6. Create another pull request:
+### 4) Create another pull request:
To make sure your new pull request does not contain commits which are already contained in previous PRs, create a new branch which is a clone of upstream/develop.
diff --git a/oc_jb_workaround/AndroidManifest.xml b/oc_jb_workaround/AndroidManifest.xml
index 9fa39b308d..b8b89c1ef1 100644
--- a/oc_jb_workaround/AndroidManifest.xml
+++ b/oc_jb_workaround/AndroidManifest.xml
@@ -1,8 +1,8 @@
+ android:versionCode="0100018"
+ android:versionName="1.0.18" >
.
-->
- حسابات
كلمة مرور خاطئةاختيار
+ الأمان
diff --git a/res/values-bg-rBG/strings.xml b/res/values-bg-rBG/strings.xml
index a00871f2a2..47d243cf46 100644
--- a/res/values-bg-rBG/strings.xml
+++ b/res/values-bg-rBG/strings.xml
@@ -263,7 +263,6 @@
Файлът вече не се намира на този сървърПрофилиДобавяне на профил
- Сигурна връзка е пренасочена по несигурен път.ДокладиИзпрати ИсторияownCloud Android доклади
@@ -278,4 +277,5 @@
Файлът вече съществува в отдалечената папка.Настъпи грешка при опита за преместване на този файл или папка.за да преместиш този файл
+ Сигурност
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index 74739f5dae..cae19b70e6 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -259,10 +259,10 @@
সার্ভারে এই ফাইলটি আর প্রাপ্তব্য নয়একাউন্টএকাউন্ট যোগ কর
- নিরাপদ সংযোগকে একটি অনিরাপদ পথে দিকবদল করা হয়েছেভুল কুটশব্দসরাওএখানে কিছু নেই। একটি ফোল্ডার যোগ করতে পারেন!বেছে নিনসরাতে ব্যার্থ হলো। ফাইলটি রয়েছে কিনা দেখুন।
+ নিরাপত্তা
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 9c1d158ef5..d0b98a1d33 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -257,8 +257,8 @@
El fitxer ja no està disponible en el servidorComptesAfegeix compte
- La connexió segura està essent redirigida a través d\'una ruta inseguraEs requereix autenticacióContrasenya incorrectaEscull
+ Seguretat
diff --git a/res/values-cs-rCZ/strings.xml b/res/values-cs-rCZ/strings.xml
index 71b84c9ee4..6b8b96c6f1 100644
--- a/res/values-cs-rCZ/strings.xml
+++ b/res/values-cs-rCZ/strings.xml
@@ -15,9 +15,9 @@
VíceÚčtySpravovat účty
- PIN aplikace
+ PIN do aplikaceChraňte svého klienta
- Okamžité nahrání obrázků
+ Okamžité nahrávání obrázkůOkamžitě nahrávat vytvořené fotografieOkamžité nahrávání videaOkamžitě odesílat nahrané video
@@ -27,7 +27,7 @@
Zobrazuje zaznamenané logySmazat historiiNápověda
- Doporučit příteli
+ Doporučit přátelůmOdezvaImprintZkuste %1$s na vašem smartphonu!
@@ -226,7 +226,7 @@
389 KB2012/05/18 12:23 PM12:23:45
- Odesílat obrázky pouze skrze WiFi
+ Odesílat obrázky pouze přes WiFiNahrávat videa pouze přes WiFi/InstantUploadKonflikt při aktualizaci
@@ -237,6 +237,7 @@
Náhled obrázkuObrázek nelze zobrazit%1$s nelze zkopírovat do místního adresáře %2$s
+ Cesta pro nahráníJe nám líto, ale sdílení není na vašem serveru povoleno. Kontaktujte svého
administrátora.Nelze sdílet. Zkontrolujte prosím že soubor existuje
@@ -262,7 +263,7 @@ administrátora.
Tento soubor již není dostupný na serveruÚčtyPřidat účet
- Zabezpečené spojení je přesměrováváno nezabezpečenou trasou.
+ Bezpečné spojení je přesměrováno na nezabezpečenou trasu.LogyOdeslat historiiLogy aplikace ownCloud pro Android
@@ -277,4 +278,6 @@ administrátora.
Soubor již v cílovém adresáři existujePři pokusu o přesun tohoto souboru či složky nastala chybapro přesun tohoto souboru
+ Okamžitá odesílání
+ Zabezpečení
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 15475299a3..771b3ce193 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -261,7 +261,6 @@
Filen er ikke længere tilgængelig på serverenKontiTilføj konto
- Sikker forbindelse videredirigeres gennem en usikker rute.LoggeSend historikApp-logregistreringer for ownCloud Android
@@ -276,4 +275,5 @@
Filen findes allerede i destinationsmappenDer opstod en fejl under forsøg på at flytte denne mappe eller filtil at flytte denne fil
+ Sikkerhed
diff --git a/res/values-de-rCH/strings.xml b/res/values-de-rCH/strings.xml
index a6cb3c2710..7a5b9e9148 100644
--- a/res/values-de-rCH/strings.xml
+++ b/res/values-de-rCH/strings.xml
@@ -198,4 +198,5 @@
KontenAuswählen
+ Sicherheit
diff --git a/res/values-de-rDE/strings.xml b/res/values-de-rDE/strings.xml
index b11328715b..70bd98fa03 100644
--- a/res/values-de-rDE/strings.xml
+++ b/res/values-de-rDE/strings.xml
@@ -238,6 +238,7 @@
BildvorschauDieses Bild kann nicht angezeigt werden%1$s konnte nicht in den lokalen %2$s Ordner kopiert werden
+ Pfad hochladenEntschuldigung, Freigaben sind auf Ihrem Server nicht aktiviert. Bitte kontaktieren Sie Ihren
⇥⇥Administrator.Teilen nicht möglich. Prüfen Sie, dass die Datei existiert
@@ -278,4 +279,6 @@
Die Datei ist bereits im Zielordner vorhandenEs ist ein Fehler beim Verschieben dieser Datei oder dieses Ordners aufgetreten.um diese Datei zu verschieben
+ Sofortiges Hochladen
+ Sicherheit
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index c859bb6e96..028b6bc6a0 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -238,6 +238,7 @@
BildvorschauDieses Bild kann nicht angezeigt werden%1$s konnte nicht in den lokalen %2$s Ordner kopiert werden
+ Pfad hochladenEntschuldigung, Freigaben sind auf Deinem Server nicht aktiviert. Bitte kontaktiere Deinen
⇥⇥Administrator.Teilen nicht möglich. Prüfe, dass die Datei existiert
@@ -263,7 +264,7 @@
Diese Datei steht auf dem Server nicht mehr zur VerfügungKontenKonto hinzufügen
- Die gesicherte Verbindung wird durch eine ungesicherte Route geleitet.
+ Die gesicherte Verbindung wird auf eine unsichere Route weitergeleitet.ProtokolleVerlauf sendenProtokolle der ownCloud-Android-App
@@ -278,4 +279,6 @@
Die Datei ist bereits im Zielordner vorhandenEs ist ein Fehler beim Verschieben der Datei oder des Ordners aufgetreten.um diese Datei zu verschieben
+ Sofortiges Hochladen
+ Sicherheit
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 8cbfca9a94..2fb159a6f0 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -260,7 +260,6 @@
Αυτό το αρχείο δεν είναι πια διαθέσιμο στο διακομιστήΛογαριασμοίΠροσθήκη λογαριασμού
- Ασφαλής σύνδεση ανακατευθύνεται μέσω μιας μη ασφαλούς διαδρομής.Αρχεία καταγραφώνΑποστολή ιστορικούΦόρτωση δεδομένων....
@@ -270,4 +269,5 @@
ΕπιλέξτεΤο αρχείο υπάρχει ήδη στο φάκελο προορισμούγια μετακίνηση αυτού του αρχείου
+ Ασφάλεια
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index fd812c6484..320d1e6700 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -238,6 +238,7 @@
Image previewThis image cannot be shown%1$s could not be copied to %2$s local folder
+ Upload PathSorry, sharing is not enabled on your server. Please contact your
administrator.Unable to share. Please check whether the file exists
@@ -263,7 +264,7 @@
The file is no longer available on the serverAccountsAdd account
- Secure connection is redirected through an unsecured route.
+ Secure connection is redirected to an unsecured route.LogsSend HistoryownCloud Android app logs
@@ -278,4 +279,6 @@
The file exists already in the destination folderAn error occurred whilst trying to move this file or folderto move this file
+ Instant Uploads
+ Security
diff --git a/res/values-eo/strings.xml b/res/values-eo/strings.xml
index 065e59aba4..2b4413ced2 100644
--- a/res/values-eo/strings.xml
+++ b/res/values-eo/strings.xml
@@ -186,4 +186,5 @@
Aŭtentiĝo neprasMalĝusta pasvortoElekti
+ Sekuro
diff --git a/res/values-es-rAR/strings.xml b/res/values-es-rAR/strings.xml
index 09fdb53b76..780a604341 100644
--- a/res/values-es-rAR/strings.xml
+++ b/res/values-es-rAR/strings.xml
@@ -241,4 +241,5 @@
Autentificación requeridaClave incorrectaElegir
+ Seguridad
diff --git a/res/values-es-rMX/strings.xml b/res/values-es-rMX/strings.xml
index 3772ff7a0c..ef91bc63fa 100644
--- a/res/values-es-rMX/strings.xml
+++ b/res/values-es-rMX/strings.xml
@@ -215,4 +215,5 @@
CuentasContraseña incorrectaSeleccionar
+ Seguridad
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 02508b6a65..7f661730df 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -101,7 +101,7 @@
Se encontraron conflictosFalló la sincronización de contenidos de %1$d ficherosFallos en la sincronización de contenidos
- Los contenidos de %1$d ficheros no se han sincronizado (%2$d conflictos)
+ Los contenidos de %1$d archivos no pudieron sincronizarse (%2$d conflictos)Algunos archivos locales se han perdido%1$d archivos en la carpeta %2$s no pudieron ser copiados aA partir de la versión 1.3.16, los ficheros subidos desde este dispositivo se copian en la carpeta local %1$s para evitar la pérdida de datos cuando se sincroniza un único archivo con varias cuentas.\n\nDebido a este cambio, todos los ficheros subidos con versiones anteriores de esta aplicación fueron copiados a la carpeta %2$s. Sin embargo, un error impidió que se completara esta operación durante la sincronización de la cuenta. Puede dejar los archivos tal y como están y eliminar el enlace a %3$s o mover los archivos a la carpeta %1$s y mantener el enlace a %4$s.\n\nDebajo se muestran los archivos locales y los archivos remotos en %5$s a los que fueron enlazados.
@@ -150,12 +150,12 @@
Ya existe una cuenta en este dispositivo con los mismos datos de Usuario y ServidorEl usuario introducido no concuerda con el usuario de esta cuentaOcurrió un error desconocido
- No se pudo encontrar la dirección
+ Error: no se pudo encontrar el hostInstancia de servidor no encontradaEl servidor ha tardado demasiado en responderURL no válidaFalló la inicialización SSL
- No fue posible verificar la identidad del servidor SLL
+ No fue posible verificar la identidad del servidor SSLNo se reconoce la versión del servidor No se ha podido establecer la conexiónConexión segura establecida
@@ -200,7 +200,7 @@
La identidad del sitio no puede ser verificada- El certificado del servidor no es de confianza- El certificado del servidor expiró
- - El certificado del servidor es demasiado reciente
+ - El certificado del servidor es de una fecha que aún no llega- La URL no coincide con el nombre de dominio del certificado¿Confías de todas formas en este certificado?El certificado no pudo ser guardado
@@ -237,7 +237,8 @@
No subirPrevisualización de imagenNo se puede mostrar la imagen
- %1$s no pudo ser copiado a la carpeta local %2$s
+ %1$s se pudo copiar a la carpeta local %2$s
+ Ruta de subidaLa función Compartir no está activada en su servidor. Contacte a su
administrador.No se puede compartir. Revise si el archivo existe
@@ -257,14 +258,14 @@
para renombrar este archivopara eliminar este archivopara compartir este archivo
- para ya no compartir este archivo
+ para dejar de compartir este archivopara crear el archivopara subir archivos a esta carpetaEste archivo ya no se encuentra en el servidorCuentasAgregar cuenta
- La conexión segura está siendo redirigida por una ruta insegura.
- Trazas
+ La conexión segura está siendo desviada por una ruta insegura.
+ LogsEnviar historialLogs de las apps ownCloud AndroidCargando datos...
@@ -274,8 +275,10 @@
Aquí no hay nada. ¡Puede agregar una carpeta!SeleccionarNo se puede mover. Revise si el archivo existe
- No se puede mover una carpeta dentro de una de sus descendientes.
+ No se puede mover una carpeta dentro de una de SUS subcarpetas.El archivo ya existe en la carpeta de destinoHubo un error al tratar de mover este archivo o carpetapara mover este archivo
+ Subidas instantáneas
+ Seguridad
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index 6604a71350..daba47f4a4 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -31,6 +31,7 @@
TagasisideImpressumProovi oma nutitelefonil rakendust %1$s!
+ Kutsun sind kasutama oma nutitelefonis rakendust %1$s!\nLaadi see alla siit: %2$sKontrolli serveritServeri aadress https://...Kasutajanimi
@@ -241,6 +242,7 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi
Pildi eelvaadeSeda pilti ei saa näidata%1$s ei suudetud kopeerida kohalikku kataloogi %2$s
+ Üleslaadimise radaVabandust, server ei toeta jagamist. Palun kontakteeru
⇥⇥administraatoriga.Jagamine ebaõnnestus. Palun kontrolli, kas fail on olemas
@@ -266,7 +268,11 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi
Fail ei ole serveris enam kättesaadavKontodLisa konto
- Turvalist ühendust suunatakse läbi turvamata ühenduse.
+ Turvaline ühendus suunatakse läbi turvamata ühenduse.
+ Logid
+ Saada ajalugu
+ ownCloud Android rakenduse logid
+ Andmete laadimine...Autentimine on vajalikVale paroolTõsta ümber
@@ -277,4 +283,6 @@ Allpool on loend kohalikest failidest ning serveris asuvatest failidest %5$s, mi
See fail on juba sihtkaustas olemasSelle faili või kausta liigutamisel tekkis tõrgeselle faili liigutamiseks
+ Kohesed üleslaadimised
+ Turvalisus
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 3edade4326..fec7404dbe 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -258,8 +258,8 @@ Mesedez, baimendu berriz
Fitxategia jadanik ez dago eskuragarri zerbitzarianKontuakGehitu kontua
- Konexio segurua birbideratu da segurua ez den bide batetik.Autentikazioa beharrezkoaPasahitz okerraAukeratu
+ Segurtasuna
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 200f5e2fb1..6a22f893e4 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -232,4 +232,5 @@
احراز هویت مورد نیاز استرمز عبور اشتباه استانتخاب کردن
+ امنیت
diff --git a/res/values-fi-rFI/strings.xml b/res/values-fi-rFI/strings.xml
index 9419f95f3a..6f02e4bcb5 100644
--- a/res/values-fi-rFI/strings.xml
+++ b/res/values-fi-rFI/strings.xml
@@ -218,6 +218,7 @@
Älä lähetäKuvan esikatseluTätä kuvaa ei voi näyttää
+ LähetyspolkuJakaminen ei ole käytössä palvelimellasi. Ota yhteys
ylläpitäjään.Virhe tiedoston tai kansion jakamista yrittäessä
@@ -240,7 +241,6 @@
Tämä tiedosto ei ole enää palvelimella käytettävissäTilitLisää tili
- Salattu yhteys on ohjattu uudelleen salaamatonta reittiä pitkin.LokitLähetä historiaownCloudin Android-sovelluksen lokit
@@ -253,4 +253,6 @@
Siirto ei onnistu. Tarkista, ettei tiedostoa ole jo olemassaTiedosto on jo olemassa kohdekansiossaTämän tiedoston tai kansion siirtoa yrittäessä tapahtui virhe
+ Välittömät lähetykset
+ Tietoturva
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 8bb1a0e886..17da4a9701 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -267,7 +267,6 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
Ce fichier n’est plus disponible sur le serveurComptesAjouter un compte
- Le connexion sécurisée est redirigée vers une route non-sécurisée.JournauxEnvoyer l\'historiqueJournaux de l\'application Android ownCloud
@@ -282,4 +281,5 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
Le fichier existe déjà dans le dossier de destinationUne erreur est survenue lors de la tentative de déplacement de ce fichier ou dossierde déplacer ce fichier
+ Sécurité
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 65344d2fc7..c169179c0c 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -259,9 +259,9 @@
O ficheiro xa non está dispoñíbel no servidorContasEngadir unha conta
- A conexión segura está a ser redirixida a través dunha ruta non segura.Requírese autenticaciónContrasinal incorrectoMoverEscoller
+ Seguranza
diff --git a/res/values-he/strings.xml b/res/values-he/strings.xml
index cd30af291d..4ae0072df8 100644
--- a/res/values-he/strings.xml
+++ b/res/values-he/strings.xml
@@ -260,6 +260,6 @@
הקובץ אינו זמין יותר על השרתחשבונותהוספת חשבון
- חיבור מאובטח מנותב דרך נתיב לא מאובטחבחירה
+ אבטחה
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 60b52f0540..b8dcfc5b1a 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -36,4 +36,5 @@
Potrebna autentikacijaPogrešna lozinkaIzaberi
+ Sigurnost
diff --git a/res/values-hu-rHU/strings.xml b/res/values-hu-rHU/strings.xml
index a0b16a04b3..f590006047 100644
--- a/res/values-hu-rHU/strings.xml
+++ b/res/values-hu-rHU/strings.xml
@@ -242,4 +242,5 @@
Felhasználóazonosítás szükségesHibás jelszóVálasszon
+ Biztonság
diff --git a/res/values-id/strings.xml b/res/values-id/strings.xml
index f7cfeaa76c..be93270a06 100644
--- a/res/values-id/strings.xml
+++ b/res/values-id/strings.xml
@@ -6,17 +6,21 @@
UnggahKonten dari apl lainBerkas
- Bukan dengan
+ Buka denganFolder baru
- pengaturan
+ PengaturanRincianKirim
- umum
+ UmumLainnyaAkunKelola AkunPIN AplLindungi klien Anda
+ Unggah gambar cepat
+ Unggah gambar yang diambil kamera dengan cepat
+ Unggah video cepat
+ Unggah video yang direkam kamera dengan cepatAktifkan PencatatanIni digunakan untuk mencatat masalahRiwayat Catatan
@@ -25,8 +29,9 @@
BantuanRekomendasikan ke temanUmpan balik
- Imprint
- Coba %1$s pada smartphone Anda!
+ Jejak
+ Cobalah %1$s pada ponsel cerdas Anda!
+ Saya ingin mengajak Anda untuk menggunakan %1$s di ponsel cerdas Anda!\nUnduh gratis disini: %2$sPeriksa ServerAlamat server https://…Nama Pengguna
@@ -35,6 +40,7 @@
BerkasSambungkanUnggah
+ Pilih folder unggah:Tidak ada akun yang ditemukanBelum ada akun %1$s pada perangkat Anda. Silahkan buat akun terlebih dahulu.Pengaturan
@@ -44,6 +50,8 @@
%1$s tidak diizinkan mengakses konten berbagiMengunggahTidak ada apa-apa di sini. Unggah sesuatu!
+ Memuat...
+ Tidak ada satupun berkas dalam folder ini.Sentuh pada berkas untuk menampilkan informasi tambahanUkuran:Tipe:
@@ -53,6 +61,7 @@
Segarkan berkasBerkas diubah namanya menjadi %1$s saat pengunggahanBagikan tautan
+ Batal bagikan tautanYaTidakOke
@@ -82,19 +91,26 @@
Gagal MengunduhMengunduh %1$s tidak selesaiBelum diunduh
+ Gagal mengunduh, Anda perlu masuk kembaliPilih akunSinkronisasi gagal
+ Sinkronisasi gagal, Anda perlu masuk kembaliSinkronisasi %1$s tidak selesaiSandi salah untuk %1$sKonflik ditemukan
+ %1$d berkas kept-in-sync tidak dapat disinkronkan
+ Berkas kept-in-sync gagalKonten berkas %1$d tidak dapat disinkronasikan (%2$d konflik)Beberapa berkas lokal terlupakan
+ %1$d berkas diluar folder %2$s tidak dapat disalin kedalamnya
+ Sejak versi 1.3.16, berkas-berkas yang diunggah dari piranti ini akan disalin kedalam folder %1$s lokal untuk mencagah kehilangan data ketika berkas tunggal disinkronkan dengan akun lebih dari satu.\n\nAkibat perubahan ini, semua berkas yang diunggah di versi aplikasi sebelumnya disalin kedalam folder %2$s. Namun, sebuah kesalahan mencegah penyelesaian operasi ini saat sinkronisasi berlangsung akun. Anda boleh meninggalkan berkas seperti ini dan menghapus tautan ke %3$s atau memindahkan berkas kedalam folder %1$s dan membiarkan tautan ke %4$s.\n\nYang tampak dibawah adalah berkas lokal, dan berkas remote didalam %5$s yang dihubungkan dengannya.Folder %1$s tidak ada lagiPindahkan semuaSemua berkas sudah dipindahkanBeberapa berkas tidak dapat dipindahkanLokal: %1$sJauh: %1$s
+ Ruang tidak cukup untuk menyalin berkas terpilih kedalam folder %1$s. Apakah Anda ingin memindahkannya saja?Silakan masukkan PIN AplMasukkan PIN AplPIN akan selalu diminta setiap kali apl dijalankan
@@ -107,6 +123,7 @@
Pemutar musik %1$s%1$s (dimainkan)%1$s (sedang dimuat)
+ %1$s pemutaran selesaiTidak ditemukan berkas mediaTidak ada akun yang diberikanBrkas tidak didalam akun yang sah
@@ -122,6 +139,7 @@
Tombol mundurTombol main dan jedaTombol maju
+ Mendapatkan otorisasi...Mencoba untuk masuk...Tidak ada koneksi internetSambungan aman tidak tersedia
@@ -150,9 +168,12 @@
Menyambungkan ke server otentikasi...Server tidak mendukung medote otentikasi ini%1$s tidak mendukung banyak akun
+ Tidak dapat mengotentikasi pada server iniBiarkan berkas tetap terbaruUbah namaHapus
+ Apakah Anda yakin ingin menghapus %1$s?
+ Apakah Anda yakin ingin menghapus %1$s dan isinya?Lokal sajaKonten lokal sajaHapus dari server
@@ -164,10 +185,13 @@
Mengubah nama tidak selesaiBerkas jauh tidak dapat diperiksaIsi berkas sudah diselaraskan
+ Folder tidak dapat dibuatKarakter yang dilarang: / \\ < > : \" | ? *
- Tunggu sejenak
+ Nama berkas tidak boleh kosong
+ Tunggu sebentarMasalah tidak terduga, silahkan pilih berkas dari apl yang berbedaTidak ada berkas yang terpilih
+ Kirim taukan keMasuk dengan oAuth2Menyambungkan ke server oAuth2...Identitas situs tidak dapat diverfikasi
@@ -192,6 +216,8 @@
Untuk:Tanda tangan:Algoritma:
+ Sertifikat tidak dapat ditampilkan.
+ - Tidak ada informasi tantang terrorIni adalah placeholderplaceholder.txtGambar PNG
@@ -199,6 +225,7 @@
18/05/2012 12:23 PM12:23:45Hanya unggah gambar via WiFi
+ Hanya unggah video via WiFi/UnggahInstanPerbarui benturanBerkas jauh %s tidak sinkron dengan berkas lokal. Melanjutkan akan menggantikan konten berkas di server.
@@ -206,10 +233,13 @@
TimpaJangan mengunggahPratilik gambar
+ Gambar ini tidak dapat ditampilkanKirim
+ Disalin ke papan klipAkunDiperlukan otentikasiSandi salahPilih
+ Keamanan
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index d450760262..42093f7f31 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -263,7 +263,6 @@
Il file non è più disponibile sul serverAccountAggiungi account
- La connessione sicura è rediretta attraverso un percorso non sicuro.RegistriInvia cronologiaRegistri applicazione ownCloud Android
@@ -278,4 +277,5 @@
Il file esiste già nella cartella di destinazioneSi è verificato un errore durante il tentativo di spostare il file o la cartellaper spostare questo file
+ Protezione
diff --git a/res/values-ja-rJP/strings.xml b/res/values-ja-rJP/strings.xml
index 996d16c313..b6d8ffb4ad 100644
--- a/res/values-ja-rJP/strings.xml
+++ b/res/values-ja-rJP/strings.xml
@@ -264,7 +264,6 @@
ファイルはサーバー上で利用できませんアカウントアカウントを追加
- 暗号化されていない接続を経て、暗号化接続へリダイレクトされました。ログログを送信ownCloud Android アプリログ
@@ -279,4 +278,5 @@
そのファイルは、宛先フォルダに既に存在しています。このファイルまたはフォルダーを移動する際にエラーが発生しましたこのファイルを移動
+ セキュリティ
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index b23ca4735b..43b1a456c2 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -149,4 +149,5 @@
ანგარიშიარჩევა
+ უსაფრთხოება
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 3c4f3cd3f0..752985c327 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -83,4 +83,5 @@
គណនីខុសពាក្យសម្ងាត់ជ្រើស
+ សុវត្ថិភាព
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index b8313dbc4d..4a0df83f71 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -217,4 +217,5 @@
인증 필요함잘못된 암호선택
+ 보안
diff --git a/res/values-lt-rLT/strings.xml b/res/values-lt-rLT/strings.xml
index 5dfaffa470..70bc85d524 100644
--- a/res/values-lt-rLT/strings.xml
+++ b/res/values-lt-rLT/strings.xml
@@ -234,4 +234,5 @@
PaskyrosNeteisingas slaptažodisPasirinkite
+ Saugumas
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 41a1872f9e..88df8292b8 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -143,4 +143,5 @@
KontiIzvēlieties
+ Drošība
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index d7a623013d..e7b4906ec4 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -122,4 +122,5 @@
Потребна е автентификацијаПогрешна лозинкаИзбери
+ Безбедност
diff --git a/res/values-nb-rNO/strings.xml b/res/values-nb-rNO/strings.xml
index dc60a35638..55e2bb4cb5 100644
--- a/res/values-nb-rNO/strings.xml
+++ b/res/values-nb-rNO/strings.xml
@@ -263,7 +263,6 @@
Filen finnes ikke på serveren lengerKontoerLegg til en konto
- Sikker tilkobling videresendes gjennom en usikker rute.LoggerSend historikklogger for ownCloud Android app
@@ -278,4 +277,5 @@
Filen finnes allerede i målmappenEn feil oppstod ved flytting av denne filen eller mappenå flytte denne filen
+ Sikkerhet
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 2f12347a4d..f79d9331ae 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -241,6 +241,7 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar
Afbeelding voorbeeldDeze afbeelding kan niet worden getoond%1$s kon niet worden gekopieerd naar de %2$s lokale map
+ Upload padSorry, delen is niet mogelijk op uw server. Neem contact op met uw
beheerder.Kan dit niet delen. Controleer of dit bestand wel bestaat.
@@ -266,7 +267,7 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar
Dit bestand is niet langer beschikbaar op de serverAccountsToevoegen account
- De beveiligde verbinding is omgeleid via een onveilige route.
+ De beveiligde verbinding is omgeleid naar een onveilige route.LogsVerstuur geschiedenisownCloud Android app logs
@@ -281,4 +282,6 @@ Hieronder staan de lokale bestanden en de externe bestanden in %5$s waar ze naar
Het bestand bestaat al in de doelmapEr trad een fout op bij uw poging dit bestand of deze map te verplaatsenom dit bestand te verplaatsen
+ Directe uploads
+ Beveiliging
diff --git a/res/values-nn-rNO/strings.xml b/res/values-nn-rNO/strings.xml
index 8c15264f8e..528bff4fcc 100644
--- a/res/values-nn-rNO/strings.xml
+++ b/res/values-nn-rNO/strings.xml
@@ -129,4 +129,5 @@
KontoarFeil passordVel
+ Tryggleik
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 9fd718a098..8c0a98787d 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -263,7 +263,6 @@
Ten plik nie jest już dostępny na serwerzeKontaDodaj konto
- Bezpieczne połączenie jest przekierowywane przez niezabezpieczone trasy.LogiWyślij historięŁaduję dane...
@@ -277,4 +276,5 @@
Plik istnieje już w folderze docelowymPojawił się błąd podczas próby przeniesienia tego pliku lub folderuaby przenieść ten plik
+ Bezpieczeństwo
diff --git a/res/values-pt-rBR/strings.xml b/res/values-pt-rBR/strings.xml
index 71df1607c1..3ffb84b83f 100644
--- a/res/values-pt-rBR/strings.xml
+++ b/res/values-pt-rBR/strings.xml
@@ -238,6 +238,7 @@
Pré-visualização da imagemEsta imagem não pode ser mostrada%1$s não pôde ser copiado para pasta local %2$s
+ Enviar CaminhoDesculpe, o compartilhamento não está habilitado em seu servidor. Entre em contato com seu
⇥⇥ administrador.Não é possível compartilhar. Por favor verifique se o arquivo existe
@@ -263,7 +264,7 @@
Este arquivo não mais está disponível neste servidorContasAdicionar uma conta
- A conexão segura está redirecionada através de uma rota insegura.
+ Conexão segura esta redirecionada para uma rota não segura.LogsEnviar HistóricoLogs do aplicativo ownCloud Android
@@ -278,4 +279,6 @@
O arquivo já existe na pasta de destinoOcorreu um erro ao tentar mover este arquivo ou pastamover este arquivo
+ Envios Instantâneos
+ Segurança
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index dcf877893c..6c4aab17de 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -31,6 +31,7 @@
RespostaImprintExperimente %1$s no seu smartphone!
+ Quero convidar-te a usares %1$s no teu smartphone!\nFaz download aqui: %2$sVerificar ServidorEndereço do servidor https://..Nome de Utilizador
@@ -236,9 +237,11 @@
Pré-Visualização da imagemEsta imagem não pode ser mostradaNão foi possível copiar %1$s para a pasta local %2$s
+ Caminho de UploadLamentamos mas não é possível partilhar através do seu servidor. Por favor contacte o seu administrador.Não é possivel partilhar. Por favor verifique se o ficheiro existeOcorreu um erro enquanto tentava partilhar este ficheiro ou pasta
+ Não é possível retirar a partilha. Verifique se o ficheiro existeOcorreu um erro enquanto retirava a partilha deste ficheiro ou pastaEnviarCopiar ligação
@@ -259,14 +262,21 @@
O ficheiro não está mais disponível no servidorContasAdicionar conta
- Uma ligação segura foi redireccionada por uma rota insegura.
+ Ligação segura é redireccionada para um caminho inseguro.
+ LogsEnviar Histórico
+ Logs da app ownCloud AndroidA carregar os dados...Autenticação necessáriaPassword erradaMoverNão está aqui nada. Pode adicionar uma pasta!Escolha
+ Não é possível mover. Verifique se o ficheiro existe
+ Não é possível mover esta pasta deste modoO ficheiro já existe na pasta de destino
+ Um erro ocorreu ao tentar mover este ficheiro ou pastapara mover este ficheiro
+ Uploads Instantâneos
+ Segurança
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index c3e20eee68..b3ea72569f 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -259,4 +259,5 @@
ConturiParolă greșităAlege
+ Securitate
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 49c3e3cc2d..66ad7ad03c 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -263,7 +263,6 @@
Этот файл больше недоступен на сервереУчётные записиДобавить учетную запись
- Безопасное соединение перенаправлено через небезопасный маршрут.ЖурналыИстория ОтправленийЖурналы Андроид-приложения ownCloud
@@ -278,4 +277,5 @@
Файл уже существует в папке назначенияПроизошла ошибка при попытке перемещения этого файла или папкипереместить этот файл
+ Безопасность
diff --git a/res/values-sk-rSK/strings.xml b/res/values-sk-rSK/strings.xml
index 78e0942522..768604358d 100644
--- a/res/values-sk-rSK/strings.xml
+++ b/res/values-sk-rSK/strings.xml
@@ -259,9 +259,9 @@
Súbor už na serveri nie je dostupnýÚčtyPridať účet
- Zabezpečené spojenie je presmerované nezabezpečenou cestou.Vyžaduje sa overenieNesprávne hesloPresunúťVybrať
+ Zabezpečenie
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index da73b33b7c..dcdf60381c 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -263,7 +263,6 @@
Datoteka na strežniku ni več na voljo.RačuniDodaj račun
- Varna povezava je preusmerjena preko ne-varne poti.DnevnikPošlji zgodovinoDnevnik programa ownCloud
@@ -278,4 +277,5 @@
Datoteka v ciljni mapi že obstaja.Prišlo je do napake med premikanjem datoteke v mapomed premikanjem datoteke
+ Varnost
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index def1b9b8e8..adeb3e99c6 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -72,4 +72,5 @@
LlogaritFjalëkalim i gabuarZgjidh
+ Siguria
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 5384da08d8..2ef137369c 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -109,4 +109,5 @@
НалозиОдабери
+ Безбедност
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index be0067470b..c077786f75 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -30,8 +30,8 @@
Rekommendera till en vänFeedbackImprint
- Försök %1$s på din smarttelefon!
- Jag skulle vilja bjuda in dig till att använda %1$s på din smartphone!\nLadda ner här: %2$s
+ Prova %1$s på din smartphone!
+ Jag skullje vilja bjuda in dig till att prova %1$s på din smartphone!\nLadda ner appen från Google Play här: %2$sKontrollera ServerServeradress https://...Användarnamn
@@ -268,4 +268,5 @@
VäljGick inte att flytta. Vänligen kontrollera att filen existeraratt flytta den här filen
+ Säkerhet
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 72a158915e..e5bfe93dea 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -238,6 +238,7 @@
Resim önizlemeBu resim gösterilemiyor%1$s, %2$s yerel klasörüne kopyalanamadı
+ Yükleme YoluÜzgünüz, paylaşım sunucunuzda etkin değil. Lütfen yöneticinizle
iletişime geçin.Paylaşma başarısız. Lütfen dosyanın mevcut olup olmadığını denetleyin
@@ -263,7 +264,7 @@
Bu dosya artık sunucuda mevcut değilHesaplarHesap ekle
- Güvenli bağlantı, güvenli olmayan bir rotaya yönlendiriliyor.
+ Güvenli bağlantı, güvenli olmayan bir rotaya yönlendirildi.GünlüklerGeçmişi GönderownCloud Android uygulama kayıtları
@@ -278,4 +279,6 @@
Dosya zaten hedef klasörde mevcutBu dosya veya klasörü taşımaya çalışılırken bir hata oluştubu dosyayı taşımak için
+ Anında Yüklemeler
+ Güvenlik
diff --git a/res/values-ug/strings.xml b/res/values-ug/strings.xml
index b126d8972f..e1140f871b 100644
--- a/res/values-ug/strings.xml
+++ b/res/values-ug/strings.xml
@@ -41,4 +41,5 @@
يوللاھېساباتلار
+ بىخەتەرلىك
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 68185743bc..d927e39fe5 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -1,8 +1,12 @@
+ %1$s Android App
+ версія %1$s
+ Оновити accountВідвантажитиВміст із інших програмФайли
+ Відкрити за допомогоюНова текаНалаштуванняДеталі
@@ -13,14 +17,30 @@
Управління обліковими записамиApp програмний PINЗахист Вашог App клієнта
+ Миттєві зображення
+ Миттєві зображення з камери
+ Миттєві відео
+ Миттєві відео з камери
+ Ввімкнути журнал
+ Використовується для реєстрації помилок
+ Журнал
+ Тут показані записи журналу
+ Видалити історію записівДопомога
+ Порадити товаришуЗворотній зв\'язокВідбиток
+ Спробуйте %1$s на своєму смартфоні!
+ Пропоную вам користуватися %1$s на вашому смартфоні!\nЗавантажити можна за посиланням: %2$s
+ Перевірити сервер
+ Адреса серверу https://…Ім\'я користувачаПароль
+ Вперше в %1$s?ФайлиЗ\'єднатиВідвантажити
+ Оберіть теку для завантаження:Не знайдено облікового записуНа Вашому пристрої відсутні облікові записи %1$s. Будь ласка, спочатку створіть запис.Налаштування
@@ -30,14 +50,18 @@
%1$s не може отримати доступ до спільного контентуЗавантаженняТут нічого немає. Відвантажте що-небудь!
+ Завантаження...
+ В цій теці немає файлів.Натисніть на файлі для відображення додаткової інформаціїРозмір:Тип:Створено:Змінено:Завантажити
+ Оновити файлФайл був переіменований в %1$s протягом вивантаженняОпублікувати посилання
+ Видалити посиланняТакНіOK
@@ -46,6 +70,7 @@
ВідмінитиЗберегти & ВихідПомилка
+ Завантаження...Невідома помилкаПроЗмінити пароль
@@ -59,25 +84,34 @@
%1$s було успішно завантаженоПомилка завантаженняЗавантаження %1$s не може завершитись
+ Завантажити не вдалося, необхідно повторити вхідЗкачування …%1$d%% Зкачування %2$sУспішно зкачано%1$s успішно завантаженоЗавантаження не вдалосяЗавантаження %1$s не вдається завершити
+ Ще не завантажене
+ Зберегти не вдалося, необхідно повторити вхідОберіть обліковий записПомилка синхронізації
+ Синхронізація не вдалася, необхідно повторити вхідСинхронізація %1$s не вдалась
+ Невірний пароль для %1$sКонфліктів знайдено%1$d файли, які мають бути синхронізованими не можуть синхронізуватисяСинхронізувати файли не вдалосяЗміст %1$d файлів не може бути синхронізований (%2$d конфліктів)Деякі локальні файли були забуті
+ Неможливо скопіювати %1$d файли з теки %2$s
+ \"Починаючи з версії 1.3.16, файли, завантажені з цього пристрою копіюються в локальну теку %1$s для запобігання втрати даних під час синхронізації одного файлу з кількома обліковими записами.\n\nТому всі файли, завантажені в попередніх версіях цього додатку були скопійовані в теку %2$s. Однак, під час синхронізації сталася помилка. Ви можете залишити файл(и) як є та видалити посилання на %3$s, або перемістити файл(и) в директорію %1$s і зберегти посилання на %4$s.\n\nНижче наведені локальні та віддалені файли у %5$s з якою вони були пов\'язані.
+ Тека %1$s білше не існуєПеремістити всеВсі файли були переміщеніДеякі файли не можуть бути переміщеніЛокально: %1$sВіддалено: %1$s
+ Недостатньо місця для копіювання обраних файлів у теку %1$s. Чи бажаєте ви перемістити їх замість копіювання?Будь ласка, введіть свій програмний PINВведіть програмний PINPIN необхідно буде вводити щоразу при запуску цієї програми
@@ -87,24 +121,62 @@
Не вірний App програмний PINApp програмний PIN видаленоApp програмний PIN збережено
+ %1$s музичний плеєр
+ %1$s (відтворення)
+ %1$s (завантаження)
+ %1$s відтворення завершене
+ Медіа-файлів не знайдено
+ Обліковий запис не налаштований
+ Файл в невірному обліковому записі
+ Кодек не підтримується
+ Медіа-файл не читається
+ Медіа-файл невірно закодований
+ Вийшов час на спробу відтворення
+ Неможливо потоком відтворити файл
+ Медіа-файл неможливо відтворити вбудованим програвачем
+ Помилка безпеки при відтворені %1$s
+ Помилка вводу при відтворені %1$s
+ Несподівана помилка при відтворені %1$s
+ Перемтка назад
+ Відтворення або пауза
+ Перемотка вперед
+ Виконується вхід...Спроба входу…Відсутнє підключення до мережіБезпечне з\'єднання не доступне.З\'єднання встановленоПеревірка з\'єднання…Не вірні налаштування сервер
+ Такий обліковий запис вже існує на пристрої
+ Введений користувач не відповідає обліковому записуВиникла невідома помилка!Не вдалося знайти хостНе знайдено примірник серверСервер занадто довго не відповідаєПошкоджений URLПомилка SSL ініціалізації
+ Неможливо перевірити SSL-сертифікат сервераНе вдалося визначити версію сервер серверуНе вдалося встановити з\'єднанняВстановлено захищене з\'єднання
+ Невірне ім\'я користувача або пароль
+ Невдала авторизація
+ Доступ заборонений сервером авторизації
+ Несподівана відповідь; будь ласка, введіть адресу сервера знову
+ Час авторизації минув. Будь ласка, увійдіть знову
+ Будь ласка, введіть пароль
+ Час сесії минув. Будь ласка, підключіться знов
+ Підключення до серверу аутентифікації...
+ Сервер не підтримує обраний метод аутентифікації
+ %1$s не підтримує одночасно декілька облікових записів
+ Ваш сервер не повертає коректний ідентифікатор користувача, будь ласка зверніться до адміністратора
+⇥
+ Аутентифікація на цьому сервері неможливаОновлювати файлПерейменуватиВидалити
+ Ви дійсно бажаєте видалити %1$s?
+ Ви дійсно бажаєте видалити %1$s та весь вміст?Лише локальноЛише локальний змістВидалити із серверу
@@ -116,9 +188,15 @@
Перейменування не вдалосяНеможливо перевірити віддалений файлЗміст файлу вже синхронізовано
+ Не вдалося створити теку
+ Заборонені символи: / \\ < > : \" | ? *
+ Ім\'я файлу не може бути порожнім.Зачекайте хвилинкуНесподівані проблеми ; будь ласка, спробуйте використати іншу програму для вибору файлуНе обрано файл
+ Надіслати посилання...
+ Увійти через oAuth2
+ Підключення до серверу oAuth2...Не вдалося перевірити ідентифікацію сайта- Не довірений сертифікат серверу- Сертифікат серверу втратив чинність
@@ -141,17 +219,65 @@
До:Підпис:Алгоритм:
+ Не вдалося показати сертифікат.
+ - Інформація про помилку відсутняЦе заповнювач
+ placeholder.txt
+ PNG зображення
+ 389 КБ
+ 2012/05/18 12:23 PM
+ 12:23:45Завантажувати зображення тільки через WiFi
+ Завантажувати відео тільки через WiFi/InstantUploadКонфлікт оновленняВіддалений файл %s не синхронізовано з локальним. Продовження процедури замінить вміст файлу на сервері.Залишити обидваЗамінитиНе завантажувати
+ Попередній перегляд зображення
+ Не вдалося показати зображення
+ %1$s неможливо скопіювати до %2$s
+ Завантажити шлях
+ На жаль, обмін не включений на вашому сервері. Будь ласка, зв\'яжіться з вашим адмінистратором.
+ Неможливо поділитися. Будь ласка, перевірте, чи існує файл
+ Виникла помилка при спробі поділитися файлом або текою
+ Неможливо заборонити доступ. Будь ласка, перевірте, чи існує файл
+ Виникла помилка при спробі заборонити доступ до файлу або текиНадіслати
+ Копіювати посиланняСкопійовано в буфер обміну
+ Критична помилка: виконання операції неможливе
+ Виникла помилка при підключені до сервера.
+ Під час очікування на сервер виникла помилка, операцію неможливо завершити
+ Під час очікування на сервер виникла помилка, операцію неможливо завершити
+ Неможливо завершити операцію, сервер недоступний
+ У вас немає повноважень %s
+ на перейменування цього файла
+ на видалення цього файла
+ для надання доступу до файла
+ для закриття доступу до файла
+ для створення файла
+ для завантаження в цю теку
+ Файл більше не доступний на серверіОблікові записи
+ Додати обліковий запис
+ Безпечне підключення перенаправляється через незабезпечений маршрут.
+ Журнали
+ Надіслати історію
+ Журнали Android-додатка ownCloud
+ Завантаження даних...
+ Потрібна аутентифікація
+ Невірний пароль
+ Перемістити
+ Тут нічого немає. Ви можете додати теку!Обрати
+ Неможливо перемістити. Будь ласка, перевірте, чи існує файл
+ Неможливо перемістити теку до теки-нащадка
+ Файл вже існує в теці призначення
+ Виникла помилка при спробі перемістити файл або теку
+ перемістити цей файл
+ Миттєво завантаження
+ Безпека
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index c744b68dfe..79255f8dee 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -263,7 +263,6 @@
该文件在服务器上不可用账号添加账号
- 安全连接是通过一个非安全路由定向的。日志发送历史ownCloud安卓客户端日志
@@ -278,4 +277,5 @@
该文件已经存在在目标文件夹尝试移动该文件或文件夹时发生错误移动该文件
+ 安全
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index aca365e0f2..91041380b7 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -31,6 +31,7 @@
反饋法律聲明在您的手機中試用%1$s!
+ 我想邀請您在您的手機上使用 %1$s ! 可以由這兒下載: %2$s檢查伺服器伺服器位址 https://...使用者名稱
@@ -49,6 +50,8 @@
%1$s 並沒有被允許存取分享的內容上傳中這裡還沒有東西,上傳一些吧!
+ 載入中…
+ 這個目錄中沒有任何檔案.在檔案上輕觸來顯示更多資訊。容量:類型:
@@ -92,6 +95,7 @@
下傳失敗, 您需要重新登入選擇帳號同步失敗
+ 同步作業失敗, 您需要重新登入同步 %1$s 未完成無效的密碼 %1$s出現衝突
@@ -100,12 +104,14 @@
%1$d 未被同步 (%2$d 衝突)有些本地端的檔案已遺失%1$d 檔案超過 %2$s 資料夾可能不能複製進去
+ 在 1.3.16 版之前, 檔案上傳時會先複製到本地的 %1$s 目錄以避免在多帳戶內同步造成遺失.\n\n由於這個改變, 所以在之前版本上傳的檔案被複製到 %2$s 目錄中. 為了避免同步發生問題. 你可以保留那些檔案並刪除連結 %3$s, 或搬移檔案到 %1$s 目錄並取得連結到 %4$s.\n\n下面列表是本地檔案, 與被連結遠端檔案 %5$s.資料夾 %1$s 不存在移動全部所有文件已被移動部份文件無法被移動本地: %1$s遠端: %1$s
+ 無足夠的空間可以複製檔案到 %1$s 目錄. 是否使用移動的方式來處理? 請輸入您的 App 密碼輸入您的 App 密碼這個密碼在你每次啟動這程式時都會被要求輸入
@@ -232,9 +238,12 @@
圖片預覽無法顯示圖片%1$s 無法被複製到本地目錄 %2$s
+ 上傳目錄很抱歉, 您的伺服器並未開啟分享的功能. 請聯絡您的
伺服器管理員.
+ 無法分享這個檔案或目錄. 請檢查它們是否存在在分享檔案或目錄時發生了錯誤
+ 無法取消分享這個檔案或目錄. 請檢查它們是否存在在取消分享檔案或目錄時發生了錯誤寄出複製連結
@@ -245,8 +254,31 @@
在等待伺服器回應時發生了錯誤, 這個操作將無法被完成這個操作無法完成, 無法使用伺服器
+ 您沒有權限 %s
+ 重新命名檔案
+ 刪除檔案
+ 分享檔案
+ 取消分享檔案
+ 建立檔案
+ 上傳這個目錄
+ 這個檔案已經不存在於伺服器中帳號
+ 新增帳號
+ 安全連線被轉向到一個非安全的連線
+ 紀錄
+ 傳送歷史記錄
+ ownCloud Android 應用程式記錄
+ 資料載入中...必須驗證密碼錯誤
+ 移動
+ 找不到任何檔案. 你可以新增一個目錄!選擇
+ 無法搬移. 請檢查該檔案是否存在
+ 把一個目錄搬移到其底下的子目錄是不可能的
+ 這個檔案已經存在於目的目錄中
+ 在移動檔案或目錄時發生了錯誤
+ 移動這個檔案
+ 即時上傳
+ 安全性
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 4c7cf34d10..389db1da41 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -251,6 +251,7 @@
This image cannot be shown%1$s could not be copied to %2$s local folder
+ Upload PathSorry, sharing is not enabled on your server. Please contact your
administrator.
@@ -283,7 +284,7 @@
AccountsAdd account
- Secure connection is redirected through an unsecured route.
+ Secure connection is redirected to an unsecured route.LogsSend History
@@ -302,4 +303,7 @@
An error occurred while trying to move this file or folderto move this file
+ Instant Uploads
+ Security
+
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index 945e853cc7..3b8b3e81b5 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -21,35 +21,41 @@
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
@@ -65,4 +71,4 @@
-
\ No newline at end of file
+
diff --git a/setup_env.sh b/setup_env.sh
index e60475288c..ae4214238b 100755
--- a/setup_env.sh
+++ b/setup_env.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/bash -e
git submodule init
git submodule update
diff --git a/src/com/owncloud/android/MainApp.java b/src/com/owncloud/android/MainApp.java
index 9a47bd78d0..e04239df87 100644
--- a/src/com/owncloud/android/MainApp.java
+++ b/src/com/owncloud/android/MainApp.java
@@ -19,6 +19,7 @@ package com.owncloud.android;
import android.app.Application;
import android.content.Context;
+import com.owncloud.android.datamodel.ThumbnailsCacheManager;
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory.Policy;
import com.owncloud.android.lib.common.utils.Log_OC;
@@ -55,6 +56,9 @@ public class MainApp extends Application {
OwnCloudClientManagerFactory.setDefaultPolicy(Policy.ALWAYS_NEW_CLIENT);
}
+ // initialise thumbnails cache on background thread
+ new ThumbnailsCacheManager.InitDiskCacheTask().execute();
+
if (BuildConfig.DEBUG) {
String dataFolder = getDataFolder();
diff --git a/src/com/owncloud/android/authentication/AuthenticatorActivity.java b/src/com/owncloud/android/authentication/AuthenticatorActivity.java
index ee38c4b50e..0f7892ee18 100644
--- a/src/com/owncloud/android/authentication/AuthenticatorActivity.java
+++ b/src/com/owncloud/android/authentication/AuthenticatorActivity.java
@@ -247,13 +247,17 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
if (mAccount != null) {
boolean oAuthRequired =
(mAccountMgr.getUserData(mAccount, Constants.KEY_SUPPORTS_OAUTH2) != null);
- boolean samlWebSsoRequired =
- (mAccountMgr.getUserData(mAccount, Constants.KEY_SUPPORTS_SAML_WEB_SSO) != null);
+ boolean samlWebSsoRequired = (
+ mAccountMgr.getUserData(
+ mAccount, Constants.KEY_SUPPORTS_SAML_WEB_SSO
+ ) != null
+ );
mAuthTokenType = chooseAuthTokenType(oAuthRequired, samlWebSsoRequired);
} else {
boolean oAuthSupported = AUTH_ON.equals(getString(R.string.auth_method_oauth2));
- boolean samlWebSsoSupported = AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso));
+ boolean samlWebSsoSupported =
+ AUTH_ON.equals(getString(R.string.auth_method_saml_web_sso));
mAuthTokenType = chooseAuthTokenType(oAuthSupported, samlWebSsoSupported);
}
}
@@ -322,7 +326,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
if (savedInstanceState == null) {
if (mAccount != null) {
mServerInfo.mBaseUrl = mAccountMgr.getUserData(mAccount, Constants.KEY_OC_BASE_URL);
- mServerInfo.mIsSslConn = mServerInfo.mBaseUrl.startsWith("https://"); // TODO do this in a setter for mBaseUrl
+ // TODO do next in a setter for mBaseUrl
+ mServerInfo.mIsSslConn = mServerInfo.mBaseUrl.startsWith("https://");
String ocVersion = mAccountMgr.getUserData(mAccount, Constants.KEY_OC_VERSION);
if (ocVersion != null) {
mServerInfo.mVersion = new OwnCloudVersion(ocVersion);
@@ -407,8 +412,12 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
@Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
- if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType) &&
- mHostUrlInput.hasFocus()) {
+ if (
+ AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(
+ MainApp.getAccountType()
+ ).equals(mAuthTokenType) &&
+ mHostUrlInput.hasFocus()
+ ) {
checkOcServer();
}
}
@@ -536,8 +545,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
/**
* Saves relevant state before {@link #onPause()}
*
- * Do NOT save {@link #mNewCapturedUriFromOAuth2Redirection}; it keeps a temporal flag, intended to defer the
- * processing of the redirection caught in {@link #onNewIntent(Intent)} until {@link #onResume()}
+ * Do NOT save {@link #mNewCapturedUriFromOAuth2Redirection}; it keeps a temporal flag,
+ * intended to defer the processing of the redirection caught in
+ * {@link #onNewIntent(Intent)} until {@link #onResume()}
*
* See {@link #loadSavedInstanceState(Bundle)}
*/
@@ -576,11 +586,11 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
/**
- * The redirection triggered by the OAuth authentication server as response to the GET AUTHORIZATION request
- * is caught here.
+ * The redirection triggered by the OAuth authentication server as response to the
+ * GET AUTHORIZATION request is caught here.
*
- * To make this possible, this activity needs to be qualified with android:launchMode = "singleTask" in the
- * AndroidManifest.xml file.
+ * To make this possible, this activity needs to be qualified with android:launchMode =
+ * "singleTask" in the AndroidManifest.xml file.
*/
@Override
protected void onNewIntent (Intent intent) {
@@ -593,8 +603,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
/**
- * The redirection triggered by the OAuth authentication server as response to the GET AUTHORIZATION, and
- * deferred in {@link #onNewIntent(Intent)}, is processed here.
+ * The redirection triggered by the OAuth authentication server as response to the
+ * GET AUTHORIZATION, and deferred in {@link #onNewIntent(Intent)}, is processed here.
*/
@Override
protected void onResume() {
@@ -737,7 +747,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
Intent getServerInfoIntent = new Intent();
getServerInfoIntent.setAction(OperationsService.ACTION_GET_SERVER_INFO);
- getServerInfoIntent.putExtra(OperationsService.EXTRA_SERVER_URL, uri);
+ getServerInfoIntent.putExtra(
+ OperationsService.EXTRA_SERVER_URL,
+ normalizeUrlSuffix(uri)
+ );
if (mOperationsServiceBinder != null) {
mWaitingForOpId = mOperationsServiceBinder.newOperation(getServerInfoIntent);
} else {
@@ -781,7 +794,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
}
private boolean isPasswordVisible() {
- return ((mPasswordInput.getInputType() & InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
+ return ((mPasswordInput.getInputType() & InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) ==
+ InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
}
private void hidePasswordButton() {
@@ -789,12 +803,16 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
}
private void showPassword() {
- mPasswordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
+ mPasswordInput.setInputType(
+ InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
+ );
showViewPasswordButton();
}
private void hidePassword() {
- mPasswordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ mPasswordInput.setInputType(
+ InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD
+ );
showViewPasswordButton();
}
@@ -826,9 +844,13 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
return;
}
- if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).equals(mAuthTokenType)) {
+ if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).
+ equals(mAuthTokenType)) {
+
startOauthorization();
- } else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType)) {
+ } else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).
+ equals(mAuthTokenType)) {
+
startSamlBasedFederatedSingleSignOnAuthorization();
} else {
checkBasicAuthorization();
@@ -883,10 +905,18 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
// GET AUTHORIZATION request
Uri uri = Uri.parse(mOAuthAuthEndpointText.getText().toString().trim());
Uri.Builder uriBuilder = uri.buildUpon();
- uriBuilder.appendQueryParameter(OAuth2Constants.KEY_RESPONSE_TYPE, getString(R.string.oauth2_response_type));
- uriBuilder.appendQueryParameter(OAuth2Constants.KEY_REDIRECT_URI, getString(R.string.oauth2_redirect_uri));
- uriBuilder.appendQueryParameter(OAuth2Constants.KEY_CLIENT_ID, getString(R.string.oauth2_client_id));
- uriBuilder.appendQueryParameter(OAuth2Constants.KEY_SCOPE, getString(R.string.oauth2_scope));
+ uriBuilder.appendQueryParameter(
+ OAuth2Constants.KEY_RESPONSE_TYPE, getString(R.string.oauth2_response_type)
+ );
+ uriBuilder.appendQueryParameter(
+ OAuth2Constants.KEY_REDIRECT_URI, getString(R.string.oauth2_redirect_uri)
+ );
+ uriBuilder.appendQueryParameter(
+ OAuth2Constants.KEY_CLIENT_ID, getString(R.string.oauth2_client_id)
+ );
+ uriBuilder.appendQueryParameter(
+ OAuth2Constants.KEY_SCOPE, getString(R.string.oauth2_scope)
+ );
uri = uriBuilder.build();
Log_OC.d(TAG, "Starting browser to view " + uri.toString());
Intent i = new Intent(Intent.ACTION_VIEW, uri);
@@ -931,7 +961,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
} else if (operation instanceof ExistenceCheckRemoteOperation) {
//Log_OC.wtf(TAG, "received detection response through callback" );
- if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType)) {
+ if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).
+ equals(mAuthTokenType)) {
onSamlBasedFederatedSingleSignOnAuthorizationStart(result);
} else {
@@ -1084,16 +1115,20 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
url = "http://" + url;
}
}
-
- url = trimUrlWebdav(url);
-
- if (url.endsWith("/")) {
- url = url.substring(0, url.length() - 1);
- }
-
+
+ url = normalizeUrlSuffix(url);
}
return (url != null ? url : "");
}
+
+
+ private String normalizeUrlSuffix(String url) {
+ if (url.endsWith("/")) {
+ url = url.substring(0, url.length() - 1);
+ }
+ url = trimUrlWebdav(url);
+ return url;
+ }
// TODO remove, if possible
@@ -1303,7 +1338,6 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
@SuppressWarnings("unchecked")
Map tokens = (Map)(result.getData().get(0));
mAuthToken = tokens.get(OAuth2Constants.KEY_ACCESS_TOKEN);
- //mAuthToken = ((OAuth2GetAccessToken)operation).getResultTokenMap().get(OAuth2Constants.KEY_ACCESS_TOKEN);
Log_OC.d(TAG, "Got ACCESS TOKEN: " + mAuthToken);
accessRootFolderRemoteOperation("", "");
@@ -1362,7 +1396,7 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
showRefreshButton(true);
mOkButton.setEnabled(false);
- // very special case (TODO: move to a common place for all the remote operations) (dangerous here?)
+ // very special case (TODO: move to a common place for all the remote operations)
if (result.getCode() == ResultCode.SSL_RECOVERABLE_PEER_UNVERIFIED) {
showUntrustedCertDialog(result);
}
@@ -1378,23 +1412,27 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
/**
- * Sets the proper response to get that the Account Authenticator that started this activity saves
- * a new authorization token for mAccount.
+ * Sets the proper response to get that the Account Authenticator that started this activity
+ * saves a new authorization token for mAccount.
*/
private void updateToken() {
Bundle response = new Bundle();
response.putString(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);
response.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccount.type);
- if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).equals(mAuthTokenType)) {
+ if (AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).
+ equals(mAuthTokenType)) {
response.putString(AccountManager.KEY_AUTHTOKEN, mAuthToken);
- // the next line is necessary; by now, notifications are calling directly to the AuthenticatorActivity to update, without AccountManager intervention
+ // the next line is necessary, notifications are calling directly to the
+ // AuthenticatorActivity to update, without AccountManager intervention
mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
- } else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType)) {
+ } else if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).
+ equals(mAuthTokenType)) {
response.putString(AccountManager.KEY_AUTHTOKEN, mAuthToken);
- // the next line is necessary; by now, notifications are calling directly to the AuthenticatorActivity to update, without AccountManager intervention
+ // the next line is necessary; by now, notifications are calling directly to the
+ // AuthenticatorActivity to update, without AccountManager intervention
mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
} else {
@@ -1415,8 +1453,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
*/
private boolean createAccount() {
/// create and save new ownCloud account
- boolean isOAuth = AccountTypeUtils.getAuthTokenTypeAccessToken(MainApp.getAccountType()).equals(mAuthTokenType);
- boolean isSaml = AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType);
+ boolean isOAuth = AccountTypeUtils.
+ getAuthTokenTypeAccessToken(MainApp.getAccountType()).equals(mAuthTokenType);
+ boolean isSaml = AccountTypeUtils.
+ getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType);
Uri uri = Uri.parse(mServerInfo.mBaseUrl);
String username = mUsernameInput.getText().toString().trim();
@@ -1438,9 +1478,12 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
mAccount = newAccount;
if (isOAuth || isSaml) {
- mAccountMgr.addAccountExplicitly(mAccount, "", null); // with external authorizations, the password is never input in the app
+ // with external authorizations, the password is never input in the app
+ mAccountMgr.addAccountExplicitly(mAccount, "", null);
} else {
- mAccountMgr.addAccountExplicitly(mAccount, mPasswordInput.getText().toString(), null);
+ mAccountMgr.addAccountExplicitly(
+ mAccount, mPasswordInput.getText().toString(), null
+ );
}
/// add the new account as default in preferences, if there is none already
@@ -1453,7 +1496,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
}
/// prepare result to return to the Authenticator
- // TODO check again what the Authenticator makes with it; probably has the same effect as addAccountExplicitly, but it's not well done
+ // TODO check again what the Authenticator makes with it; probably has the same
+ // effect as addAccountExplicitly, but it's not well done
final Intent intent = new Intent();
intent.putExtra(AccountManager.KEY_ACCOUNT_TYPE, MainApp.getAccountType());
intent.putExtra(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);
@@ -1463,9 +1507,14 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
if (isOAuth || isSaml) {
mAccountMgr.setAuthToken(mAccount, mAuthTokenType, mAuthToken);
}
- /// add user data to the new account; TODO probably can be done in the last parameter addAccountExplicitly, or in KEY_USERDATA
- mAccountMgr.setUserData(mAccount, Constants.KEY_OC_VERSION, mServerInfo.mVersion.getVersion());
- mAccountMgr.setUserData(mAccount, Constants.KEY_OC_BASE_URL, mServerInfo.mBaseUrl);
+ /// add user data to the new account; TODO probably can be done in the last parameter
+ // addAccountExplicitly, or in KEY_USERDATA
+ mAccountMgr.setUserData(
+ mAccount, Constants.KEY_OC_VERSION, mServerInfo.mVersion.getVersion()
+ );
+ mAccountMgr.setUserData(
+ mAccount, Constants.KEY_OC_BASE_URL, mServerInfo.mBaseUrl
+ );
if (isSaml) {
mAccountMgr.setUserData(mAccount, Constants.KEY_SUPPORTS_SAML_WEB_SSO, "TRUE");
@@ -1487,7 +1536,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
* @param view 'Account register' button
*/
public void onRegisterClick(View view) {
- Intent register = new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.welcome_link_url)));
+ Intent register = new Intent(
+ Intent.ACTION_VIEW, Uri.parse(getString(R.string.welcome_link_url))
+ );
setResult(RESULT_CANCELED);
startActivity(register);
}
@@ -1587,18 +1638,21 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
/**
* Called when the 'action' button in an IME is pressed ('enter' in software keyboard).
*
- * Used to trigger the authentication check when the user presses 'enter' after writing the password,
- * or to throw the server test when the only field on screen is the URL input field.
+ * Used to trigger the authentication check when the user presses 'enter' after writing the
+ * password, or to throw the server test when the only field on screen is the URL input field.
*/
@Override
public boolean onEditorAction(TextView inputField, int actionId, KeyEvent event) {
- if (actionId == EditorInfo.IME_ACTION_DONE && inputField != null && inputField.equals(mPasswordInput)) {
+ if (actionId == EditorInfo.IME_ACTION_DONE && inputField != null &&
+ inputField.equals(mPasswordInput)) {
if (mOkButton.isEnabled()) {
mOkButton.performClick();
}
- } else if (actionId == EditorInfo.IME_ACTION_NEXT && inputField != null && inputField.equals(mHostUrlInput)) {
- if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType)) {
+ } else if (actionId == EditorInfo.IME_ACTION_NEXT && inputField != null &&
+ inputField.equals(mHostUrlInput)) {
+ if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).
+ equals(mAuthTokenType)) {
checkOcServer();
}
}
@@ -1626,8 +1680,10 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
final int x = (int) event.getX();
final int y = (int) event.getY();
final Rect bounds = rightDrawable.getBounds();
- if (x >= (view.getRight() - bounds.width() - fuzz) && x <= (view.getRight() - view.getPaddingRight() + fuzz)
- && y >= (view.getPaddingTop() - fuzz) && y <= (view.getHeight() - view.getPaddingBottom()) + fuzz) {
+ if ( x >= (view.getRight() - bounds.width() - fuzz) &&
+ x <= (view.getRight() - view.getPaddingRight() + fuzz) &&
+ y >= (view.getPaddingTop() - fuzz) &&
+ y <= (view.getHeight() - view.getPaddingBottom()) + fuzz) {
return onDrawableTouch(event);
}
@@ -1676,7 +1732,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
@Override
public boolean onTouchEvent(MotionEvent event) {
- if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).equals(mAuthTokenType) &&
+ if (AccountTypeUtils.getAuthTokenTypeSamlSessionCookie(MainApp.getAccountType()).
+ equals(mAuthTokenType) &&
mHostUrlInput.hasFocus() && event.getAction() == MotionEvent.ACTION_DOWN) {
checkOcServer();
}
@@ -1687,13 +1744,16 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
/**
* Show untrusted cert dialog
*/
- public void showUntrustedCertDialog(X509Certificate x509Certificate, SslError error, SslErrorHandler handler) {
+ public void showUntrustedCertDialog(
+ X509Certificate x509Certificate, SslError error, SslErrorHandler handler
+ ) {
// Show a dialog with the certificate info
SslUntrustedCertDialog dialog = null;
if (x509Certificate == null) {
dialog = SslUntrustedCertDialog.newInstanceForEmptySslError(error, handler);
} else {
- dialog = SslUntrustedCertDialog.newInstanceForFullSslError(x509Certificate, error, handler);
+ dialog = SslUntrustedCertDialog.
+ newInstanceForFullSslError(x509Certificate, error, handler);
}
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
@@ -1707,7 +1767,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
*/
private void showUntrustedCertDialog(RemoteOperationResult result) {
// Show a dialog with the certificate info
- SslUntrustedCertDialog dialog = SslUntrustedCertDialog.newInstanceForFullSslError((CertificateCombinedException)result.getException());
+ SslUntrustedCertDialog dialog = SslUntrustedCertDialog.
+ newInstanceForFullSslError((CertificateCombinedException)result.getException());
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.addToBackStack(null);
@@ -1721,7 +1782,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
public void onSavedCertificate() {
Fragment fd = getSupportFragmentManager().findFragmentByTag(SAML_DIALOG_TAG);
if (fd == null) {
- // if SAML dialog is not shown, the SslDialog was shown due to an SSL error in the server check
+ // if SAML dialog is not shown,
+ // the SslDialog was shown due to an SSL error in the server check
checkOcServer();
}
}
@@ -1771,7 +1833,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
@Override
public void onServiceConnected(ComponentName component, IBinder service) {
- if (component.equals(new ComponentName(AuthenticatorActivity.this, OperationsService.class))) {
+ if (component.equals(
+ new ComponentName(AuthenticatorActivity.this, OperationsService.class)
+ )) {
//Log_OC.wtf(TAG, "Operations service connected");
mOperationsServiceBinder = (OperationsServiceBinder) service;
@@ -1785,7 +1849,9 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
@Override
public void onServiceDisconnected(ComponentName component) {
- if (component.equals(new ComponentName(AuthenticatorActivity.this, OperationsService.class))) {
+ if (component.equals(
+ new ComponentName(AuthenticatorActivity.this, OperationsService.class)
+ )) {
Log_OC.e(TAG, "Operations service crashed");
mOperationsServiceBinder = null;
}
@@ -1801,7 +1867,8 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
public void createAuthenticationDialog(WebView webView, HttpAuthHandler handler) {
// Show a dialog with the certificate info
- CredentialsDialogFragment dialog = CredentialsDialogFragment.newInstanceForCredentials(webView, handler);
+ CredentialsDialogFragment dialog =
+ CredentialsDialogFragment.newInstanceForCredentials(webView, handler);
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.addToBackStack(null);
@@ -1809,7 +1876,11 @@ SsoWebViewClientListener, OnSslUntrustedCertListener {
dialog.show(ft, CREDENTIALS_DIALOG_TAG);
if (!mIsFirstAuthAttempt) {
- Toast.makeText(getApplicationContext(), getText(R.string.saml_authentication_wrong_pass), Toast.LENGTH_LONG).show();
+ Toast.makeText(
+ getApplicationContext(),
+ getText(R.string.saml_authentication_wrong_pass),
+ Toast.LENGTH_LONG
+ ).show();
} else {
mIsFirstAuthAttempt = false;
}
diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java
index 795004a166..5b1bef1b5d 100644
--- a/src/com/owncloud/android/datamodel/FileDataStorageManager.java
+++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java
@@ -151,7 +151,7 @@ public class FileDataStorageManager {
public Vector getFolderImages(OCFile folder) {
Vector ret = new Vector();
if (folder != null) {
- // TODO better implementation, filtering in the access to database (if possible) instead of here
+ // TODO better implementation, filtering in the access to database instead of here
Vector tmp = getFolderContent(folder);
OCFile current = null;
for (int i=0; i updatedFiles, Collection filesToRemove) {
+ public void saveFolder(
+ OCFile folder, Collection updatedFiles, Collection filesToRemove
+ ) {
- Log_OC.d(TAG, "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size() + " children and " + filesToRemove.size() + " files to remove");
+ Log_OC.d(TAG, "Saving folder " + folder.getRemotePath() + " with " + updatedFiles.size()
+ + " children and " + filesToRemove.size() + " files to remove");
- ArrayList operations = new ArrayList(updatedFiles.size());
+ ArrayList operations =
+ new ArrayList(updatedFiles.size());
// prepare operations to insert or update files to save in the given folder
for (OCFile file : updatedFiles) {
ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
- cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
+ cv.put(
+ ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
+ file.getModificationTimestampAtLastSyncForData()
+ );
cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
@@ -302,29 +312,40 @@ public class FileDataStorageManager {
} else {
// adding a new file
- operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
+ operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).
+ withValues(cv).build());
}
}
// prepare operations to remove files in the given folder
- String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
+ String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " +
+ ProviderTableMeta.FILE_PATH + "=?";
String [] whereArgs = null;
for (OCFile file : filesToRemove) {
if (file.getParentId() == folder.getFileId()) {
whereArgs = new String[]{mAccount.name, file.getRemotePath()};
//Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, "" + file.getFileId());
if (file.isFolder()) {
- operations.add(ContentProviderOperation
- .newDelete(ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_DIR, file.getFileId())).withSelection(where, whereArgs)
- .build());
- // TODO remove local folder
+ operations.add(ContentProviderOperation.newDelete(
+ ContentUris.withAppendedId(
+ ProviderTableMeta.CONTENT_URI_DIR, file.getFileId()
+ )
+ ).withSelection(where, whereArgs).build());
+
+ File localFolder =
+ new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
+ if (localFolder.exists()) {
+ removeLocalFolder(localFolder);
+ }
} else {
- operations.add(ContentProviderOperation
- .newDelete(ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, file.getFileId())).withSelection(where, whereArgs)
- .build());
+ operations.add(ContentProviderOperation.newDelete(
+ ContentUris.withAppendedId(
+ ProviderTableMeta.CONTENT_URI_FILE, file.getFileId()
+ )
+ ).withSelection(where, whereArgs).build());
+
if (file.isDown()) {
new File(file.getStoragePath()).delete();
- // TODO move the deletion of local contents after success of deletions
}
}
}
@@ -333,9 +354,12 @@ public class FileDataStorageManager {
// update metadata of folder
ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.FILE_MODIFIED, folder.getModificationTimestamp());
- cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, folder.getModificationTimestampAtLastSyncForData());
+ cv.put(
+ ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
+ folder.getModificationTimestampAtLastSyncForData()
+ );
cv.put(ProviderTableMeta.FILE_CREATION, folder.getCreationTimestamp());
- cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, 0); // FileContentProvider calculates the right size
+ cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, 0);
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, folder.getMimetype());
cv.put(ProviderTableMeta.FILE_NAME, folder.getFileName());
cv.put(ProviderTableMeta.FILE_PARENT, folder.getParentId());
@@ -409,18 +433,21 @@ public class FileDataStorageManager {
// Log_OC.d(TAG, "Updating size of " + id);
// if (getContentResolver() != null) {
// getContentResolver().update(ProviderTableMeta.CONTENT_URI_DIR,
-// new ContentValues(), // won't be used, but cannot be null; crashes in KLP
+// new ContentValues(),
+ // won't be used, but cannot be null; crashes in KLP
// ProviderTableMeta._ID + "=?",
// new String[] { String.valueOf(id) });
// } else {
// try {
// getContentProviderClient().update(ProviderTableMeta.CONTENT_URI_DIR,
-// new ContentValues(), // won't be used, but cannot be null; crashes in KLP
+// new ContentValues(),
+ // won't be used, but cannot be null; crashes in KLP
// ProviderTableMeta._ID + "=?",
// new String[] { String.valueOf(id) });
//
// } catch (RemoteException e) {
-// Log_OC.e(TAG, "Exception in update of folder size through compatibility patch " + e.getMessage());
+// Log_OC.e(
+// TAG, "Exception in update of folder size through compatibility patch " + e.getMessage());
// }
// }
// } else {
@@ -437,9 +464,12 @@ public class FileDataStorageManager {
} else {
if (removeDBData) {
- //Uri file_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, ""+file.getFileId());
- Uri file_uri = ContentUris.withAppendedId(ProviderTableMeta.CONTENT_URI_FILE, file.getFileId());
- String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
+ Uri file_uri = ContentUris.withAppendedId(
+ ProviderTableMeta.CONTENT_URI_FILE,
+ file.getFileId()
+ );
+ String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " +
+ ProviderTableMeta.FILE_PATH + "=?";
String [] whereArgs = new String[]{mAccount.name, file.getRemotePath()};
int deleted = 0;
if (getContentProviderClient() != null) {
@@ -481,8 +511,10 @@ public class FileDataStorageManager {
}
private boolean removeFolderInDb(OCFile folder) {
- Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, ""+ folder.getFileId()); // URI for recursive deletion
- String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
+ Uri folder_uri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_DIR, "" +
+ folder.getFileId()); // URI for recursive deletion
+ String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=?" + " AND " +
+ ProviderTableMeta.FILE_PATH + "=?";
String [] whereArgs = new String[]{mAccount.name, folder.getRemotePath()};
int deleted = 0;
if (getContentProviderClient() != null) {
@@ -552,43 +584,67 @@ public class FileDataStorageManager {
public void moveFolder(OCFile folder, String newPath) {
// TODO check newPath
- if (folder != null && folder.isFolder() && folder.fileExists() && !OCFile.ROOT_PATH.equals(folder.getFileName())) {
+ if ( folder != null && folder.isFolder() &&
+ folder.fileExists() && !OCFile.ROOT_PATH.equals(folder.getFileName())
+ ) {
/// 1. get all the descendants of 'dir' in a single QUERY (including 'dir')
Cursor c = null;
if (getContentProviderClient() != null) {
try {
- c = getContentProviderClient().query(ProviderTableMeta.CONTENT_URI,
- null,
- ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ? ",
- new String[] { mAccount.name, folder.getRemotePath() + "%" }, ProviderTableMeta.FILE_PATH + " ASC ");
+ c = getContentProviderClient().query (
+ ProviderTableMeta.CONTENT_URI,
+ null,
+ ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
+ ProviderTableMeta.FILE_PATH + " LIKE ? ",
+ new String[] { mAccount.name, folder.getRemotePath() + "%" },
+ ProviderTableMeta.FILE_PATH + " ASC "
+ );
} catch (RemoteException e) {
Log_OC.e(TAG, e.getMessage());
}
} else {
- c = getContentResolver().query(ProviderTableMeta.CONTENT_URI,
- null,
- ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PATH + " LIKE ? ",
- new String[] { mAccount.name, folder.getRemotePath() + "%" }, ProviderTableMeta.FILE_PATH + " ASC ");
+ c = getContentResolver().query (
+ ProviderTableMeta.CONTENT_URI,
+ null,
+ ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
+ ProviderTableMeta.FILE_PATH + " LIKE ? ",
+ new String[] { mAccount.name, folder.getRemotePath() + "%" },
+ ProviderTableMeta.FILE_PATH + " ASC "
+ );
}
/// 2. prepare a batch of update operations to change all the descendants
- ArrayList operations = new ArrayList(c.getCount());
+ ArrayList operations =
+ new ArrayList(c.getCount());
int lengthOfOldPath = folder.getRemotePath().length();
String defaultSavePath = FileStorageUtils.getSavePath(mAccount.name);
int lengthOfOldStoragePath = defaultSavePath.length() + lengthOfOldPath;
if (c.moveToFirst()) {
do {
- ContentValues cv = new ContentValues(); // don't take the constructor out of the loop and clear the object
+ ContentValues cv = new ContentValues(); // keep the constructor in the loop
OCFile child = createFileInstance(c);
- cv.put(ProviderTableMeta.FILE_PATH, newPath + child.getRemotePath().substring(lengthOfOldPath));
- if (child.getStoragePath() != null && child.getStoragePath().startsWith(defaultSavePath)) {
- cv.put(ProviderTableMeta.FILE_STORAGE_PATH, defaultSavePath + newPath + child.getStoragePath().substring(lengthOfOldStoragePath));
+ cv.put(
+ ProviderTableMeta.FILE_PATH,
+ newPath + child.getRemotePath().substring(lengthOfOldPath)
+ );
+ if ( child.getStoragePath() != null &&
+ child.getStoragePath().startsWith(defaultSavePath) ) {
+ cv.put(
+ ProviderTableMeta.FILE_STORAGE_PATH,
+ defaultSavePath + newPath +
+ child.getStoragePath().substring(lengthOfOldStoragePath)
+ );
}
- operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+ operations.add(
+ ContentProviderOperation.
+ newUpdate(ProviderTableMeta.CONTENT_URI).
withValues(cv).
- withSelection( ProviderTableMeta._ID + "=?",
- new String[] { String.valueOf(child.getFileId()) })
- .build());
+ withSelection(
+ ProviderTableMeta._ID + "=?",
+ new String[] { String.valueOf(child.getFileId()) }
+ ).
+ build()
+ );
} while (c.moveToNext());
}
c.close();
@@ -603,10 +659,12 @@ public class FileDataStorageManager {
}
} catch (OperationApplicationException e) {
- Log_OC.e(TAG, "Fail to update descendants of " + folder.getFileId() + " in database", e);
+ Log_OC.e(TAG, "Fail to update descendants of " +
+ folder.getFileId() + " in database", e);
} catch (RemoteException e) {
- Log_OC.e(TAG, "Fail to update desendants of " + folder.getFileId() + " in database", e);
+ Log_OC.e(TAG, "Fail to update desendants of " +
+ folder.getFileId() + " in database", e);
}
}
@@ -851,7 +909,9 @@ public class FileDataStorageManager {
file.setStoragePath(c.getString(c
.getColumnIndex(ProviderTableMeta.FILE_STORAGE_PATH)));
if (file.getStoragePath() == null) {
- // try to find existing file and bind it with current account; - with the current update of SynchronizeFolderOperation, this won't be necessary anymore after a full synchronization of the account
+ // try to find existing file and bind it with current account;
+ // with the current update of SynchronizeFolderOperation, this won't be
+ // necessary anymore after a full synchronization of the account
File f = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, file));
if (f.exists()) {
file.setStoragePath(f.getAbsolutePath());
@@ -930,13 +990,16 @@ public class FileDataStorageManager {
cv.put(ProviderTableMeta.OCSHARES_SHARED_DATE, share.getSharedDate());
cv.put(ProviderTableMeta.OCSHARES_EXPIRATION_DATE, share.getExpirationDate());
cv.put(ProviderTableMeta.OCSHARES_TOKEN, share.getToken());
- cv.put(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME, share.getSharedWithDisplayName());
+ cv.put(
+ ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME,
+ share.getSharedWithDisplayName()
+ );
cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
cv.put(ProviderTableMeta.OCSHARES_ACCOUNT_OWNER, mAccount.name);
- if (shareExists(share.getIdRemoteShared())) { // for renamed files; no more delete and create
+ if (shareExists(share.getIdRemoteShared())) { // for renamed files
overriden = true;
if (getContentResolver() != null) {
@@ -1038,7 +1101,9 @@ public class FileDataStorageManager {
share.setIsFolder(c.getInt(
c.getColumnIndex(ProviderTableMeta.OCSHARES_IS_DIRECTORY)) == 1 ? true : false);
share.setUserId(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_USER_ID)));
- share.setIdRemoteShared(c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED)));
+ share.setIdRemoteShared(
+ c.getLong(c.getColumnIndex(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED))
+ );
}
return share;
@@ -1090,7 +1155,9 @@ public class FileDataStorageManager {
} else {
try {
- getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
+ getContentProviderClient().update(
+ ProviderTableMeta.CONTENT_URI, cv, where, whereArgs
+ );
} catch (RemoteException e) {
Log_OC.e(TAG, "Exception in cleanSharedFiles" + e.getMessage());
@@ -1102,7 +1169,8 @@ public class FileDataStorageManager {
ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, false);
cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, "");
- String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " + ProviderTableMeta.FILE_PARENT + "=?";
+ String where = ProviderTableMeta.FILE_ACCOUNT_OWNER + "=? AND " +
+ ProviderTableMeta.FILE_PARENT + "=?";
String [] whereArgs = new String[] { mAccount.name , String.valueOf(folder.getFileId()) };
if (getContentResolver() != null) {
@@ -1110,7 +1178,9 @@ public class FileDataStorageManager {
} else {
try {
- getContentProviderClient().update(ProviderTableMeta.CONTENT_URI, cv, where, whereArgs);
+ getContentProviderClient().update(
+ ProviderTableMeta.CONTENT_URI, cv, where, whereArgs
+ );
} catch (RemoteException e) {
Log_OC.e(TAG, "Exception in cleanSharedFilesInFolder " + e.getMessage());
@@ -1127,7 +1197,9 @@ public class FileDataStorageManager {
} else {
try {
- getContentProviderClient().delete(ProviderTableMeta.CONTENT_URI_SHARE, where, whereArgs);
+ getContentProviderClient().delete(
+ ProviderTableMeta.CONTENT_URI_SHARE, where, whereArgs
+ );
} catch (RemoteException e) {
Log_OC.e(TAG, "Exception in cleanShares" + e.getMessage());
@@ -1138,7 +1210,8 @@ public class FileDataStorageManager {
public void saveShares(Collection shares) {
cleanShares();
if (shares != null) {
- ArrayList operations = new ArrayList(shares.size());
+ ArrayList operations =
+ new ArrayList(shares.size());
// prepare operations to insert or update files to save in the given folder
for (OCShare share : shares) {
@@ -1152,7 +1225,10 @@ public class FileDataStorageManager {
cv.put(ProviderTableMeta.OCSHARES_SHARED_DATE, share.getSharedDate());
cv.put(ProviderTableMeta.OCSHARES_EXPIRATION_DATE, share.getExpirationDate());
cv.put(ProviderTableMeta.OCSHARES_TOKEN, share.getToken());
- cv.put(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME, share.getSharedWithDisplayName());
+ cv.put(
+ ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME,
+ share.getSharedWithDisplayName()
+ );
cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
@@ -1160,15 +1236,23 @@ public class FileDataStorageManager {
if (shareExists(share.getIdRemoteShared())) {
// updating an existing file
- operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE).
+ operations.add(
+ ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE).
withValues(cv).
- withSelection( ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
- new String[] { String.valueOf(share.getIdRemoteShared()) })
- .build());
+ withSelection(
+ ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
+ new String[] { String.valueOf(share.getIdRemoteShared()) }
+ ).
+ build()
+ );
} else {
// adding a new file
- operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI_SHARE).withValues(cv).build());
+ operations.add(
+ ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI_SHARE).
+ withValues(cv).
+ build()
+ );
}
}
@@ -1176,10 +1260,13 @@ public class FileDataStorageManager {
if (operations.size() > 0) {
@SuppressWarnings("unused")
ContentProviderResult[] results = null;
- Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
+ Log_OC.d(TAG, "Sending " + operations.size() +
+ " operations to FileContentProvider");
try {
if (getContentResolver() != null) {
- results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
+ results = getContentResolver().applyBatch(
+ MainApp.getAuthority(), operations
+ );
} else {
results = getContentProviderClient().applyBatch(operations);
@@ -1200,13 +1287,17 @@ public class FileDataStorageManager {
cleanSharedFiles();
if (sharedFiles != null) {
- ArrayList operations = new ArrayList(sharedFiles.size());
+ ArrayList operations =
+ new ArrayList(sharedFiles.size());
// prepare operations to insert or update files to save in the given folder
for (OCFile file : sharedFiles) {
ContentValues cv = new ContentValues();
cv.put(ProviderTableMeta.FILE_MODIFIED, file.getModificationTimestamp());
- cv.put(ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA, file.getModificationTimestampAtLastSyncForData());
+ cv.put(
+ ProviderTableMeta.FILE_MODIFIED_AT_LAST_SYNC_FOR_DATA,
+ file.getModificationTimestampAtLastSyncForData()
+ );
cv.put(ProviderTableMeta.FILE_CREATION, file.getCreationTimestamp());
cv.put(ProviderTableMeta.FILE_CONTENT_LENGTH, file.getFileLength());
cv.put(ProviderTableMeta.FILE_CONTENT_TYPE, file.getMimetype());
@@ -1218,27 +1309,40 @@ public class FileDataStorageManager {
}
cv.put(ProviderTableMeta.FILE_ACCOUNT_OWNER, mAccount.name);
cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE, file.getLastSyncDateForProperties());
- cv.put(ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA, file.getLastSyncDateForData());
+ cv.put(
+ ProviderTableMeta.FILE_LAST_SYNC_DATE_FOR_DATA,
+ file.getLastSyncDateForData()
+ );
cv.put(ProviderTableMeta.FILE_KEEP_IN_SYNC, file.keepInSync() ? 1 : 0);
cv.put(ProviderTableMeta.FILE_ETAG, file.getEtag());
cv.put(ProviderTableMeta.FILE_SHARE_BY_LINK, file.isShareByLink() ? 1 : 0);
cv.put(ProviderTableMeta.FILE_PUBLIC_LINK, file.getPublicLink());
cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions());
cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId());
- cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail() ? 1 : 0);
+ cv.put(
+ ProviderTableMeta.FILE_UPDATE_THUMBNAIL,
+ file.needsUpdateThumbnail() ? 1 : 0
+ );
boolean existsByPath = fileExists(file.getRemotePath());
if (existsByPath || fileExists(file.getFileId())) {
// updating an existing file
- operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
+ operations.add(
+ ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI).
withValues(cv).
- withSelection( ProviderTableMeta._ID + "=?",
- new String[] { String.valueOf(file.getFileId()) })
- .build());
+ withSelection(
+ ProviderTableMeta._ID + "=?",
+ new String[] { String.valueOf(file.getFileId()) }
+ ).build()
+ );
} else {
// adding a new file
- operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).withValues(cv).build());
+ operations.add(
+ ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI).
+ withValues(cv).
+ build()
+ );
}
}
@@ -1246,10 +1350,13 @@ public class FileDataStorageManager {
if (operations.size() > 0) {
@SuppressWarnings("unused")
ContentProviderResult[] results = null;
- Log_OC.d(TAG, "Sending " + operations.size() + " operations to FileContentProvider");
+ Log_OC.d(TAG, "Sending " + operations.size() +
+ " operations to FileContentProvider");
try {
if (getContentResolver() != null) {
- results = getContentResolver().applyBatch(MainApp.getAuthority(), operations);
+ results = getContentResolver().applyBatch(
+ MainApp.getAuthority(), operations
+ );
} else {
results = getContentProviderClient().applyBatch(operations);
@@ -1268,7 +1375,8 @@ public class FileDataStorageManager {
public void removeShare(OCShare share){
Uri share_uri = ProviderTableMeta.CONTENT_URI_SHARE;
- String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" + " AND " + ProviderTableMeta.FILE_PATH + "=?";
+ String where = ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?" + " AND " +
+ ProviderTableMeta.FILE_PATH + "=?";
String [] whereArgs = new String[]{mAccount.name, share.getPath()};
if (getContentProviderClient() != null) {
try {
@@ -1325,7 +1433,10 @@ public class FileDataStorageManager {
cv.put(ProviderTableMeta.OCSHARES_SHARED_DATE, share.getSharedDate());
cv.put(ProviderTableMeta.OCSHARES_EXPIRATION_DATE, share.getExpirationDate());
cv.put(ProviderTableMeta.OCSHARES_TOKEN, share.getToken());
- cv.put(ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME, share.getSharedWithDisplayName());
+ cv.put(
+ ProviderTableMeta.OCSHARES_SHARE_WITH_DISPLAY_NAME,
+ share.getSharedWithDisplayName()
+ );
cv.put(ProviderTableMeta.OCSHARES_IS_DIRECTORY, share.isFolder() ? 1 : 0);
cv.put(ProviderTableMeta.OCSHARES_USER_ID, share.getUserId());
cv.put(ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED, share.getIdRemoteShared());
@@ -1334,7 +1445,8 @@ public class FileDataStorageManager {
/*
if (shareExists(share.getIdRemoteShared())) {
// updating an existing share resource
- operations.add(ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE).
+ operations.add(
+ ContentProviderOperation.newUpdate(ProviderTableMeta.CONTENT_URI_SHARE).
withValues(cv).
withSelection( ProviderTableMeta.OCSHARES_ID_REMOTE_SHARED + "=?",
new String[] { String.valueOf(share.getIdRemoteShared()) })
@@ -1343,7 +1455,11 @@ public class FileDataStorageManager {
} else {
*/
// adding a new share resource
- operations.add(ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI_SHARE).withValues(cv).build());
+ operations.add(
+ ContentProviderOperation.newInsert(ProviderTableMeta.CONTENT_URI_SHARE).
+ withValues(cv).
+ build()
+ );
//}
}
}
@@ -1372,18 +1488,23 @@ public class FileDataStorageManager {
}
- private ArrayList prepareRemoveSharesInFolder(OCFile folder, ArrayList preparedOperations) {
+ private ArrayList prepareRemoveSharesInFolder(
+ OCFile folder, ArrayList preparedOperations
+ ) {
if (folder != null) {
- String where = ProviderTableMeta.OCSHARES_PATH + "=?" + " AND " + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
+ String where = ProviderTableMeta.OCSHARES_PATH + "=?" + " AND "
+ + ProviderTableMeta.OCSHARES_ACCOUNT_OWNER + "=?";
String [] whereArgs = new String[]{ "", mAccount.name };
Vector files = getFolderContent(folder);
for (OCFile file : files) {
whereArgs[0] = file.getRemotePath();
- preparedOperations.add(ContentProviderOperation.newDelete(ProviderTableMeta.CONTENT_URI_SHARE)
- .withSelection(where, whereArgs)
- .build());
+ preparedOperations.add(
+ ContentProviderOperation.newDelete(ProviderTableMeta.CONTENT_URI_SHARE).
+ withSelection(where, whereArgs).
+ build()
+ );
}
}
return preparedOperations;
diff --git a/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java b/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
new file mode 100644
index 0000000000..e75404ef3b
--- /dev/null
+++ b/src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java
@@ -0,0 +1,265 @@
+/* ownCloud Android client application
+ * Copyright (C) 2012-2014 ownCloud Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * 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 com.owncloud.android.datamodel;
+
+import java.io.File;
+import java.lang.ref.WeakReference;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.media.ThumbnailUtils;
+import android.os.AsyncTask;
+import android.util.TypedValue;
+import android.widget.ImageView;
+
+import com.owncloud.android.MainApp;
+import com.owncloud.android.lib.common.utils.Log_OC;
+import com.owncloud.android.ui.adapter.DiskLruImageCache;
+import com.owncloud.android.utils.BitmapUtils;
+import com.owncloud.android.utils.DisplayUtils;
+
+/**
+ * Manager for concurrent access to thumbnails cache.
+ *
+ * @author Tobias Kaminsky
+ * @author David A. Velasco
+ */
+public class ThumbnailsCacheManager {
+
+ private static final String TAG = ThumbnailsCacheManager.class.getSimpleName();
+
+ private static final String CACHE_FOLDER = "thumbnailCache";
+
+ private static final Object mThumbnailsDiskCacheLock = new Object();
+ private static DiskLruImageCache mThumbnailCache = null;
+ private static boolean mThumbnailCacheStarting = true;
+
+ private static final int DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB
+ private static final CompressFormat mCompressFormat = CompressFormat.JPEG;
+ private static final int mCompressQuality = 70;
+
+ public static Bitmap mDefaultImg =
+ BitmapFactory.decodeResource(
+ MainApp.getAppContext().getResources(),
+ DisplayUtils.getResourceId("image/png", "default.png")
+ );
+
+
+ public static class InitDiskCacheTask extends AsyncTask {
+ @Override
+ protected Void doInBackground(File... params) {
+ synchronized (mThumbnailsDiskCacheLock) {
+ mThumbnailCacheStarting = true;
+ if (mThumbnailCache == null) {
+ try {
+ // Check if media is mounted or storage is built-in, if so,
+ // try and use external cache dir; otherwise use internal cache dir
+ final String cachePath =
+ MainApp.getAppContext().getExternalCacheDir().getPath() +
+ File.separator + CACHE_FOLDER;
+ Log_OC.d(TAG, "create dir: " + cachePath);
+ final File diskCacheDir = new File(cachePath);
+ mThumbnailCache = new DiskLruImageCache(
+ diskCacheDir,
+ DISK_CACHE_SIZE,
+ mCompressFormat,
+ mCompressQuality
+ );
+ } catch (Exception e) {
+ Log_OC.d(TAG, "Thumbnail cache could not be opened ", e);
+ mThumbnailCache = null;
+ }
+ }
+ mThumbnailCacheStarting = false; // Finished initialization
+ mThumbnailsDiskCacheLock.notifyAll(); // Wake any waiting threads
+ }
+ return null;
+ }
+ }
+
+
+ public static void addBitmapToCache(String key, Bitmap bitmap) {
+ synchronized (mThumbnailsDiskCacheLock) {
+ if (mThumbnailCache != null) {
+ mThumbnailCache.put(key, bitmap);
+ }
+ }
+ }
+
+
+ public static Bitmap getBitmapFromDiskCache(String key) {
+ synchronized (mThumbnailsDiskCacheLock) {
+ // Wait while disk cache is started from background thread
+ while (mThumbnailCacheStarting) {
+ try {
+ mThumbnailsDiskCacheLock.wait();
+ } catch (InterruptedException e) {}
+ }
+ if (mThumbnailCache != null) {
+ return (Bitmap) mThumbnailCache.getBitmap(key);
+ }
+ }
+ return null;
+ }
+
+
+ public static boolean cancelPotentialWork(OCFile file, ImageView imageView) {
+ final ThumbnailGenerationTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
+
+ if (bitmapWorkerTask != null) {
+ final OCFile bitmapData = bitmapWorkerTask.mFile;
+ // If bitmapData is not yet set or it differs from the new data
+ if (bitmapData == null || bitmapData != file) {
+ // Cancel previous task
+ bitmapWorkerTask.cancel(true);
+ } else {
+ // The same work is already in progress
+ return false;
+ }
+ }
+ // No task associated with the ImageView, or an existing task was cancelled
+ return true;
+ }
+
+ public static ThumbnailGenerationTask getBitmapWorkerTask(ImageView imageView) {
+ if (imageView != null) {
+ final Drawable drawable = imageView.getDrawable();
+ if (drawable instanceof AsyncDrawable) {
+ final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+ return asyncDrawable.getBitmapWorkerTask();
+ }
+ }
+ return null;
+ }
+
+ public static class ThumbnailGenerationTask extends AsyncTask {
+ private final WeakReference mImageViewReference;
+ private OCFile mFile;
+ private FileDataStorageManager mStorageManager;
+
+ public ThumbnailGenerationTask(ImageView imageView, FileDataStorageManager storageManager) {
+ // Use a WeakReference to ensure the ImageView can be garbage collected
+ mImageViewReference = new WeakReference(imageView);
+ if (storageManager == null)
+ throw new IllegalArgumentException("storageManager must not be NULL");
+ mStorageManager = storageManager;
+ }
+
+ // Decode image in background.
+ @Override
+ protected Bitmap doInBackground(OCFile... params) {
+ Bitmap thumbnail = null;
+
+ try {
+ mFile = params[0];
+ final String imageKey = String.valueOf(mFile.getRemoteId());
+
+ // Check disk cache in background thread
+ thumbnail = getBitmapFromDiskCache(imageKey);
+
+ // Not found in disk cache
+ if (thumbnail == null || mFile.needsUpdateThumbnail()) {
+ // Converts dp to pixel
+ Resources r = MainApp.getAppContext().getResources();
+ int px = (int) Math.round(TypedValue.applyDimension(
+ TypedValue.COMPLEX_UNIT_DIP, 150, r.getDisplayMetrics()
+ ));
+
+ if (mFile.isDown()){
+ Bitmap bitmap = BitmapUtils.decodeSampledBitmapFromFile(
+ mFile.getStoragePath(), px, px);
+
+ if (bitmap != null) {
+ thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
+
+ // Add thumbnail to cache
+ addBitmapToCache(imageKey, thumbnail);
+
+ mFile.setNeedsUpdateThumbnail(false);
+ mStorageManager.saveFile(mFile);
+ }
+
+ }
+ }
+
+ } catch (Throwable t) {
+ // the app should never break due to a problem with thumbnails
+ Log_OC.e(TAG, "Generation of thumbnail for " + mFile + " failed", t);
+ if (t instanceof OutOfMemoryError) {
+ System.gc();
+ }
+ }
+
+ return thumbnail;
+ }
+
+ protected void onPostExecute(Bitmap bitmap){
+ if (isCancelled()) {
+ bitmap = null;
+ }
+
+ if (mImageViewReference != null && bitmap != null) {
+ final ImageView imageView = mImageViewReference.get();
+ final ThumbnailGenerationTask bitmapWorkerTask =
+ getBitmapWorkerTask(imageView);
+ if (this == bitmapWorkerTask && imageView != null) {
+ if (imageView.getTag().equals(mFile.getFileId())) {
+ imageView.setImageBitmap(bitmap);
+ }
+ }
+ }
+ }
+ }
+
+
+ public static class AsyncDrawable extends BitmapDrawable {
+ private final WeakReference bitmapWorkerTaskReference;
+
+ public AsyncDrawable(
+ Resources res, Bitmap bitmap, ThumbnailGenerationTask bitmapWorkerTask
+ ) {
+
+ super(res, bitmap);
+ bitmapWorkerTaskReference =
+ new WeakReference(bitmapWorkerTask);
+ }
+
+ public ThumbnailGenerationTask getBitmapWorkerTask() {
+ return bitmapWorkerTaskReference.get();
+ }
+ }
+
+
+ /**
+ * Remove from cache the remoteId passed
+ * @param fileRemoteId: remote id of mFile passed
+ */
+ public static void removeFileFromCache(String fileRemoteId){
+ synchronized (mThumbnailsDiskCacheLock) {
+ if (mThumbnailCache != null) {
+ mThumbnailCache.removeKey(fileRemoteId);
+ }
+ mThumbnailsDiskCacheLock.notifyAll(); // Wake any waiting threads
+ }
+ }
+
+}
diff --git a/src/com/owncloud/android/files/services/FileDownloader.java b/src/com/owncloud/android/files/services/FileDownloader.java
index cb0f12ceb6..fdc35f8d9c 100644
--- a/src/com/owncloud/android/files/services/FileDownloader.java
+++ b/src/com/owncloud/android/files/services/FileDownloader.java
@@ -398,6 +398,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis
file.setMimetype(mCurrentDownload.getMimeType());
file.setStoragePath(mCurrentDownload.getSavePath());
file.setFileLength((new File(mCurrentDownload.getSavePath()).length()));
+ file.setRemoteId(mCurrentDownload.getFile().getRemoteId());
mStorageManager.saveFile(file);
}
diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java
index 5b7185ac8f..ad2a2cbe44 100644
--- a/src/com/owncloud/android/files/services/FileUploader.java
+++ b/src/com/owncloud/android/files/services/FileUploader.java
@@ -630,7 +630,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
// coincidence; nothing else is needed, the storagePath is right
// in the instance returned by mCurrentUpload.getFile()
}
-
+ file.setNeedsUpdateThumbnail(true);
mStorageManager.saveFile(file);
}
@@ -641,6 +641,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
file.setModificationTimestamp(remoteFile.getModifiedTimestamp());
file.setModificationTimestampAtLastSyncForData(remoteFile.getModifiedTimestamp());
// file.setEtag(remoteFile.getEtag()); // TODO Etag, where available
+ file.setRemoteId(remoteFile.getRemoteId());
}
private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType,
diff --git a/src/com/owncloud/android/operations/CreateFolderOperation.java b/src/com/owncloud/android/operations/CreateFolderOperation.java
index b0e7ed9de4..4df8b3df1f 100644
--- a/src/com/owncloud/android/operations/CreateFolderOperation.java
+++ b/src/com/owncloud/android/operations/CreateFolderOperation.java
@@ -84,21 +84,36 @@ public class CreateFolderOperation extends SyncOperation implements OnRemoteOper
}
}
-
/**
* Save new directory in local database
*/
public void saveFolderInDB() {
- OCFile newDir = new OCFile(mRemotePath);
- newDir.setMimetype("DIR");
- long parentId = getStorageManager().getFileByPath(FileStorageUtils.getParentPath(mRemotePath)).getFileId();
- newDir.setParentId(parentId);
- newDir.setModificationTimestamp(System.currentTimeMillis());
- getStorageManager().saveFile(newDir);
+ if (mCreateFullPath && getStorageManager().
+ getFileByPath(FileStorageUtils.getParentPath(mRemotePath)) == null){// When parent
+ // of remote path
+ // is not created
+ String[] subFolders = mRemotePath.split("/");
+ String composedRemotePath = "/";
- Log_OC.d(TAG, "Create directory " + mRemotePath + " in Database");
+ // For each antecesor folders create them recursively
+ for (int i=0; i mForgottenLocalFiles;
/** 'True' means that this operation is part of a full account synchronization */
private boolean mSyncFullAccount;
- /** 'True' means that Share resources bound to the files into the folder should be refreshed also */
+ /** 'True' means that Share resources bound to the files into should be refreshed also */
private boolean mIsShareSupported;
- /** 'True' means that the remote folder changed from last synchronization and should be fetched */
+ /** 'True' means that the remote folder changed and should be fetched */
private boolean mRemoteFolderChanged;
/** 'True' means that Etag will be ignored */
@@ -118,9 +123,12 @@ public class SynchronizeFolderOperation extends RemoteOperation {
*
* @param remoteFolderPath Remote folder to synchronize.
* @param currentSyncTime Time stamp for the synchronization process in progress.
- * @param localFolderId Identifier in the local database of the folder to synchronize.
- * @param updateFolderProperties 'True' means that the properties of the folder should be updated also, not just its content.
- * @param syncFullAccount 'True' means that this operation is part of a full account synchronization.
+ * @param localFolderId Identifier in the local database of the folder
+ * to synchronize.
+ * @param updateFolderProperties 'True' means that the properties of the folder should
+ * be updated also, not just its content.
+ * @param syncFullAccount 'True' means that this operation is part of a full account
+ * synchronization.
* @param dataStorageManager Interface with the local database.
* @param account ownCloud account where the folder is located.
* @param context Application context.
@@ -159,7 +167,8 @@ public class SynchronizeFolderOperation extends RemoteOperation {
}
/**
- * Returns the list of files and folders contained in the synchronized folder, if called after synchronization is complete.
+ * Returns the list of files and folders contained in the synchronized folder,
+ * if called after synchronization is complete.
*
* @return List of files and folders contained in the synchronized folder.
*/
@@ -194,7 +203,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
}
if (!mSyncFullAccount) {
- sendLocalBroadcast(EVENT_SINGLE_FOLDER_CONTENTS_SYNCED, mLocalFolder.getRemotePath(), result);
+ sendLocalBroadcast(
+ EVENT_SINGLE_FOLDER_CONTENTS_SYNCED, mLocalFolder.getRemotePath(), result
+ );
}
if (result.isSuccess() && mIsShareSupported && !mSyncFullAccount) {
@@ -202,7 +213,9 @@ public class SynchronizeFolderOperation extends RemoteOperation {
}
if (!mSyncFullAccount) {
- sendLocalBroadcast(EVENT_SINGLE_FOLDER_SHARES_SYNCED, mLocalFolder.getRemotePath(), result);
+ sendLocalBroadcast(
+ EVENT_SINGLE_FOLDER_SHARES_SYNCED, mLocalFolder.getRemotePath(), result
+ );
}
return result;
@@ -235,12 +248,14 @@ public class SynchronizeFolderOperation extends RemoteOperation {
if (!mIgnoreETag) {
// check if remote and local folder are different
- mRemoteFolderChanged = !(remoteFolder.getEtag().equalsIgnoreCase(mLocalFolder.getEtag()));
+ mRemoteFolderChanged =
+ !(remoteFolder.getEtag().equalsIgnoreCase(mLocalFolder.getEtag()));
}
result = new RemoteOperationResult(ResultCode.OK);
- Log_OC.i(TAG, "Checked " + mAccount.name + remotePath + " : " + (mRemoteFolderChanged ? "changed" : "not changed"));
+ Log_OC.i(TAG, "Checked " + mAccount.name + remotePath + " : " +
+ (mRemoteFolderChanged ? "changed" : "not changed"));
} else {
// check failed
@@ -248,9 +263,11 @@ public class SynchronizeFolderOperation extends RemoteOperation {
removeLocalFolder();
}
if (result.isException()) {
- Log_OC.e(TAG, "Checked " + mAccount.name + remotePath + " : " + result.getLogMessage(), result.getException());
+ Log_OC.e(TAG, "Checked " + mAccount.name + remotePath + " : " +
+ result.getLogMessage(), result.getException());
} else {
- Log_OC.e(TAG, "Checked " + mAccount.name + remotePath + " : " + result.getLogMessage());
+ Log_OC.e(TAG, "Checked " + mAccount.name + remotePath + " : " +
+ result.getLogMessage());
}
}
@@ -267,7 +284,8 @@ public class SynchronizeFolderOperation extends RemoteOperation {
if (result.isSuccess()) {
synchronizeData(result.getData(), client);
if (mConflictsFound > 0 || mFailsInFavouritesFound > 0) {
- result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT); // should be different result, but will do the job
+ result = new RemoteOperationResult(ResultCode.SYNC_CONFLICT);
+ // should be a different result code, but will do the job
}
} else {
if (result.getCode() == ResultCode.FILE_NOT_FOUND)
@@ -281,7 +299,13 @@ public class SynchronizeFolderOperation extends RemoteOperation {
private void removeLocalFolder() {
if (mStorageManager.fileExists(mLocalFolder.getFileId())) {
String currentSavePath = FileStorageUtils.getSavePath(mAccount.name);
- mStorageManager.removeFolder(mLocalFolder, true, (mLocalFolder.isDown() && mLocalFolder.getStoragePath().startsWith(currentSavePath)));
+ mStorageManager.removeFolder(
+ mLocalFolder,
+ true,
+ ( mLocalFolder.isDown() &&
+ mLocalFolder.getStoragePath().startsWith(currentSavePath)
+ )
+ );
}
}
@@ -296,7 +320,7 @@ public class SynchronizeFolderOperation extends RemoteOperation {
*
* @param client Client instance to the remote server where the data were
* retrieved.
- * @return 'True' when any change was made in the local data, 'false' otherwise.
+ * @return 'True' when any change was made in the local data, 'false' otherwise
*/
private void synchronizeData(ArrayList