Эх сурвалжийг харах

Add FileListCursorLoader. Update data using CursorLoader and LoaderManager. Update filelist when a file/folder is deleted

masensio 11 жил өмнө
parent
commit
c9626772a1

+ 2 - 1
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 {
             */
         //}
     }
+    
 }

+ 76 - 0
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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+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;
+    }
+}

+ 42 - 2
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();

+ 45 - 26
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;
       
     }

+ 127 - 11
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<Cursor>{
     
     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<Cursor>
+     */
+    
+    /**
+     * Instantiate and return a new Loader for the given ID. This is where the cursor is created.
+     */
+    @Override
+    public Loader<Cursor> 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<Cursor> 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<Cursor> 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");
+    }
+
 
 }