From: masensio Date: Fri, 2 May 2014 12:24:00 +0000 (+0200) Subject: Add FileListCursorLoader. Update data using CursorLoader and LoaderManager. Update... X-Git-Tag: oc-android-1.7.0_signed~309^2~61 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/c9626772a19c0f5631ae5b58c09dda39d0baa878?ds=sidebyside Add FileListCursorLoader. Update data using CursorLoader and LoaderManager. Update filelist when a file/folder is deleted --- diff --git a/src/com/owncloud/android/datamodel/FileDataStorageManager.java b/src/com/owncloud/android/datamodel/FileDataStorageManager.java index 04f3271a..39b1959c 100644 --- a/src/com/owncloud/android/datamodel/FileDataStorageManager.java +++ b/src/com/owncloud/android/datamodel/FileDataStorageManager.java @@ -33,7 +33,6 @@ import com.owncloud.android.lib.resources.files.FileUtils; import com.owncloud.android.utils.FileStorageUtils; import com.owncloud.android.utils.Log_OC; - import android.accounts.Account; import android.content.ContentProviderClient; import android.content.ContentProviderOperation; @@ -631,6 +630,7 @@ public class FileDataStorageManager { ProviderTableMeta.FILE_PARENT + "=?" , new String[] { String.valueOf(parentId)}, null); + //Log_OC.d(TAG, "getContent Uri " + req_uri); //c.setNotificationUri(getContentResolver(), req_uri); } @@ -1329,4 +1329,5 @@ public class FileDataStorageManager { */ //} } + } diff --git a/src/com/owncloud/android/datamodel/FileListCursorLoader.java b/src/com/owncloud/android/datamodel/FileListCursorLoader.java new file mode 100644 index 00000000..20039eef --- /dev/null +++ b/src/com/owncloud/android/datamodel/FileListCursorLoader.java @@ -0,0 +1,76 @@ +/* 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 com.owncloud.android.utils.Log_OC; + +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.support.v4.content.CursorLoader; + +/** + * CursorLoader for FileList + * + * @author masensio + * + */ +public class FileListCursorLoader extends CursorLoader { + + private static final String TAG = CursorLoader.class.getSimpleName(); + + private long mParentId; + private FileDataStorageManager mStorageManager; + + public FileListCursorLoader(Context context) { + super(context); + // TODO Auto-generated constructor stub + } + + public FileListCursorLoader(Context context, Uri uri, String[] projection, String selection, + String[] selectionArgs, String sortOrder) { + super(context, uri, projection, selection, selectionArgs, sortOrder); + // TODO Auto-generated constructor stub + } + + public FileListCursorLoader(Context context, FileDataStorageManager storageManager) { + super(context); + mStorageManager = storageManager; + } + + public void setParentId(long parentId) { + mParentId = parentId; + } + public long getParentId(){ + return mParentId; + } + + public void setStorageManager(FileDataStorageManager storageManager) { + mStorageManager = storageManager; + } + + @Override + public Cursor loadInBackground() { + Log_OC.d(TAG, "loadInBackgroud"); + Cursor cursor = null; + if (mStorageManager != null) { + cursor = mStorageManager.getContent(mParentId); + } + return cursor; + } +} \ No newline at end of file diff --git a/src/com/owncloud/android/providers/FileContentProvider.java b/src/com/owncloud/android/providers/FileContentProvider.java index c84d66b0..1a5810bd 100644 --- a/src/com/owncloud/android/providers/FileContentProvider.java +++ b/src/com/owncloud/android/providers/FileContentProvider.java @@ -24,6 +24,7 @@ import java.util.HashMap; import com.owncloud.android.R; import com.owncloud.android.db.ProviderMeta; import com.owncloud.android.db.ProviderMeta.ProviderTableMeta; +import com.owncloud.android.lib.resources.files.FileUtils; import com.owncloud.android.lib.resources.shares.ShareType; import com.owncloud.android.utils.Log_OC; @@ -141,20 +142,57 @@ public class FileContentProvider extends ContentProvider { @Override public int delete(Uri uri, String where, String[] whereArgs) { - //Log_OC.d(TAG, "Deleting " + uri + " at provider " + this); + Log_OC.d(TAG, "Deleting " + uri + " at provider " + this); int count = 0; SQLiteDatabase db = mDbHelper.getWritableDatabase(); db.beginTransaction(); + + // Get parentId to notify the change + long parentId = getParentId(uri); + + // Delete action try { count = delete(db, uri, where, whereArgs); db.setTransactionSuccessful(); } finally { db.endTransaction(); } + Log_OC.d(TAG, "Uri " + uri); getContext().getContentResolver().notifyChange(uri, null); + + // Notify the change to the parent folder + notifyChangeToParentUri(parentId); return count; } + private long getParentId(Uri uri) { + long parentId = -1; + + if (mUriMatcher.match(uri) == SINGLE_FILE || mUriMatcher.match(uri) == DIRECTORY) { + String fileId = uri.toString().substring(uri.toString().lastIndexOf(FileUtils.PATH_SEPARATOR) + 1); + Uri selectFileUri = Uri.withAppendedPath(ProviderTableMeta.CONTENT_URI_FILE, fileId); + String[] fileProjection = new String[] { ProviderTableMeta.FILE_PARENT}; + Cursor fileCursor = query(selectFileUri, fileProjection, null, null, null); + + if (fileCursor != null && fileCursor.moveToFirst()) { + parentId = fileCursor.getLong(fileCursor.getColumnIndex(ProviderTableMeta.FILE_PARENT)); + } + fileCursor.close(); + } + Log_OC.d(TAG, "getParentId = " + parentId); + return parentId; + } + + private void notifyChangeToParentUri(long parentId) { + if (parentId != -1) { + Uri parentUri = Uri.withAppendedPath( + ProviderTableMeta.CONTENT_URI_DIR, + String.valueOf(parentId)); + Log_OC.d(TAG, "ParentUri " + parentUri); + getContext().getContentResolver().notifyChange(parentUri, null); + } + } + private int delete(SQLiteDatabase db, Uri uri, String where, String[] whereArgs) { int count = 0; switch (mUriMatcher.match(uri)) { @@ -252,6 +290,7 @@ public class FileContentProvider extends ContentProvider { @Override public Uri insert(Uri uri, ContentValues values) { //Log_OC.d(TAG, "Inserting " + values.getAsString(ProviderTableMeta.FILE_PATH) + " at provider " + this); + Log_OC.d(TAG, "Uri " + uri); Uri newUri = null; SQLiteDatabase db = mDbHelper.getWritableDatabase(); db.beginTransaction(); @@ -424,7 +463,8 @@ public class FileContentProvider extends ContentProvider { @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - //Log_OC.d(TAG, "Updating " + values.getAsString(ProviderTableMeta.FILE_PATH) + " at provider " + this); + Log_OC.d(TAG, "Updating " + values.getAsString(ProviderTableMeta.FILE_PATH) + " at provider " + this); + Log_OC.d(TAG, "Uri " + uri); int count = 0; SQLiteDatabase db = mDbHelper.getWritableDatabase(); db.beginTransaction(); diff --git a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java index 2913c9e6..7af48328 100644 --- a/src/com/owncloud/android/ui/adapter/FileListListAdapter.java +++ b/src/com/owncloud/android/ui/adapter/FileListListAdapter.java @@ -57,13 +57,26 @@ public class FileListListAdapter extends CursorAdapter implements ListAdapter { private Account mAccount; private TransferServiceGetter mTransferServiceGetter; + public FileListListAdapter(Context context, TransferServiceGetter transferServiceGetter) { - super(context, null, 0); + super(context, null, FLAG_AUTO_REQUERY); mContext = context; mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext); mTransferServiceGetter = transferServiceGetter; } + public void setStorageManager(FileDataStorageManager storageManager) { + mStorageManager = storageManager; + } + + @Override + protected void onContentChanged() { + Log_OC.d(TAG, "onContentChanged() start"); + super.onContentChanged(); + + notifyDataSetChanged(); + Log_OC.d(TAG, "onContentChanged() end"); + } /* @Override public boolean areAllItemsEnabled() { @@ -115,31 +128,37 @@ public class FileListListAdapter extends CursorAdapter implements ListAdapter { } */ - /** - * Change the adapted directory for a new one - * @param folder New file to adapt. Can be NULL, meaning "no content to adapt". - * @param updatedStorageManager Optional updated storage manager; used to replace mStorageManager if is different (and not NULL) - */ - public void swapDirectory(OCFile folder, FileDataStorageManager updatedStorageManager) { - if (updatedStorageManager != null && updatedStorageManager != mStorageManager) { - mStorageManager = updatedStorageManager; - mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext); - } - Cursor newCursor = null; - if (mStorageManager != null) { - //mFiles = mStorageManager.getFolderContent(mFile); - newCursor = mStorageManager.getContent(folder.getFileId()); - } - Cursor oldCursor = swapCursor(newCursor); - if (oldCursor != null){ - oldCursor.close(); - } - notifyDataSetChanged(); - } +// /** +// * Change the adapted directory for a new one +// * @param folder New file to adapt. Can be NULL, meaning "no content to adapt". +// * @param updatedStorageManager Optional updated storage manager; used to replace mStorageManager if is different (and not NULL) +// */ +// public void swapDirectory(OCFile folder, FileDataStorageManager updatedStorageManager) { +// if (updatedStorageManager != null && updatedStorageManager != mStorageManager) { +// mStorageManager = updatedStorageManager; +// mAccount = AccountUtils.getCurrentOwnCloudAccount(mContext); +// } +// Cursor newCursor = null; +// if (mStorageManager != null) { +// //mFiles = mStorageManager.getFolderContent(mFile); +// newCursor = mStorageManager.getContent(folder.getFileId()); +// Uri uri = Uri.withAppendedPath( +// ProviderTableMeta.CONTENT_URI_DIR, +// String.valueOf(folder.getFileId())); +// Log_OC.d(TAG, "swapDirectory Uri " + uri); +// newCursor.setNotificationUri(mContext.getContentResolver(), uri); +// +// } +// Cursor oldCursor = swapCursor(newCursor); +// if (oldCursor != null){ +// oldCursor.close(); +// } +// notifyDataSetChanged(); +// } @Override public void bindView(View view, Context context, Cursor cursor) { - Log_OC.d(TAG, "bindView start"); + //Log_OC.d(TAG, "bindView start"); OCFile file = mStorageManager.createFileInstance(cursor); @@ -200,12 +219,12 @@ public class FileListListAdapter extends CursorAdapter implements ListAdapter { shareIconV.setVisibility(View.INVISIBLE); } //} - Log_OC.d(TAG, "bindView end"); + //Log_OC.d(TAG, "bindView end"); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { - Log_OC.d(TAG, "newView start"); + //Log_OC.d(TAG, "newView start"); LayoutInflater inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflator.inflate(R.layout.list_item, null); @@ -222,7 +241,7 @@ public class FileListListAdapter extends CursorAdapter implements ListAdapter { }*/ checkBoxV.setVisibility(View.VISIBLE); } - Log_OC.d(TAG, "newView end"); + //Log_OC.d(TAG, "newView end"); return view; } diff --git a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java index b7adb26a..d6e2e163 100644 --- a/src/com/owncloud/android/ui/fragment/OCFileListFragment.java +++ b/src/com/owncloud/android/ui/fragment/OCFileListFragment.java @@ -24,7 +24,9 @@ import java.util.List; import com.owncloud.android.R; import com.owncloud.android.authentication.AccountUtils; import com.owncloud.android.datamodel.FileDataStorageManager; +import com.owncloud.android.datamodel.FileListCursorLoader; import com.owncloud.android.datamodel.OCFile; +import com.owncloud.android.db.ProviderMeta.ProviderTableMeta; import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder; import com.owncloud.android.files.services.FileUploader.FileUploaderBinder; import com.owncloud.android.lib.common.operations.OnRemoteOperationListener; @@ -33,6 +35,7 @@ import com.owncloud.android.operations.RemoveFileOperation; import com.owncloud.android.operations.RenameFileOperation; import com.owncloud.android.operations.SynchronizeFileOperation; import com.owncloud.android.ui.activity.FileActivity; +import com.owncloud.android.ui.ExtendedListView; import com.owncloud.android.ui.activity.TransferServiceGetter; import com.owncloud.android.ui.adapter.FileListListAdapter; import com.owncloud.android.ui.dialog.ConfirmationDialogFragment; @@ -46,8 +49,12 @@ import com.owncloud.android.utils.Log_OC; import android.accounts.Account; import android.app.Activity; import android.database.Cursor; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.support.v4.app.LoaderManager; +import android.support.v4.app.LoaderManager.LoaderCallbacks; +import android.support.v4.content.Loader; import android.view.ContextMenu; import android.view.MenuInflater; import android.view.MenuItem; @@ -61,7 +68,9 @@ import android.widget.AdapterView.AdapterContextMenuInfo; * @author Bartek Przybylski * */ -public class OCFileListFragment extends ExtendedListFragment implements EditNameDialogListener, ConfirmationDialogFragmentListener { +public class OCFileListFragment extends ExtendedListFragment + implements EditNameDialogListener, ConfirmationDialogFragmentListener, + LoaderCallbacks{ private static final String TAG = OCFileListFragment.class.getSimpleName(); @@ -73,10 +82,14 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName private static final String KEY_TOPS = "TOPS"; private static final String KEY_HEIGHT_CELL = "HEIGHT_CELL"; + private static final int LOADER_ID = 0; + private OCFileListFragment.ContainerActivity mContainerActivity; private OCFile mFile = null; private FileListListAdapter mAdapter; + private LoaderManager mLoaderManager; + private FileListCursorLoader mCursorLoader; private Handler mHandler; private OCFile mTargetFile; @@ -110,8 +123,9 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Log_OC.e(TAG, "onActivityCreated() start"); - + mAdapter = new FileListListAdapter(getSherlockActivity(), mContainerActivity); + mLoaderManager = getLoaderManager(); if (savedInstanceState != null) { mFile = savedInstanceState.getParcelable(EXTRA_FILE); @@ -128,12 +142,16 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName } + // Initialize loaderManager and makes it active + mLoaderManager.initLoader(LOADER_ID, null, this); + setListAdapter(mAdapter); registerForContextMenu(getListView()); - getListView().setOnCreateContextMenuListener(this); + getListView().setOnCreateContextMenuListener(this); mHandler = new Handler(); + } @@ -210,20 +228,21 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName int top = mTops.remove(mTops.size() - 1); - mList.setSelectionFromTop(firstPosition, top); + ExtendedListView list = (ExtendedListView) getListView(); + list.setSelectionFromTop(firstPosition, top); // Move the scroll if the selection is not visible int indexPosition = mHeightCell*index; - int height = mList.getHeight(); + int height = list.getHeight(); if (indexPosition > height) { if (android.os.Build.VERSION.SDK_INT >= 11) { - mList.smoothScrollToPosition(index); + list.smoothScrollToPosition(index); } else if (android.os.Build.VERSION.SDK_INT >= 8) { - mList.setSelectionFromTop(index, 0); + list.setSelectionFromTop(index, 0); } } @@ -237,10 +256,12 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName mIndexes.add(index); - int firstPosition = mList.getFirstVisiblePosition(); + ExtendedListView list = (ExtendedListView) getListView(); + + int firstPosition = list.getFirstVisiblePosition(); mFirstPositions.add(firstPosition); - View view = mList.getChildAt(0); + View view = list.getChildAt(0); int top = (view == null) ? 0 : view.getTop() ; mTops.add(top); @@ -527,15 +548,45 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName directory = storageManager.getFileById(directory.getParentId()); } - mAdapter.swapDirectory(directory, storageManager); + swapDirectory(directory.getFileId(), storageManager); + if (mFile == null || !mFile.equals(directory)) { - mList.setSelectionFromTop(0, 0); + ((ExtendedListView) getListView()).setSelectionFromTop(0, 0); } mFile = directory; } } + /** + * Change the adapted directory for a new one + * @param folder New file to adapt. Can be NULL, meaning "no content to adapt". + * @param updatedStorageManager Optional updated storage manager; used to replace mStorageManager if is different (and not NULL) + */ + public void swapDirectory(long parentId, FileDataStorageManager updatedStorageManager) { + FileDataStorageManager storageManager = null; + if (updatedStorageManager != null && updatedStorageManager != storageManager) { + storageManager = updatedStorageManager; + } + Cursor newCursor = null; + if (storageManager != null) { + mAdapter.setStorageManager(storageManager); + mCursorLoader.setParentId(parentId); + newCursor = mCursorLoader.loadInBackground();//storageManager.getContent(folder.getFileId()); + Uri uri = Uri.withAppendedPath( + ProviderTableMeta.CONTENT_URI_DIR, + String.valueOf(parentId)); + Log_OC.d(TAG, "swapDirectory Uri " + uri); + //newCursor.setNotificationUri(getSherlockActivity().getContentResolver(), uri); + + } + Cursor oldCursor = mAdapter.swapCursor(newCursor); + if (oldCursor != null){ + oldCursor.close(); + } + mAdapter.notifyDataSetChanged(); + } + /** * Interface to implement by any Activity that includes some instance of FileListFragment @@ -626,5 +677,70 @@ public class OCFileListFragment extends ExtendedListFragment implements EditName Log_OC.d(TAG, "REMOVAL CANCELED"); } + /*** + * LoaderManager.LoaderCallbacks + */ + + /** + * Instantiate and return a new Loader for the given ID. This is where the cursor is created. + */ + @Override + public Loader onCreateLoader(int id, Bundle bundle) { + Log_OC.d(TAG, "onCreateLoader start"); + mCursorLoader = new FileListCursorLoader((FileActivity)getSherlockActivity(), + ((FileActivity)getSherlockActivity()).getStorageManager()); + if (mFile != null) { + mCursorLoader.setParentId(mFile.getFileId()); + } else { + mCursorLoader.setParentId(1); + } + Log_OC.d(TAG, "onCreateLoader end"); + return mCursorLoader; + } + + + /** + * Called when a previously created loader has finished its load. Here, you can start using the cursor. + */ + @Override + public void onLoadFinished(Loader loader, Cursor cursor) { + Log_OC.d(TAG, "onLoadFinished start"); + + FileDataStorageManager storageManager = ((FileActivity)getSherlockActivity()).getStorageManager(); + if (storageManager != null) { + mCursorLoader.setStorageManager(storageManager); + if (mFile != null) { + mCursorLoader.setParentId(mFile.getFileId()); + } else { + mCursorLoader.setParentId(1); + } + mAdapter.swapCursor(mCursorLoader.loadInBackground()); + } + +// if(mAdapter != null && cursor != null) +// mAdapter.swapCursor(cursor); //swap the new cursor in. +// else +// Log_OC.d(TAG,"OnLoadFinished: mAdapter is null"); + + Log_OC.d(TAG, "onLoadFinished end"); + } + + + /** + * Called when a previously created loader is being reset, thus making its data unavailable. + * It is being reset in order to create a new cursor to query different data. + * This is called when the last Cursor provided to onLoadFinished() above is about to be closed. + * We need to make sure we are no longer using it. + */ + @Override + public void onLoaderReset(Loader loader) { + Log_OC.d(TAG, "onLoadReset start"); + if(mAdapter != null) + mAdapter.swapCursor(null); + else + Log_OC.d(TAG,"OnLoadFinished: mAdapter is null"); + Log_OC.d(TAG, "onLoadReset end"); + } + }