Merge branch 'develop' into instant_uploads_set_path

This commit is contained in:
jabarros 2014-11-19 18:40:06 +01:00
commit 1435e8c406
7 changed files with 374 additions and 112 deletions

@ -1 +1 @@
Subproject commit 5bd0d7387712ce3f53869294761ac4d8537841cd
Subproject commit 2799b3e853c79e8ebb37051c92dfcc43f8d63788

View file

@ -40,14 +40,14 @@
<string name="prefs_imprint">Empreinte</string>
<string name="prefs_remember_last_share_location">Mémoriser l\'emplacement de partage</string>
<string name="prefs_remember_last_upload_location_summary">Mémoriser le dernier emplacement d\'upload</string>
<string name="recommend_subject">Essayez %1$s sur votre smartphone !</string>
<string name="recommend_subject">Essayez %1$s sur votre smartphone&amp;nbsp;!</string>
<string name="recommend_text">J\'aimerais vous inviter à utiliser %1$s sur votre smartphone !
Téléchargez-le ici : %2$s</string>
<string name="auth_check_server">Vérifier le serveur</string>
<string name="auth_host_url">Adresse du serveur https://...</string>
<string name="auth_host_url">Adresse du serveur https://</string>
<string name="auth_username">Nom d\'utilisateur</string>
<string name="auth_password">Mot de passe</string>
<string name="auth_register">Nouveau dans %1$s ?</string>
<string name="auth_register">Nouveau dans %1$s&amp;nbsp;?</string>
<string name="sync_string_files">Fichiers</string>
<string name="setup_btn_connect">Connecter</string>
<string name="uploader_btn_upload_text">Téléverser</string>
@ -82,8 +82,8 @@ Téléchargez-le ici : %2$s</string>
<string name="common_cancel">Annuler</string>
<string name="common_save_exit">Sauvegarder &amp; Quitter</string>
<string name="common_error">Erreur</string>
<string name="common_loading">Chargement ...</string>
<string name="common_error_unknown">Erreur Inconnue </string>
<string name="common_loading">Chargement</string>
<string name="common_error_unknown">Erreur inconnue </string>
<string name="about_title">À propos de</string>
<string name="change_password">Changer de mot de passe</string>
<string name="delete_account">Effacer ce compte</string>
@ -113,7 +113,7 @@ Téléchargez-le ici : %2$s</string>
<string name="sync_conflicts_in_favourites_ticker">Des conflits ont été trouvés</string>
<string name="sync_conflicts_in_favourites_content">%1$d fichiers à garder synchronisés n\'ont put être synchronisé</string>
<string name="sync_fail_in_favourites_ticker">La synchronisation des fichiers a échoué</string>
<string name="sync_fail_in_favourites_content">Le contenu de %1$d fichiers n\'a put être synchronisé (%2$d conflits)</string>
<string name="sync_fail_in_favourites_content">Le contenu de %1$d fichiers n\'a pu être synchronisé (%2$d conflits)</string>
<string name="sync_foreign_files_forgotten_ticker">Certains fichiers locaux ont été oubliés</string>
<string name="sync_foreign_files_forgotten_content">%1$d fichiers du dossier %2$s n\'ont pas pu être copiés dans</string>
<string name="sync_foreign_files_forgotten_explanation">Depuis la version 1.3.16, les fichiers envoyé depuis ce périphérique sont copiés dans le dossier local %1$s pour éviter une perte de données lorsqu\'un même fichier est synchronisé avec plusieurs comptes.
@ -125,7 +125,7 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
<string name="foreign_files_move">Tout déplacer</string>
<string name="foreign_files_success">Tous les fichiers ont été déplacés</string>
<string name="foreign_files_fail">Certains fichiers n\'ont pu être déplacés</string>
<string name="foreign_files_local_text">Local: %1$s</string>
<string name="foreign_files_local_text">Local&amp;nbsp;: %1$s</string>
<string name="foreign_files_remote_text">Distant : %1$s</string>
<string name="upload_query_move_foreign_files">Il n\'y a pas assez de place disponible pour copier les fichiers sélectionnés dans le dossier %1$s. Voulez-vous quand même les déplacer ?</string>
<string name="pincode_enter_pin_code">Veuillez saisir votre code de sécurité</string>
@ -149,15 +149,15 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
<string name="media_err_malformed">Le fichier média n\'est pas correctement encodé</string>
<string name="media_err_timeout">Délai dépassé pour la lecture du morceau.</string>
<string name="media_err_invalid_progressive_playback">Le fichier média ne peut pas être diffusé</string>
<string name="media_err_unknown">Fichier média ne peut être joué avec le stock de media player</string>
<string name="media_err_unknown">Le fichier média ne peut être joué avec le lecteur standard</string>
<string name="media_err_security_ex">Erreur de sécurité à la lecture de %1$s</string>
<string name="media_err_io_ex">Erreur de lecture de fichier à la lecture de %1$s</string>
<string name="media_err_unexpected">Erreur inattendue à la lecture de %1$s </string>
<string name="media_rewind_description">Bouton de rem-bobinage</string>
<string name="media_play_pause_description">Bouton de Lecture ou de Pause</string>
<string name="media_rewind_description">Bouton de rembobinage</string>
<string name="media_play_pause_description">Bouton de lecture ou de pause</string>
<string name="media_forward_description">Bouton d\'avance rapide</string>
<string name="auth_getting_authorization">Demande d\'autorisation...</string>
<string name="auth_trying_to_login">Tentative de connexion </string>
<string name="auth_getting_authorization">Demande d\'autorisation</string>
<string name="auth_trying_to_login">Tentative de connexion…</string>
<string name="auth_no_net_conn_title">Pas de connexion réseau</string>
<string name="auth_nossl_plain_ok_title">Connexion sécurisée non disponible</string>
<string name="auth_connection_established">Connexion établie</string>
@ -171,7 +171,7 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
<string name="auth_timeout_title">Le serveur met trop longtemps à répondre</string>
<string name="auth_incorrect_address_title">Adresse invalide</string>
<string name="auth_ssl_general_error_title">Échec de l\'initialisation SSL</string>
<string name="auth_ssl_unverified_server_title">Impossible de vérifier l\'identité du serveur SSL.</string>
<string name="auth_ssl_unverified_server_title">Impossible de vérifier l\'identité du serveur SSL</string>
<string name="auth_bad_oc_version_title">La version du serveur n\'est pas reconnue</string>
<string name="auth_wrong_connection_title">Impossible d\'établir la connexion</string>
<string name="auth_secure_connection">Connexion sécurisée établie</string>
@ -182,7 +182,7 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
<string name="auth_expired_oauth_token_toast">Votre autorisation a expiré. Merci de vous authentifier à nouveau</string>
<string name="auth_expired_basic_auth_toast">Veuillez saisir le mot de passe courant</string>
<string name="auth_expired_saml_sso_token_toast">Votre session a expiré. Merci de vous reconnecter</string>
<string name="auth_connecting_auth_server">Connexion au serveur d\'authentification...</string>
<string name="auth_connecting_auth_server">Connexion au serveur d\'authentification</string>
<string name="auth_unsupported_auth_method">Le serveur ne prend pas en charge pas cette méthode d\'authentification</string>
<string name="auth_unsupported_multiaccount">%1$s ne prend pas en charge les comptes multiples</string>
<string name="auth_fail_get_user_name">Votre serveur a retourné un identifiant d\'utilisateur incorrect. Veuillez prendre contact avec votre administrateur
@ -191,8 +191,8 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
<string name="fd_keep_in_sync">Maintenir le fichier à jour</string>
<string name="common_rename">Renommer</string>
<string name="common_remove">Supprimer</string>
<string name="confirmation_remove_alert">Voulez-vous vraiment supprimer %1$s ?</string>
<string name="confirmation_remove_folder_alert">Voulez-vous vraiment supprimer %1$s et son contenu ?</string>
<string name="confirmation_remove_alert">Voulez-vous vraiment supprimer %1$s&amp;nbsp;?</string>
<string name="confirmation_remove_folder_alert">Voulez-vous vraiment supprimer %1$s et son contenu&amp;nbsp;?</string>
<string name="confirmation_remove_local">Local seulement</string>
<string name="confirmation_remove_folder_local">Le contenu local uniquement</string>
<string name="confirmation_remove_remote">Effacer du serveur</string>
@ -205,36 +205,36 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
<string name="sync_file_fail_msg">Le fichier distant n\'a pu être vérifié</string>
<string name="sync_file_nothing_to_do_msg">Le contenu des fichiers est déjà synchronisé</string>
<string name="create_dir_fail_msg">Le dossier n\'a pas pu être créé</string>
<string name="filename_forbidden_characters">Caractères interdits : / \\ &lt; &gt; : \" | ? *</string>
<string name="filename_forbidden_characters">Caractères interdits&amp;nbsp;: / \\ &amp;lt; &amp;gt; : " | ? *</string>
<string name="filename_empty">Le nom du fichier ne peut pas être vide</string>
<string name="wait_a_moment">Veuillez patienter</string>
<string name="filedisplay_unexpected_bad_get_content">Problème inattendu. Veuillez essayer une autre app pour la sélection du fichier</string>
<string name="filedisplay_unexpected_bad_get_content">Problème inattendu. Veuillez essayer une autre application pour la sélection du fichier</string>
<string name="filedisplay_no_file_selected">Aucun fichier sélectionné</string>
<string name="activity_chooser_title">Envoyer un lien à…</string>
<string name="oauth_check_onoff">Connexion avec aAuth2.</string>
<string name="oauth_login_connection">Connexion au serveur aAuth2...</string>
<string name="oauth_check_onoff">Connexion avec oAuth2</string>
<string name="oauth_login_connection">Connexion au serveur oAuth2…</string>
<string name="ssl_validator_header">L\'identité du site ne peut être vérifiée</string>
<string name="ssl_validator_reason_cert_not_trusted">- Le certificat du serveur n\'est pas sûr</string>
<string name="ssl_validator_reason_cert_expired">- Le certificat du serveur a expiré</string>
<string name="ssl_validator_reason_cert_not_yet_valid">- Le certificat du serveur n\'est pas encore valide</string>
<string name="ssl_validator_reason_hostname_not_verified">- L\'URL ne correspond pas au nom d\'hôte du certificat</string>
<string name="ssl_validator_question">Voulez-vous tout de même faire confiance à ce certificat ?</string>
<string name="ssl_validator_question">Voulez-vous tout de même faire confiance à ce certificat&amp;nbsp;?</string>
<string name="ssl_validator_not_saved">Impossible de sauvegarder le certificat</string>
<string name="ssl_validator_btn_details_see">Détails</string>
<string name="ssl_validator_btn_details_hide">Masquer</string>
<string name="ssl_validator_label_subject">Délivré à :</string>
<string name="ssl_validator_label_issuer">Délivré par :</string>
<string name="ssl_validator_label_subject">Délivré à&amp;nbsp;:</string>
<string name="ssl_validator_label_issuer">Délivré par&amp;nbsp;:</string>
<string name="ssl_validator_label_CN">Nom d\'usage :</string>
<string name="ssl_validator_label_O">Organisation :</string>
<string name="ssl_validator_label_OU">Unité organisationnelle :</string>
<string name="ssl_validator_label_C">Pays :</string>
<string name="ssl_validator_label_ST">Région :</string>
<string name="ssl_validator_label_L">Localisation :</string>
<string name="ssl_validator_label_validity">Validité :</string>
<string name="ssl_validator_label_validity_from">De :</string>
<string name="ssl_validator_label_validity_to">À :</string>
<string name="ssl_validator_label_signature">Signature :</string>
<string name="ssl_validator_label_signature_algorithm">Algorithme :</string>
<string name="ssl_validator_label_O">Organisation&amp;nbsp;:</string>
<string name="ssl_validator_label_OU">Unité organisationnelle&amp;nbsp;:</string>
<string name="ssl_validator_label_C">Pays&amp;nbsp;:</string>
<string name="ssl_validator_label_ST">Région&amp;nbsp;:</string>
<string name="ssl_validator_label_L">Localisation&amp;nbsp;:</string>
<string name="ssl_validator_label_validity">Validité&amp;nbsp;:</string>
<string name="ssl_validator_label_validity_from">De&amp;nbsp;:</string>
<string name="ssl_validator_label_validity_to">À&amp;nbsp;:</string>
<string name="ssl_validator_label_signature">Signature&amp;nbsp;:</string>
<string name="ssl_validator_label_signature_algorithm">Algorithme&amp;nbsp;:</string>
<string name="ssl_validator_null_cert">Impossible d\'afficher le certificat.</string>
<string name="ssl_validator_no_info_about_error">- Aucune information sur l\'erreur</string>
<string name="placeholder_sentence">Ceci est un espace réservé</string>
@ -255,7 +255,7 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
<string name="preview_image_error_unknown_format">Cette image ne peut pas être affichée</string>
<string name="error__upload__local_file_not_copied">%1$s n\'a pas pu être copié dans le dossier local %2$s</string>
<string name="prefs_instant_upload_path_title">Chemin d\'accès pour le téléversement</string>
<string name="share_link_no_support_share_api">Désolé, le partage n\'est pas disponible sur votre serveur. Contactez votre administrateur, s\'il vous plait.</string>
<string name="share_link_no_support_share_api">Désolé, le partage n\'est pas disponible sur votre serveur. Veuillez contacter votre administrateur.</string>
<string name="share_link_file_no_exist">Impossible de partager. Vérifiez que le fichier est bien présent</string>
<string name="share_link_file_error">Une erreur est survenue lors de la tentative de partage de ce fichier ou répertoire</string>
<string name="unshare_link_file_no_exist">Impossible de supprimer le partage. Vérifiez que le fichier est bien présent</string>
@ -263,7 +263,7 @@ Ci-dessous la liste des fichiers locaux, et les fichiers distants dans %5$s auxq
<string name="activity_chooser_send_file_title">Envoyer</string>
<string name="copy_link">Copier le lien</string>
<string name="clipboard_text_copied">Copié dans le presse-papiers</string>
<string name="error_cant_bind_to_operations_service">Erreur critique : impossible de réaliser des opérations</string>
<string name="error_cant_bind_to_operations_service">Erreur critique&amp;nbsp;: impossible de réaliser des opérations</string>
<string name="network_error_socket_exception">Une erreur s\'est produite pendant la connection au serveur</string>
<string name="network_error_socket_timeout_exception">Une erreur est survenue pendant l\'attente du serveur. L\'opération n\'a pas pu être effectuée.</string>
<string name="network_error_connect_timeout_exception">Une erreur est survenue pendant l\'attente du serveur. L\'opération n\'a pas pu être effectuée.</string>

