X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/c63f7fbfafbc7cd1b984e73274f87671d719cab2..afaa2879d192be067cae523b51dad75d89a6c6cb:/src/com/owncloud/android/datamodel/FileDataStorageManager.java diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java index b10e525c..c32dbbce 100644 --- a/src/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -1,6 +1,8 @@ -/* ownCloud Android client application +/** + * ownCloud Android client application + * * Copyright (C) 2012 Bartek Przybylski - * Copyright (C) 2012-2014 ownCloud Inc. + * Copyright (C) 2015 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, @@ -23,6 +25,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Iterator; +import java.util.List; import java.util.Vector; import com.owncloud.android.MainApp; @@ -33,7 +36,6 @@ import com.owncloud.android.lib.resources.shares.ShareType; import com.owncloud.android.lib.resources.files.FileUtils; import com.owncloud.android.utils.FileStorageUtils; - import android.accounts.Account; import android.content.ContentProviderClient; import android.content.ContentProviderOperation; @@ -41,10 +43,12 @@ import android.content.ContentProviderResult; import android.content.ContentResolver; import android.content.ContentUris; import android.content.ContentValues; +import android.content.Intent; import android.content.OperationApplicationException; import android.database.Cursor; import android.net.Uri; import android.os.RemoteException; +import android.provider.MediaStore; public class FileDataStorageManager { @@ -164,7 +168,6 @@ public class FileDataStorageManager { return ret; } - public boolean saveFile(OCFile file) { boolean overriden = false; ContentValues cv = new ContentValues(); @@ -192,6 +195,7 @@ public class FileDataStorageManager { cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions()); cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId()); cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail()); + cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading()); boolean sameRemotePath = fileExists(file.getRemotePath()); if (sameRemotePath || @@ -260,8 +264,8 @@ public class FileDataStorageManager { * HERE ONLY DATA CONSISTENCY SHOULD BE GRANTED * * @param folder - * @param files - * @param removeNotUpdated + * @param updatedFiles + * @param filesToRemove */ public void saveFolder( OCFile folder, Collection updatedFiles, Collection filesToRemove @@ -301,6 +305,7 @@ public class FileDataStorageManager { cv.put(ProviderTableMeta.FILE_PERMISSIONS, file.getPermissions()); cv.put(ProviderTableMeta.FILE_REMOTE_ID, file.getRemoteId()); cv.put(ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail()); + cv.put(ProviderTableMeta.FILE_IS_DOWNLOADING, file.isDownloading()); boolean existsByPath = fileExists(file.getRemotePath()); if (existsByPath || fileExists(file.getFileId())) { @@ -346,7 +351,9 @@ public class FileDataStorageManager { ).withSelection(where, whereArgs).build()); if (file.isDown()) { - new File(file.getStoragePath()).delete(); + String path = file.getStoragePath(); + new File(path).delete(); + triggerMediaScan(path); // notify MediaScanner about removed file } } } @@ -484,8 +491,12 @@ public class FileDataStorageManager { } success &= (deleted > 0); } - if (removeLocalCopy && file.isDown() && file.getStoragePath() != null && success) { - success = new File(file.getStoragePath()).delete(); + String localPath = file.getStoragePath(); + if (removeLocalCopy && file.isDown() && localPath != null && success) { + success = new File(localPath).delete(); + if (success) { + deleteFileInMediaScan(localPath); + } if (!removeDBData && success) { // maybe unnecessary, but should be checked TODO remove if unnecessary file.setStoragePath(null); @@ -532,7 +543,8 @@ public class FileDataStorageManager { private boolean removeLocalFolder(OCFile folder) { boolean success = true; - File localFolder = new File(FileStorageUtils.getDefaultSavePathFor(mAccount.name, folder)); + String localFolderPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, folder); + File localFolder = new File(localFolderPath); if (localFolder.exists()) { // stage 1: remove the local files already registered in the files database Vector files = getFolderContent(folder.getFileId()); @@ -545,6 +557,8 @@ public class FileDataStorageManager { File localFile = new File(file.getStoragePath()); success &= localFile.delete(); if (success) { + // notify MediaScanner about removed file + deleteFileInMediaScan(file.getStoragePath()); file.setStoragePath(null); saveFile(file); } @@ -568,6 +582,7 @@ public class FileDataStorageManager { if (localFile.isDirectory()) { success &= removeLocalFolder(localFile); } else { + String path = localFile.getAbsolutePath(); success &= localFile.delete(); } } @@ -576,109 +591,20 @@ public class FileDataStorageManager { return success; } + /** - * Updates database for a folder that was moved to a different location. + * Updates database and file system for a file or folder that was moved to a different location. * * TODO explore better (faster) implementations * TODO throw exceptions up ! */ - public void moveFolder(OCFile folder, String newPath) { - // TODO check newPath - - 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 " - ); - } 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 " - ); - } - - /// 2. prepare a batch of update operations to change all the descendants - 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(); // 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) - ); - } - operations.add( - ContentProviderOperation. - newUpdate(ProviderTableMeta.CONTENT_URI). - withValues(cv). - withSelection( - ProviderTableMeta._ID + "=?", - new String[] { String.valueOf(child.getFileId()) } - ). - build() - ); - } while (c.moveToNext()); - } - c.close(); - - /// 3. apply updates in batch - try { - if (getContentResolver() != null) { - getContentResolver().applyBatch(MainApp.getAuthority(), operations); - - } else { - getContentProviderClient().applyBatch(operations); - } - - } catch (OperationApplicationException 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); - } - - } - } - - public void moveLocalFile(OCFile file, String targetPath, String targetParentPath) { if (file != null && file.fileExists() && !OCFile.ROOT_PATH.equals(file.getFileName())) { OCFile targetParent = getFileByPath(targetParentPath); if (targetParent == null) { - // TODO panic + throw new IllegalStateException("Parent folder of the target path does not exist!!"); } /// 1. get all the descendants of the moved element in a single QUERY @@ -718,6 +644,8 @@ public class FileDataStorageManager { ArrayList operations = new ArrayList(c.getCount()); String defaultSavePath = FileStorageUtils.getSavePath(mAccount.name); + List originalPathsToTriggerMediaScan = new ArrayList(); + List newPathsToTriggerMediaScan = new ArrayList(); if (c.moveToFirst()) { int lengthOfOldPath = file.getRemotePath().length(); int lengthOfOldStoragePath = defaultSavePath.length() + lengthOfOldPath; @@ -731,11 +659,14 @@ public class FileDataStorageManager { if (child.getStoragePath() != null && child.getStoragePath().startsWith(defaultSavePath)) { // update link to downloaded content - but local move is not done here! - cv.put( - ProviderTableMeta.FILE_STORAGE_PATH, - defaultSavePath + targetPath + - child.getStoragePath().substring(lengthOfOldStoragePath) - ); + String targetLocalPath = defaultSavePath + targetPath + + child.getStoragePath().substring(lengthOfOldStoragePath); + + cv.put(ProviderTableMeta.FILE_STORAGE_PATH, targetLocalPath); + + originalPathsToTriggerMediaScan.add(child.getStoragePath()); + newPathsToTriggerMediaScan.add(targetLocalPath); + } if (child.getRemotePath().equals(file.getRemotePath())) { cv.put( @@ -766,27 +697,35 @@ public class FileDataStorageManager { } } catch (Exception e) { - Log_OC.e( - TAG, - "Fail to update " + file.getFileId() + " and descendants in database", - e - ); + Log_OC.e(TAG, "Fail to update " + file.getFileId() + " and descendants in database", e); } /// 4. move in local file system - String localPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, file); - File localFile = new File(localPath); + String originalLocalPath = FileStorageUtils.getDefaultSavePathFor(mAccount.name, file); + String targetLocalPath = defaultSavePath + targetPath; + File localFile = new File(originalLocalPath); boolean renamed = false; if (localFile.exists()) { - File targetFile = new File(defaultSavePath + targetPath); + File targetFile = new File(targetLocalPath); File targetFolder = targetFile.getParentFile(); if (!targetFolder.exists()) { targetFolder.mkdirs(); } renamed = localFile.renameTo(targetFile); } - Log_OC.d(TAG, "Local file RENAMED : " + renamed); - + + if (renamed) { + Iterator it = originalPathsToTriggerMediaScan.iterator(); + while (it.hasNext()) { + // Notify MediaScanner about removed file + deleteFileInMediaScan(it.next()); + } + it = newPathsToTriggerMediaScan.iterator(); + while (it.hasNext()) { + // Notify MediaScanner about new file/folder + triggerMediaScan(it.next()); + } + } } } @@ -942,6 +881,8 @@ public class FileDataStorageManager { file.setRemoteId(c.getString(c.getColumnIndex(ProviderTableMeta.FILE_REMOTE_ID))); file.setNeedsUpdateThumbnail(c.getInt( c.getColumnIndex(ProviderTableMeta.FILE_UPDATE_THUMBNAIL)) == 1 ? true : false); + file.setDownloading(c.getInt( + c.getColumnIndex(ProviderTableMeta.FILE_IS_DOWNLOADING)) == 1 ? true : false); } return file; @@ -1324,6 +1265,10 @@ public class FileDataStorageManager { ProviderTableMeta.FILE_UPDATE_THUMBNAIL, file.needsUpdateThumbnail() ? 1 : 0 ); + cv.put( + ProviderTableMeta.FILE_IS_DOWNLOADING, + file.isDownloading() ? 1 : 0 + ); boolean existsByPath = fileExists(file.getRemotePath()); if (existsByPath || fileExists(file.getFileId())) { @@ -1549,4 +1494,52 @@ public class FileDataStorageManager { //} } + public void triggerMediaScan(String path) { + Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + intent.setData(Uri.fromFile(new File(path))); + MainApp.getAppContext().sendBroadcast(intent); + } + + public void deleteFileInMediaScan(String path) { + + String mimetypeString = FileStorageUtils.getMimeTypeFromName(path); + ContentResolver contentResolver = getContentResolver(); + + if (contentResolver != null) { + if (mimetypeString.startsWith("image/")) { + // Images + contentResolver.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + MediaStore.Images.Media.DATA + "=?", new String[]{path}); + } else if (mimetypeString.startsWith("audio/")) { + // Audio + contentResolver.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, + MediaStore.Audio.Media.DATA + "=?", new String[]{path}); + } else if (mimetypeString.startsWith("video/")) { + // Video + contentResolver.delete(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, + MediaStore.Video.Media.DATA + "=?", new String[]{path}); + } + } else { + ContentProviderClient contentProviderClient = getContentProviderClient(); + try { + if (mimetypeString.startsWith("image/")) { + // Images + contentProviderClient.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + MediaStore.Images.Media.DATA + "=?", new String[]{path}); + } else if (mimetypeString.startsWith("audio/")) { + // Audio + contentProviderClient.delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, + MediaStore.Audio.Media.DATA + "=?", new String[]{path}); + } else if (mimetypeString.startsWith("video/")) { + // Video + contentProviderClient.delete(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, + MediaStore.Video.Media.DATA + "=?", new String[]{path}); + } + } catch (RemoteException e) { + Log_OC.e(TAG, "Exception deleting media file in MediaStore " + e.getMessage()); + } + } + + } + }