Loading packages/DocumentsUI/res/layout/fragment_directory.xml +8 −0 Original line number Diff line number Diff line Loading @@ -42,4 +42,12 @@ android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:visibility="gone" /> <Button android:id="@+id/more" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="@string/more" android:visibility="gone" /> </FrameLayout> packages/DocumentsUI/res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -60,4 +60,7 @@ <string name="toast_no_application">Can\'t open file</string> <string name="toast_failed_delete">Unable to delete some documents</string> <string name="more">More</string> <string name="loading">Loading\u2026</string> </resources> packages/DocumentsUI/res/xml/document_provider.xml 0 → 100644 +19 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2013 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <documents-provider xmlns:android="http://schemas.android.com/apk/res/android" android:customRoots="true"> </documents-provider> packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +34 −7 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.Loader; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Point; import android.net.Uri; Loading @@ -54,6 +55,7 @@ import android.widget.AbsListView.MultiChoiceModeListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.GridView; import android.widget.ImageView; import android.widget.ListView; Loading @@ -79,6 +81,7 @@ public class DirectoryFragment extends Fragment { private View mEmptyView; private ListView mListView; private GridView mGridView; private Button mMoreView; private AbsListView mCurrentView; Loading @@ -93,7 +96,7 @@ public class DirectoryFragment extends Fragment { private Point mThumbSize; private DocumentsAdapter mAdapter; private LoaderCallbacks<List<Document>> mCallbacks; private LoaderCallbacks<DirectoryResult> mCallbacks; private static final String EXTRA_TYPE = "type"; private static final String EXTRA_URI = "uri"; Loading Loading @@ -150,14 +153,16 @@ public class DirectoryFragment extends Fragment { mGridView.setOnItemClickListener(mItemListener); mGridView.setMultiChoiceModeListener(mMultiListener); mMoreView = (Button) view.findViewById(R.id.more); mAdapter = new DocumentsAdapter(); final Uri uri = getArguments().getParcelable(EXTRA_URI); mType = getArguments().getInt(EXTRA_TYPE); mCallbacks = new LoaderCallbacks<List<Document>>() { mCallbacks = new LoaderCallbacks<DirectoryResult>() { @Override public Loader<List<Document>> onCreateLoader(int id, Bundle args) { public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { final DisplayState state = getDisplayState(DirectoryFragment.this); mFilter = new MimePredicate(state.acceptMimes); Loading Loading @@ -189,12 +194,34 @@ public class DirectoryFragment extends Fragment { } @Override public void onLoadFinished(Loader<List<Document>> loader, List<Document> data) { mAdapter.swapDocuments(data); public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { mAdapter.swapDocuments(result.contents); final Cursor cursor = result.cursor; if (cursor != null && cursor.getExtras() .getBoolean(DocumentsContract.EXTRA_HAS_MORE, false)) { mMoreView.setText(R.string.more); mMoreView.setVisibility(View.VISIBLE); mMoreView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mMoreView.setText(R.string.loading); final Bundle bundle = new Bundle(); bundle.putBoolean(DocumentsContract.EXTRA_REQUEST_MORE, true); try { cursor.respond(bundle); } catch (Exception e) { Log.w(TAG, "Failed to respond: " + e); } } }); } else { mMoreView.setVisibility(View.GONE); } } @Override public void onLoaderReset(Loader<List<Document>> loader) { public void onLoaderReset(Loader<DirectoryResult> loader) { mAdapter.swapDocuments(null); } }; Loading Loading @@ -407,7 +434,7 @@ public class DirectoryFragment extends Fragment { public void swapDocuments(List<Document> documents) { mDocuments = documents; if (documents != null && documents.isEmpty()) { if (mDocuments != null && mDocuments.isEmpty()) { mEmptyView.setVisibility(View.VISIBLE); } else { mEmptyView.setVisibility(View.GONE); Loading packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java +43 −49 Original line number Diff line number Diff line Loading @@ -36,29 +36,27 @@ import com.google.android.collect.Lists; import libcore.io.IoUtils; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; public class DirectoryLoader extends UriDerivativeLoader<List<Document>> { class DirectoryResult implements AutoCloseable { Cursor cursor; List<Document> contents = Lists.newArrayList(); Exception e; @Override public void close() throws Exception { IoUtils.closeQuietly(cursor); } } public class DirectoryLoader extends UriDerivativeLoader<Uri, DirectoryResult> { private final int mType; private Predicate<Document> mFilter; private Comparator<Document> mSortOrder; /** * Stub result that represents an internal error. */ public static class ExceptionResult extends LinkedList<Document> { public final Exception e; public ExceptionResult(Exception e) { this.e = e; } } public DirectoryLoader(Context context, Uri uri, int type, Predicate<Document> filter, Comparator<Document> sortOrder) { super(context, uri); Loading @@ -68,23 +66,24 @@ public class DirectoryLoader extends UriDerivativeLoader<List<Document>> { } @Override public List<Document> loadInBackground(Uri uri, CancellationSignal signal) { public DirectoryResult loadInBackground(Uri uri, CancellationSignal signal) { final DirectoryResult result = new DirectoryResult(); try { return loadInBackgroundInternal(uri, signal); loadInBackgroundInternal(result, uri, signal); } catch (Exception e) { return new ExceptionResult(e); result.e = e; } return result; } private List<Document> loadInBackgroundInternal(Uri uri, CancellationSignal signal) { final ArrayList<Document> result = Lists.newArrayList(); // TODO: subscribe to the notify uri from query private void loadInBackgroundInternal( DirectoryResult result, Uri uri, CancellationSignal signal) { final ContentResolver resolver = getContext().getContentResolver(); final Cursor cursor = resolver.query(uri, null, null, null, getQuerySortOrder(), signal); try { while (cursor != null && cursor.moveToNext()) { result.cursor = cursor; result.cursor.registerContentObserver(mObserver); while (cursor.moveToNext()) { Document doc = null; switch (mType) { case TYPE_NORMAL: Loading @@ -103,18 +102,13 @@ public class DirectoryLoader extends UriDerivativeLoader<List<Document>> { } if (doc != null && (mFilter == null || mFilter.apply(doc))) { result.add(doc); } result.contents.add(doc); } } finally { IoUtils.closeQuietly(cursor); } if (mSortOrder != null) { Collections.sort(result, mSortOrder); Collections.sort(result.contents, mSortOrder); } return result; } private String getQuerySortOrder() { Loading Loading
packages/DocumentsUI/res/layout/fragment_directory.xml +8 −0 Original line number Diff line number Diff line Loading @@ -42,4 +42,12 @@ android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:visibility="gone" /> <Button android:id="@+id/more" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="@string/more" android:visibility="gone" /> </FrameLayout>
packages/DocumentsUI/res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -60,4 +60,7 @@ <string name="toast_no_application">Can\'t open file</string> <string name="toast_failed_delete">Unable to delete some documents</string> <string name="more">More</string> <string name="loading">Loading\u2026</string> </resources>
packages/DocumentsUI/res/xml/document_provider.xml 0 → 100644 +19 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="utf-8"?> <!-- Copyright (C) 2013 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <documents-provider xmlns:android="http://schemas.android.com/apk/res/android" android:customRoots="true"> </documents-provider>
packages/DocumentsUI/src/com/android/documentsui/DirectoryFragment.java +34 −7 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.Loader; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Point; import android.net.Uri; Loading @@ -54,6 +55,7 @@ import android.widget.AbsListView.MultiChoiceModeListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.GridView; import android.widget.ImageView; import android.widget.ListView; Loading @@ -79,6 +81,7 @@ public class DirectoryFragment extends Fragment { private View mEmptyView; private ListView mListView; private GridView mGridView; private Button mMoreView; private AbsListView mCurrentView; Loading @@ -93,7 +96,7 @@ public class DirectoryFragment extends Fragment { private Point mThumbSize; private DocumentsAdapter mAdapter; private LoaderCallbacks<List<Document>> mCallbacks; private LoaderCallbacks<DirectoryResult> mCallbacks; private static final String EXTRA_TYPE = "type"; private static final String EXTRA_URI = "uri"; Loading Loading @@ -150,14 +153,16 @@ public class DirectoryFragment extends Fragment { mGridView.setOnItemClickListener(mItemListener); mGridView.setMultiChoiceModeListener(mMultiListener); mMoreView = (Button) view.findViewById(R.id.more); mAdapter = new DocumentsAdapter(); final Uri uri = getArguments().getParcelable(EXTRA_URI); mType = getArguments().getInt(EXTRA_TYPE); mCallbacks = new LoaderCallbacks<List<Document>>() { mCallbacks = new LoaderCallbacks<DirectoryResult>() { @Override public Loader<List<Document>> onCreateLoader(int id, Bundle args) { public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { final DisplayState state = getDisplayState(DirectoryFragment.this); mFilter = new MimePredicate(state.acceptMimes); Loading Loading @@ -189,12 +194,34 @@ public class DirectoryFragment extends Fragment { } @Override public void onLoadFinished(Loader<List<Document>> loader, List<Document> data) { mAdapter.swapDocuments(data); public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { mAdapter.swapDocuments(result.contents); final Cursor cursor = result.cursor; if (cursor != null && cursor.getExtras() .getBoolean(DocumentsContract.EXTRA_HAS_MORE, false)) { mMoreView.setText(R.string.more); mMoreView.setVisibility(View.VISIBLE); mMoreView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mMoreView.setText(R.string.loading); final Bundle bundle = new Bundle(); bundle.putBoolean(DocumentsContract.EXTRA_REQUEST_MORE, true); try { cursor.respond(bundle); } catch (Exception e) { Log.w(TAG, "Failed to respond: " + e); } } }); } else { mMoreView.setVisibility(View.GONE); } } @Override public void onLoaderReset(Loader<List<Document>> loader) { public void onLoaderReset(Loader<DirectoryResult> loader) { mAdapter.swapDocuments(null); } }; Loading Loading @@ -407,7 +434,7 @@ public class DirectoryFragment extends Fragment { public void swapDocuments(List<Document> documents) { mDocuments = documents; if (documents != null && documents.isEmpty()) { if (mDocuments != null && mDocuments.isEmpty()) { mEmptyView.setVisibility(View.VISIBLE); } else { mEmptyView.setVisibility(View.GONE); Loading
packages/DocumentsUI/src/com/android/documentsui/DirectoryLoader.java +43 −49 Original line number Diff line number Diff line Loading @@ -36,29 +36,27 @@ import com.google.android.collect.Lists; import libcore.io.IoUtils; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.LinkedList; import java.util.List; public class DirectoryLoader extends UriDerivativeLoader<List<Document>> { class DirectoryResult implements AutoCloseable { Cursor cursor; List<Document> contents = Lists.newArrayList(); Exception e; @Override public void close() throws Exception { IoUtils.closeQuietly(cursor); } } public class DirectoryLoader extends UriDerivativeLoader<Uri, DirectoryResult> { private final int mType; private Predicate<Document> mFilter; private Comparator<Document> mSortOrder; /** * Stub result that represents an internal error. */ public static class ExceptionResult extends LinkedList<Document> { public final Exception e; public ExceptionResult(Exception e) { this.e = e; } } public DirectoryLoader(Context context, Uri uri, int type, Predicate<Document> filter, Comparator<Document> sortOrder) { super(context, uri); Loading @@ -68,23 +66,24 @@ public class DirectoryLoader extends UriDerivativeLoader<List<Document>> { } @Override public List<Document> loadInBackground(Uri uri, CancellationSignal signal) { public DirectoryResult loadInBackground(Uri uri, CancellationSignal signal) { final DirectoryResult result = new DirectoryResult(); try { return loadInBackgroundInternal(uri, signal); loadInBackgroundInternal(result, uri, signal); } catch (Exception e) { return new ExceptionResult(e); result.e = e; } return result; } private List<Document> loadInBackgroundInternal(Uri uri, CancellationSignal signal) { final ArrayList<Document> result = Lists.newArrayList(); // TODO: subscribe to the notify uri from query private void loadInBackgroundInternal( DirectoryResult result, Uri uri, CancellationSignal signal) { final ContentResolver resolver = getContext().getContentResolver(); final Cursor cursor = resolver.query(uri, null, null, null, getQuerySortOrder(), signal); try { while (cursor != null && cursor.moveToNext()) { result.cursor = cursor; result.cursor.registerContentObserver(mObserver); while (cursor.moveToNext()) { Document doc = null; switch (mType) { case TYPE_NORMAL: Loading @@ -103,18 +102,13 @@ public class DirectoryLoader extends UriDerivativeLoader<List<Document>> { } if (doc != null && (mFilter == null || mFilter.apply(doc))) { result.add(doc); } result.contents.add(doc); } } finally { IoUtils.closeQuietly(cursor); } if (mSortOrder != null) { Collections.sort(result, mSortOrder); Collections.sort(result.contents, mSortOrder); } return result; } private String getQuerySortOrder() { Loading