View file

@ -73,6 +73,7 @@ import com.owncloud.android.operations.common.SyncOperation;
import com.owncloud.android.ui.activity.FileActivity;
import com.owncloud.android.ui.activity.FileDisplayActivity;
import com.owncloud.android.utils.ErrorMessageAdapter;
import com.owncloud.android.utils.UriUtils;
@ -120,6 +121,9 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
private NotificationCompat.Builder mNotificationBuilder;
private int mLastPercent;
private static final String MIME_TYPE_PDF = "application/pdf";
private static final String FILE_EXTENSION_PDF = ".pdf";
public static String getUploadFinishMessage() {
return FileUploader.class.getName().toString() + UPLOAD_FINISH_MESSAGE;
@ -646,18 +650,6 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
private OCFile obtainNewOCFileToUpload(String remotePath, String localPath, String mimeType,
FileDataStorageManager storageManager) {
OCFile newFile = new OCFile(remotePath);
newFile.setStoragePath(localPath);
newFile.setLastSyncDateForProperties(0);
newFile.setLastSyncDateForData(0);
// size
if (localPath != null && localPath.length() > 0) {
File localFile = new File(localPath);
newFile.setFileLength(localFile.length());
newFile.setLastSyncDateForData(localFile.lastModified());
} // don't worry about not assigning size, the problems with localPath
// are checked when the UploadFileOperation instance is created
// MIME type
if (mimeType == null || mimeType.length() <= 0) {
@ -671,6 +663,25 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
if (mimeType == null) {
mimeType = "application/octet-stream";
}
if (isPdfFileFromContentProviderWithoutExtension(localPath, mimeType)){
remotePath += FILE_EXTENSION_PDF;
}
OCFile newFile = new OCFile(remotePath);
newFile.setStoragePath(localPath);
newFile.setLastSyncDateForProperties(0);
newFile.setLastSyncDateForData(0);
// size
if (localPath != null && localPath.length() > 0) {
File localFile = new File(localPath);
newFile.setFileLength(localFile.length());
newFile.setLastSyncDateForData(localFile.lastModified());
} // don't worry about not assigning size, the problems with localPath
// are checked when the UploadFileOperation instance is created
newFile.setMimetype(mimeType);
return newFile;
@ -856,4 +867,17 @@ public class FileUploader extends Service implements OnDatatransferProgressListe
sendStickyBroadcast(end);
}
/**
* Checks if content provider, using the content:// scheme, returns a file with mime-type
* 'application/pdf' but file has not extension
* @param localPath
* @param mimeType
* @return true if is needed to add the pdf file extension to the file
*/
private boolean isPdfFileFromContentProviderWithoutExtension(String localPath, String mimeType) {
return localPath.startsWith(UriUtils.URI_CONTENT_SCHEME) &&
mimeType.equals(MIME_TYPE_PDF) &&
!localPath.endsWith(FILE_EXTENSION_PDF);
}
}

View file

@ -31,11 +31,16 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import android.accounts.Account;
import android.content.Context;
import android.net.Uri;
import com.owncloud.android.MainApp;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.files.services.FileUploader;
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
import com.owncloud.android.lib.common.OwnCloudClient;
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener;
import com.owncloud.android.lib.common.network.ProgressiveDataTransferer;
import com.owncloud.android.lib.common.operations.OperationCancelledException;
import com.owncloud.android.lib.common.operations.RemoteOperation;
import com.owncloud.android.lib.common.operations.RemoteOperationResult;
@ -45,9 +50,7 @@ import com.owncloud.android.lib.resources.files.ChunkedUploadRemoteFileOperation
import com.owncloud.android.lib.resources.files.ExistenceCheckRemoteOperation;
import com.owncloud.android.lib.resources.files.UploadRemoteFileOperation;
import com.owncloud.android.utils.FileStorageUtils;
import android.accounts.Account;
import android.content.Context;
import com.owncloud.android.utils.UriUtils;
/**
@ -92,10 +95,9 @@ public class UploadFileOperation extends RemoteOperation {
throw new IllegalArgumentException("Illegal NULL account in UploadFileOperation creation");
if (file == null)
throw new IllegalArgumentException("Illegal NULL file in UploadFileOperation creation");
if (file.getStoragePath() == null || file.getStoragePath().length() <= 0
|| !(new File(file.getStoragePath()).exists())) {
if (file.getStoragePath() == null || file.getStoragePath().length() <= 0) {
throw new IllegalArgumentException(
"Illegal file in UploadFileOperation; storage path invalid or file not found: "
"Illegal file in UploadFileOperation; storage path invalid: "
+ file.getStoragePath());
}
@ -218,51 +220,76 @@ public class UploadFileOperation extends RemoteOperation {
// copied
} else {
String temporalPath = FileStorageUtils.getTemporalPath(mAccount.name) + mFile.getRemotePath();
mFile.setStoragePath(temporalPath);
temporalFile = new File(temporalPath);
if (!mOriginalStoragePath.equals(temporalPath)) { // preventing
// weird
// but
// possible
// situation
InputStream in = null;
OutputStream out = null;
try {
File temporalParent = temporalFile.getParentFile();
temporalParent.mkdirs();
if (!temporalParent.isDirectory()) {
throw new IOException("Unexpected error: parent directory could not be created");
}
temporalFile.createNewFile();
if (!temporalFile.isFile()) {
throw new IOException("Unexpected error: target file could not be created");
}
in = new FileInputStream(originalFile);
File temporalParent = temporalFile.getParentFile();
temporalParent.mkdirs();
if (!temporalParent.isDirectory()) {
throw new IOException("Unexpected error: parent directory could not be created");
}
temporalFile.createNewFile();
if (!temporalFile.isFile()) {
throw new IOException("Unexpected error: target file could not be created");
}
InputStream in = null;
OutputStream out = null;
try {
// In case document provider schema as 'content://'
if (mOriginalStoragePath.startsWith(UriUtils.URI_CONTENT_SCHEME)) {
Uri uri = Uri.parse(mOriginalStoragePath);
in = MainApp.getAppContext().getContentResolver().openInputStream(uri);
out = new FileOutputStream(temporalFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
int nRead;
byte[] data = new byte[16384];
while ((nRead = in.read(data, 0, data.length)) != -1) {
out.write(data, 0, nRead);
}
out.flush();
} else {
if (!mOriginalStoragePath.equals(temporalPath)) { // preventing
// weird
// but
// possible
// situation
in = new FileInputStream(originalFile);
out = new FileOutputStream(temporalFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
}
}
} catch (Exception e) {
result = new RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_COPIED);
return result;
} finally {
try {
if (in != null)
in.close();
} catch (Exception e) {
result = new RemoteOperationResult(ResultCode.LOCAL_STORAGE_NOT_COPIED);
return result;
} finally {
try {
if (in != null)
in.close();
} catch (Exception e) {
Log_OC.d(TAG, "Weird exception while closing input stream for " + mOriginalStoragePath + " (ignoring)", e);
}
try {
if (out != null)
out.close();
} catch (Exception e) {
Log_OC.d(TAG, "Weird exception while closing output stream for " + expectedPath + " (ignoring)", e);
}
Log_OC.d(TAG, "Weird exception while closing input stream for " + mOriginalStoragePath + " (ignoring)", e);
}
try {
if (out != null)
out.close();
} catch (Exception e) {
Log_OC.d(TAG, "Weird exception while closing output stream for " + expectedPath + " (ignoring)", e);
}
}
}
@ -417,5 +444,4 @@ public class UploadFileOperation extends RemoteOperation {
public void cancel() {
mUploadOperation.cancel();
}
}

View file

@ -31,6 +31,7 @@ import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@ -41,13 +42,18 @@ import android.content.SyncRequest;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
@ -101,6 +107,7 @@ import com.owncloud.android.ui.preview.PreviewMediaFragment;
import com.owncloud.android.ui.preview.PreviewVideoActivity;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.ErrorMessageAdapter;
import com.owncloud.android.utils.UriUtils;
/**
@ -151,7 +158,7 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
private String DIALOG_UNTRUSTED_CERT;
private OCFile mWaitingToSend;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log_OC.d(TAG, "onCreate() start");
@ -563,6 +570,11 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
builder.setExpedited(true);
builder.setManual(true);
builder.syncOnce();
// Fix bug in Android Lollipop when you click on refresh the whole account
Bundle extras = new Bundle();
builder.setExtras(extras);
SyncRequest request = builder.build();
ContentResolver.requestSync(request);
}
@ -654,8 +666,12 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
private void requestSimpleUpload(Intent data, int resultCode) {
String filepath = null;
String mimeType = null;
Uri selectedImageUri = data.getData();
try {
Uri selectedImageUri = data.getData();
mimeType = getContentResolver().getType(selectedImageUri);
String filemanagerstring = selectedImageUri.getPath();
String selectedImagePath = getPath(selectedImageUri);
@ -687,10 +703,34 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
}
if (!remotepath.endsWith(OCFile.PATH_SEPARATOR))
remotepath += OCFile.PATH_SEPARATOR;
remotepath += new File(filepath).getName();
if (filepath.startsWith(UriUtils.URI_CONTENT_SCHEME)) {
Cursor cursor = MainApp.getAppContext().getContentResolver()
.query(Uri.parse(filepath), null, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
String displayName = cursor.getString(
cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
Log.i(TAG, "Display Name: " + displayName + "; mimeType: " + mimeType);
displayName.replace(File.separatorChar, '_');
displayName.replace(File.pathSeparatorChar, '_');
remotepath += displayName + DisplayUtils.getComposedFileExtension(filepath);
}
} finally {
cursor.close();
}
} else {
remotepath += new File(filepath).getName();
}
i.putExtra(FileUploader.KEY_LOCAL_FILE, filepath);
i.putExtra(FileUploader.KEY_REMOTE_FILE, remotepath);
i.putExtra(FileUploader.KEY_MIME_TYPE, mimeType);
i.putExtra(FileUploader.KEY_UPLOAD_TYPE, FileUploader.UPLOAD_SINGLE_FILE);
if (resultCode == UploadFilesActivity.RESULT_OK_AND_MOVE)
i.putExtra(FileUploader.KEY_LOCAL_BEHAVIOUR, FileUploader.LOCAL_BEHAVIOUR_MOVE);
@ -866,22 +906,74 @@ OnSslUntrustedCertListener, OnEnforceableRefreshListener {
return dialog;
}
/**
* Translates a content URI of an image to a physical path
* on the disk
* Translates a content URI of an content to a physical path on the disk
*
* @param uri The URI to resolve
* @return The path to the image or null if it could not be found
* @return The path to the content or null if it could not be found
*/
public String getPath(Uri uri) {
String[] projection = { MediaStore.Images.Media.DATA };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if (cursor != null) {
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
final boolean isKitKatOrLater = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKatOrLater && DocumentsContract.isDocumentUri(getApplicationContext(), uri)) {
// ExternalStorageProvider
if (UriUtils.isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (UriUtils.isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
Long.valueOf(id));
return UriUtils.getDataColumn(getApplicationContext(), contentUri, null, null);
}
// MediaProvider
else if (UriUtils.isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] { split[1] };
return UriUtils.getDataColumn(getApplicationContext(), contentUri, selection, selectionArgs);
}
// Documents providers returned as content://...
else if (UriUtils.isContentDocument(uri)) {
return uri.toString();
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (UriUtils.isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return UriUtils.getDataColumn(getApplicationContext(), uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}

View file

@ -277,7 +277,24 @@ public class DisplayUtils {
return url;
}
}
/**
* Get the file extension if it is on path as type "content://.../DocInfo.doc"
* @param filepath: Content Uri converted to string format
* @return String: fileExtension (type '.pdf'). Empty if no extension
*/
public static String getComposedFileExtension(String filepath) {
String fileExtension = "";
String fileNameInContentUri = filepath.substring(filepath.lastIndexOf("/"));
// Check if extension is included in uri
int pos = fileNameInContentUri.lastIndexOf('.');
if (pos >= 0) {
fileExtension = fileNameInContentUri.substring(pos);
}
return fileExtension;
}
public static CharSequence getRelativeDateTimeString(Context c, long time, long minResolution, long transitionResolution, int flags){
CharSequence dateString = "";
@ -301,6 +318,6 @@ public class DisplayUtils {
}
}
return dateString.toString().split(",")[0];
return dateString.toString().split(",")[0];
}
}

View file

@ -0,0 +1,103 @@
/* 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 <http://www.gnu.org/licenses/>.
*
*/
package com.owncloud.android.utils;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
/**
* A helper class for some Uri operations.
*/
public class UriUtils {
public static final String URI_CONTENT_SCHEME = "content://";
/**
* Get the value of the data column for this Uri. This is useful for
* MediaStore Uris, and other file-based ContentProviders.
*
* @param context The context.
* @param uri The Uri to query.
* @param selection (Optional) Filter used in the query.
* @param selectionArgs (Optional) Selection arguments used in the query.
* @return The value of the _data column, which is typically a file path.
*/
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = { column };
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is ExternalStorageProvider.
*/
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is Google Photos.
*/
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
/**
*
* @param uri The Uri to check.
* @return Whether the Uri is from a content provider as kind "content://..."
*/
public static boolean isContentDocument(Uri uri) {
return uri.toString().startsWith(URI_CONTENT_SCHEME);
}
}