DirectoryFragment.java revision 28c05ee8931cecf4c51c470e0043d30196010c49
19e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey/* 29e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * Copyright (C) 2013 The Android Open Source Project 39e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * 49e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 59e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * you may not use this file except in compliance with the License. 69e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * You may obtain a copy of the License at 79e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * 89e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 99e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * 109e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * Unless required by applicable law or agreed to in writing, software 119e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 129e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * See the License for the specific language governing permissions and 149e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey * limitations under the License. 159e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey */ 169e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 179e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeypackage com.android.documentsui; 189e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 199d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport static com.android.documentsui.DocumentsActivity.TAG; 20b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.ACTION_MANAGE; 21b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.MODE_GRID; 22b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport static com.android.documentsui.DocumentsActivity.State.MODE_LIST; 235dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport static com.android.documentsui.model.DocumentInfo.getCursorInt; 245dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport static com.android.documentsui.model.DocumentInfo.getCursorLong; 255dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport static com.android.documentsui.model.DocumentInfo.getCursorString; 269d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 2754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.app.Fragment; 289e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.FragmentManager; 299e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.FragmentTransaction; 309e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.app.LoaderManager.LoaderCallbacks; 314eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.ContentResolver; 329e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Context; 334eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.content.Intent; 349e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.content.Loader; 355dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport android.database.Cursor; 369d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.graphics.Bitmap; 379d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.graphics.Point; 389e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.net.Uri; 399d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.os.AsyncTask; 409e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.os.Bundle; 419e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.provider.DocumentsContract; 425dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkeyimport android.provider.DocumentsContract.Document; 4354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.text.format.DateUtils; 44b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport android.text.format.Formatter; 459d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.text.format.Time; 469d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkeyimport android.util.Log; 47be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.util.SparseBooleanArray; 48be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.view.ActionMode; 499e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.LayoutInflater; 5054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.Menu; 5154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.view.MenuItem; 529e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.View; 539e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.view.ViewGroup; 54be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.widget.AbsListView; 55be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport android.widget.AbsListView.MultiChoiceModeListener; 5654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.AdapterView; 5754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.AdapterView.OnItemClickListener; 58ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport android.widget.BaseAdapter; 5954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeyimport android.widget.GridView; 609e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.ImageView; 619e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.ListView; 629e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkeyimport android.widget.TextView; 634eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkeyimport android.widget.Toast; 649e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 65b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkeyimport com.android.documentsui.DocumentsActivity.State; 66ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkeyimport com.android.documentsui.model.DocumentInfo; 67251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkeyimport com.android.documentsui.model.RootInfo; 68ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport com.android.internal.util.Predicate; 69be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport com.google.android.collect.Lists; 70be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 71be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkeyimport java.util.ArrayList; 72ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkeyimport java.util.List; 73b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkeyimport java.util.concurrent.atomic.AtomicInteger; 7454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 7554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey/** 7654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey * Display the documents inside a single directory. 7754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey */ 7854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkeypublic class DirectoryFragment extends Fragment { 7954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 809fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey private View mEmptyView; 8154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private ListView mListView; 8254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private GridView mGridView; 8354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 84be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey private AbsListView mCurrentView; 85be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 86ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private Predicate<DocumentInfo> mFilter; 879fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 88ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final int TYPE_NORMAL = 1; 89ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static final int TYPE_SEARCH = 2; 90251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey public static final int TYPE_RECENT_OPEN = 3; 91dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 92dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey private int mType = TYPE_NORMAL; 93dc2963aecaf38bf53d6de82957412a486049c207Jeff Sharkey 949d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private Point mThumbSize; 959d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 969e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey private DocumentsAdapter mAdapter; 97b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey private LoaderCallbacks<DirectoryResult> mCallbacks; 989e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 99b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static final String EXTRA_TYPE = "type"; 100251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey private static final String EXTRA_AUTHORITY = "authority"; 101251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey private static final String EXTRA_ROOT_ID = "rootId"; 102251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey private static final String EXTRA_DOC_ID = "docId"; 103251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey private static final String EXTRA_QUERY = "query"; 1049e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 105b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private static AtomicInteger sLoaderId = new AtomicInteger(4000); 106b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 1075dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey private int mLastSortOrder = -1; 1085dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 109b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey private final int mLoaderId = sLoaderId.incrementAndGet(); 110b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 111b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public static void showNormal(FragmentManager fm, Uri uri) { 112251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey show(fm, TYPE_NORMAL, uri.getAuthority(), null, DocumentsContract.getDocumentId(uri), null); 113b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 114b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 115b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public static void showSearch(FragmentManager fm, Uri uri, String query) { 116251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey show(fm, TYPE_SEARCH, uri.getAuthority(), null, DocumentsContract.getDocumentId(uri), 117251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey query); 118b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 119b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 120b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public static void showRecentsOpen(FragmentManager fm) { 121251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey show(fm, TYPE_RECENT_OPEN, null, null, null, null); 122b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 1239e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 124251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey private static void show(FragmentManager fm, int type, String authority, String rootId, 125251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey String docId, String query) { 1269e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final Bundle args = new Bundle(); 127b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey args.putInt(EXTRA_TYPE, type); 128251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey args.putString(EXTRA_AUTHORITY, authority); 129251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey args.putString(EXTRA_ROOT_ID, rootId); 130251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey args.putString(EXTRA_DOC_ID, docId); 131251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey args.putString(EXTRA_QUERY, query); 1329e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 1339e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final DirectoryFragment fragment = new DirectoryFragment(); 1349e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey fragment.setArguments(args); 1359e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 1369e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final FragmentTransaction ft = fm.beginTransaction(); 13766516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey ft.replace(R.id.container_directory, fragment); 1389e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey ft.commitAllowingStateLoss(); 1399e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 1409e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 141ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public static DirectoryFragment get(FragmentManager fm) { 142ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey // TODO: deal with multiple directories shown at once 14366516697a29cf00d93893a1011d3befc7c1ee37fJeff Sharkey return (DirectoryFragment) fm.findFragmentById(R.id.container_directory); 144ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 145ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 1469e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 1479e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey public View onCreateView( 1489e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 1499e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey final Context context = inflater.getContext(); 15054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey final View view = inflater.inflate(R.layout.fragment_directory, container, false); 15154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1529fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView = view.findViewById(android.R.id.empty); 1539fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 15454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView = (ListView) view.findViewById(R.id.list); 15554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setOnItemClickListener(mItemListener); 156be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setMultiChoiceModeListener(mMultiListener); 15754e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 15854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView = (GridView) view.findViewById(R.id.grid); 15954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setOnItemClickListener(mItemListener); 160be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setMultiChoiceModeListener(mMultiListener); 16154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1625dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey return view; 1635dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 16454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 1655dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey @Override 1665dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public void onActivityCreated(Bundle savedInstanceState) { 1675dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey super.onActivityCreated(savedInstanceState); 1685dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 1695dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Context context = getActivity(); 1705dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 171251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey mAdapter = new DocumentsAdapter(); 172b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mType = getArguments().getInt(EXTRA_TYPE); 1739e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 174b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey mCallbacks = new LoaderCallbacks<DirectoryResult>() { 1759e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 176b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public Loader<DirectoryResult> onCreateLoader(int id, Bundle args) { 177b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 1781482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey 179251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String authority = getArguments().getString(EXTRA_AUTHORITY); 180251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String rootId = getArguments().getString(EXTRA_ROOT_ID); 181251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docId = getArguments().getString(EXTRA_DOC_ID); 182251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String query = getArguments().getString(EXTRA_QUERY); 183251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey 18454ca29a5b94c2edf461c5433825d4ae17469fd7cJeff Sharkey Uri contentsUri; 185251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey switch (mType) { 186251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_NORMAL: 187251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey contentsUri = DocumentsContract.buildChildDocumentsUri(authority, docId); 188251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey return new DirectoryLoader(context, rootId, contentsUri, state.sortOrder); 189251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_SEARCH: 190251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey contentsUri = DocumentsContract.buildSearchDocumentsUri( 191251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey authority, docId, query); 192251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey return new DirectoryLoader(context, rootId, contentsUri, state.sortOrder); 193251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey case TYPE_RECENT_OPEN: 194348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 195348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey final List<RootInfo> matchingRoots = roots.getMatchingRoots(state); 196348ad6866b91afa4d59d45df533ef88094c74d13Jeff Sharkey return new RecentLoader(context, matchingRoots); 197251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey default: 198251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey throw new IllegalStateException("Unknown type " + mType); 199bc2971d2499f5bf5534ced7296ece630ca902738Jeff Sharkey 200251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } 2019e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2029e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 2039e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 204b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public void onLoadFinished(Loader<DirectoryResult> loader, DirectoryResult result) { 2055dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mAdapter.swapCursor(result.cursor); 2069e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2079e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 2089e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 209b448660a227f93d7bd5c5d019a21745e67c2f54dJeff Sharkey public void onLoaderReset(Loader<DirectoryResult> loader) { 2105dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mAdapter.swapCursor(null); 2119e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 2129e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey }; 2139e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 214b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey updateDisplayState(); 21554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 2169e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 21728c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey @Override 21828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey public void onStart() { 21928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey super.onStart(); 22028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey updateDisplayState(); 22128c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey } 22228c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 223b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey public void updateDisplayState() { 224b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(this); 22554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 2265dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (mLastSortOrder != state.sortOrder) { 2275dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); 2285dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mLastSortOrder = state.sortOrder; 2295dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 2305dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 231b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mListView.smoothScrollToPosition(0); 232b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey mGridView.smoothScrollToPosition(0); 23354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 2344eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mListView.setVisibility(state.mode == MODE_LIST ? View.VISIBLE : View.GONE); 2354eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mGridView.setVisibility(state.mode == MODE_GRID ? View.VISIBLE : View.GONE); 23654e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 2375dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mFilter = new MimePredicate(state.acceptMimes); 2385dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 239be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey final int choiceMode; 2401482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey if (state.allowMultiple) { 241be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey choiceMode = ListView.CHOICE_MODE_MULTIPLE_MODAL; 242be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 243be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey choiceMode = ListView.CHOICE_MODE_NONE; 244be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 245be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 2469d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final int thumbSize; 2474eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (state.mode == MODE_GRID) { 2489d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey thumbSize = getResources().getDimensionPixelSize(R.dimen.grid_width); 24954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setAdapter(null); 250be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setChoiceMode(ListView.CHOICE_MODE_NONE); 25154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setAdapter(mAdapter); 252be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setColumnWidth(getResources().getDimensionPixelSize(R.dimen.grid_width)); 25354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setNumColumns(GridView.AUTO_FIT); 254be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setChoiceMode(choiceMode); 255be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView = mGridView; 2564eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (state.mode == MODE_LIST) { 2579d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey thumbSize = getResources().getDimensionPixelSize(android.R.dimen.app_icon_size); 25854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mGridView.setAdapter(null); 259be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mGridView.setChoiceMode(ListView.CHOICE_MODE_NONE); 26054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey mListView.setAdapter(mAdapter); 261be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mListView.setChoiceMode(choiceMode); 262be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView = mListView; 2631482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey } else { 2641482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey throw new IllegalStateException(); 26554e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 2669d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 2679d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mThumbSize = new Point(thumbSize, thumbSize); 26854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 26954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 27054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey private OnItemClickListener mItemListener = new OnItemClickListener() { 27154e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey @Override 27254e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 2735dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(position); 274251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor); 275a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey if (mFilter.apply(doc)) { 276a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey ((DocumentsActivity) getActivity()).onDocumentPicked(doc); 277a5599ef636e37cb0b6474349936999be1afe6987Jeff Sharkey } 27854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 27954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey }; 28054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 281be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey private MultiChoiceModeListener mMultiListener = new MultiChoiceModeListener() { 282be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 283be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onCreateActionMode(ActionMode mode, Menu menu) { 284be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mode.getMenuInflater().inflate(R.menu.mode_directory, menu); 285be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 286be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 287be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 288be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 289be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onPrepareActionMode(ActionMode mode, Menu menu) { 290b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 2914eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 2924eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem open = menu.findItem(R.id.menu_open); 2934eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem share = menu.findItem(R.id.menu_share); 2944eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final MenuItem delete = menu.findItem(R.id.menu_delete); 2954eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 2964eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final boolean manageMode = state.action == ACTION_MANAGE; 2974eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey open.setVisible(!manageMode); 2984eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey share.setVisible(manageMode); 2994eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey delete.setVisible(manageMode); 3004eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 301be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 302be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 303be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 304be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 305be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public boolean onActionItemClicked(ActionMode mode, MenuItem item) { 3064eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final SparseBooleanArray checked = mCurrentView.getCheckedItemPositions(); 307ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey final ArrayList<DocumentInfo> docs = Lists.newArrayList(); 3084eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int size = checked.size(); 3094eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey for (int i = 0; i < size; i++) { 3104eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (checked.valueAt(i)) { 3115dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(checked.keyAt(i)); 312251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final DocumentInfo doc = DocumentInfo.fromDirectoryCursor(cursor); 3134eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey docs.add(doc); 314be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 3154eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 3164eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 3174eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final int id = item.getItemId(); 3184eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (id == R.id.menu_open) { 3194eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey DocumentsActivity.get(DirectoryFragment.this).onDocumentsPicked(docs); 320b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 3214eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return true; 322be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 3234eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (id == R.id.menu_share) { 3244eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey onShareDocuments(docs); 325b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 326be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return true; 3274eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 3284eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (id == R.id.menu_delete) { 3294eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey onDeleteDocuments(docs); 330b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mode.finish(); 3314eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey return true; 3324eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 333be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } else { 334be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey return false; 335be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 336be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 337be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 338be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 339be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public void onDestroyActionMode(ActionMode mode) { 340be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey // ignored 341be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 342be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 343be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey @Override 344be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey public void onItemCheckedStateChanged( 345be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey ActionMode mode, int position, long id, boolean checked) { 346be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey if (checked) { 347be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey // Directories cannot be checked 3485dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = mAdapter.getItem(position); 3495dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 3505dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType)) { 351be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mCurrentView.setItemChecked(position, false); 352be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 353be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 354be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 355be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey mode.setTitle(getResources() 356be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey .getString(R.string.mode_selected_count, mCurrentView.getCheckedItemCount())); 357be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey } 358be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey }; 359be8b12e687bd10a526b1f54c2d8a52abdad15d85Jeff Sharkey 360ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private void onShareDocuments(List<DocumentInfo> docs) { 361b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey Intent intent; 362b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (docs.size() == 1) { 363b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final DocumentInfo doc = docs.get(0); 364b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 365b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent = new Intent(Intent.ACTION_SEND); 366b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 367b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.addCategory(Intent.CATEGORY_DEFAULT); 368b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.setType(doc.mimeType); 369b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.putExtra(Intent.EXTRA_STREAM, doc.uri); 3704eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 371b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } else if (docs.size() > 1) { 3724eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent = new Intent(Intent.ACTION_SEND_MULTIPLE); 3734eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 3744eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.addCategory(Intent.CATEGORY_DEFAULT); 375b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 376b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final ArrayList<String> mimeTypes = Lists.newArrayList(); 377b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final ArrayList<Uri> uris = Lists.newArrayList(); 378b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (DocumentInfo doc : docs) { 379b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey mimeTypes.add(doc.mimeType); 380b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey uris.add(doc.uri); 381b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 382b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 383b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent.setType(findCommonMimeType(mimeTypes)); 3844eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); 385b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 3864eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else { 387b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return; 3884eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 3894eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 390b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey intent = Intent.createChooser(intent, getActivity().getText(R.string.share_via)); 3914eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey startActivity(intent); 3924eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 3934eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 394ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey private void onDeleteDocuments(List<DocumentInfo> docs) { 3954eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final Context context = getActivity(); 3964eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ContentResolver resolver = context.getContentResolver(); 3974eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 3984eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey boolean hadTrouble = false; 399ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey for (DocumentInfo doc : docs) { 4004eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (!doc.isDeleteSupported()) { 4014eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey Log.w(TAG, "Skipping " + doc); 4024eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey hadTrouble = true; 4034eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey continue; 4044eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4054eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 406ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey if (!DocumentsContract.deleteDocument(resolver, doc.uri)) { 407ded77187ef53341765fcab8e29cda94810fc2ca5Jeff Sharkey Log.w(TAG, "Failed to delete " + doc); 4084eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey hadTrouble = true; 4094eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4104eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4114eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 4124eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (hadTrouble) { 4134eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey Toast.makeText(context, R.string.toast_failed_delete, Toast.LENGTH_SHORT).show(); 4144eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4154eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } 4164eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 417b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private static State getDisplayState(Fragment fragment) { 4181482789374fb8da3abea8f6f4f272a67205b95dbJeff Sharkey return ((DocumentsActivity) fragment.getActivity()).getDisplayState(); 41954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 42054e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 421954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private interface Footer { 422954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent); 423954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 424954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 425954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private static class LoadingFooter implements Footer { 426954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 427954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 428954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Context context = parent.getContext(); 429954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (convertView == null) { 430954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 431954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_loading, parent, false); 432954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 433954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return convertView; 434954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 435954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 436954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 437954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private class MessageFooter implements Footer { 438954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private final int mIcon; 439954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private final String mMessage; 440954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 441954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public MessageFooter(int icon, String message) { 442954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mIcon = icon; 443954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mMessage = message; 444954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 445954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 446954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 447954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public View getView(View convertView, ViewGroup parent) { 448954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Context context = parent.getContext(); 449954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 450954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 451954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (convertView == null) { 452954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 453954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (state.mode == MODE_LIST) { 454954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_message_list, parent, false); 455954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else if (state.mode == MODE_GRID) { 456954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey convertView = inflater.inflate(R.layout.item_message_grid, parent, false); 457954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 458954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey throw new IllegalStateException(); 459954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 460954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 461954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 462954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 463954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 464954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey icon.setImageResource(mIcon); 465954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey title.setText(mMessage); 466954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return convertView; 467954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 468954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 469954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 470ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey private class DocumentsAdapter extends BaseAdapter { 4715dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey private Cursor mCursor; 472954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private int mCursorCount; 473954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 474954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private List<Footer> mFooters = Lists.newArrayList(); 475ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 4765dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public void swapCursor(Cursor cursor) { 4775dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mCursor = cursor; 478954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mCursorCount = cursor != null ? cursor.getCount() : 0; 479954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 480954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mFooters.clear(); 481954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 482954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final Bundle extras = cursor != null ? cursor.getExtras() : null; 483954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (extras != null) { 484954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final String info = extras.getString(DocumentsContract.EXTRA_INFO); 485954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (info != null) { 4866d97d3c1a2ebac4e3f32c7e5bc134864ace1c17fJeff Sharkey mFooters.add(new MessageFooter(R.drawable.ic_dialog_alert, info)); 487954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 488954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey final String error = extras.getString(DocumentsContract.EXTRA_ERROR); 489954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (error != null) { 4906d97d3c1a2ebac4e3f32c7e5bc134864ace1c17fJeff Sharkey mFooters.add(new MessageFooter(R.drawable.ic_dialog_alert, error)); 491954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 492954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (extras.getBoolean(DocumentsContract.EXTRA_LOADING, false)) { 493954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey mFooters.add(new LoadingFooter()); 494954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 495954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 4969fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 4975dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (isEmpty()) { 4989fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView.setVisibility(View.VISIBLE); 4999fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } else { 5009fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey mEmptyView.setVisibility(View.GONE); 5019fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey } 5029fb567b59112f99e64e0bff6f343188331bad28dJeff Sharkey 503ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey notifyDataSetChanged(); 5049e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 5059e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 5069e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey @Override 507ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public View getView(int position, View convertView, ViewGroup parent) { 508954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 509954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return getDocumentView(position, convertView, parent); 510954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 511954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey position -= mCursorCount; 512954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mFooters.get(position).getView(convertView, parent); 513954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 514954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 515954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 516954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey private View getDocumentView(int position, View convertView, ViewGroup parent) { 517ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final Context context = parent.getContext(); 518b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey final State state = getDisplayState(DirectoryFragment.this); 519ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 5204eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final RootsCache roots = DocumentsApplication.getRootsCache(context); 5214eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache( 5224eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey context, mThumbSize); 5234eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey 524ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey if (convertView == null) { 525ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final LayoutInflater inflater = LayoutInflater.from(context); 5264eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey if (state.mode == MODE_LIST) { 527ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_list, parent, false); 5284eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey } else if (state.mode == MODE_GRID) { 529ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey convertView = inflater.inflate(R.layout.item_doc_grid, parent, false); 530ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } else { 531ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey throw new IllegalStateException(); 532ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 533ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 534ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 5355dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Cursor cursor = getItem(position); 5365dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey 537251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docAuthority = getCursorString(cursor, RootCursorWrapper.COLUMN_AUTHORITY); 538251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final String docRootId = getCursorString(cursor, RootCursorWrapper.COLUMN_ROOT_ID); 5395dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docId = getCursorString(cursor, Document.COLUMN_DOCUMENT_ID); 5405dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); 5415dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docDisplayName = getCursorString(cursor, Document.COLUMN_DISPLAY_NAME); 5425dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final long docLastModified = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED); 5435dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final int docIcon = getCursorInt(cursor, Document.COLUMN_ICON); 5445dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); 5455dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final String docSummary = getCursorString(cursor, Document.COLUMN_SUMMARY); 5465dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final long docSize = getCursorLong(cursor, Document.COLUMN_SIZE); 547ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 548b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ImageView icon = (ImageView) convertView.findViewById(android.R.id.icon); 549ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final TextView title = (TextView) convertView.findViewById(android.R.id.title); 55028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey final View line2 = convertView.findViewById(R.id.line2); 551b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final ImageView icon1 = (ImageView) convertView.findViewById(android.R.id.icon1); 552ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey final TextView summary = (TextView) convertView.findViewById(android.R.id.summary); 553b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView date = (TextView) convertView.findViewById(R.id.date); 554b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey final TextView size = (TextView) convertView.findViewById(R.id.size); 555ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 5569d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) icon.getTag(); 5579d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (oldTask != null) { 5589d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey oldTask.cancel(false); 5599d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 5609d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 5615dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if ((docFlags & Document.FLAG_SUPPORTS_THUMBNAIL) != 0) { 562251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final Uri uri = DocumentsContract.buildDocumentUri(docAuthority, docId); 5635dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey final Bitmap cachedResult = thumbs.get(uri); 5649d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (cachedResult != null) { 5659d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey icon.setImageBitmap(cachedResult); 5669d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 5679d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final ThumbnailAsyncTask task = new ThumbnailAsyncTask(icon, mThumbSize); 5689d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey icon.setImageBitmap(null); 5699d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey icon.setTag(task); 5705dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey task.execute(uri); 5719d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 5725dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } else if (docIcon != 0) { 5730b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey icon.setImageDrawable(IconUtils.loadPackageIcon(context, docAuthority, docIcon)); 5749e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } else { 5750b14db3cf5eac43736462999337c9a3efdc1ac81Jeff Sharkey icon.setImageDrawable(IconUtils.loadMimeIcon(context, docMimeType)); 5769e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 5779e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 5785dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey title.setText(docDisplayName); 579b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 58028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey boolean hasLine2 = false; 58128c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 582251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey if (mType == TYPE_RECENT_OPEN) { 583251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey final RootInfo root = roots.getRoot(docAuthority, docRootId); 584251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey icon1.setVisibility(View.VISIBLE); 585251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey icon1.setImageDrawable(root.loadIcon(context)); 586251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey summary.setText(root.getDirectoryString()); 5875dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey summary.setVisibility(View.VISIBLE); 58828c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey summary.setTextAlignment(TextView.TEXT_ALIGNMENT_TEXT_END); 58928c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 5905dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } else { 591251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey icon1.setVisibility(View.GONE); 592251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey if (docSummary != null) { 593251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey summary.setText(docSummary); 594251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey summary.setVisibility(View.VISIBLE); 59528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 596251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } else { 597251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey summary.setVisibility(View.INVISIBLE); 598251097b3789632000ccdaf7fb7d66a82ff37d882Jeff Sharkey } 599b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 600b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 6015dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (docLastModified == -1) { 6029d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey date.setText(null); 6039d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 6045dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey date.setText(formatTime(context, docLastModified)); 60528c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 6069d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 607b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey 608b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey if (state.showSize) { 609b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setVisibility(View.VISIBLE); 6105dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey if (Document.MIME_TYPE_DIR.equals(docMimeType) || docSize == -1) { 611b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setText(null); 612b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 6135dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey size.setText(Formatter.formatFileSize(context, docSize)); 61428c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey hasLine2 = true; 615b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } 616b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey } else { 617b156f4bf8cdfe475a7116b627d84a281e1a281b7Jeff Sharkey size.setVisibility(View.GONE); 61854e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 619ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey 62028c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey line2.setVisibility(hasLine2 ? View.VISIBLE : View.GONE); 62128c05ee8931cecf4c51c470e0043d30196010c49Jeff Sharkey 622ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey return convertView; 62354e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey } 62454e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 625ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 626ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public int getCount() { 627954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mCursorCount + mFooters.size(); 628ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 6299e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey 630ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 6315dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey public Cursor getItem(int position) { 632954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 6335dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey mCursor.moveToPosition(position); 634954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return mCursor; 635954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 636954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return null; 6375dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey } 638ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 63954e55b740fef1be654c3959aee41ef5ddfa61293Jeff Sharkey 640ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey @Override 641ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey public long getItemId(int position) { 6425dfb345df7cb17b3a7e534a80a270b4afe7934daJeff Sharkey return position; 643ef7184a1aa0be5d496a5cb495a0f9e11f342af44Jeff Sharkey } 644954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 645954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 646954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public int getItemViewType(int position) { 647954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey if (position < mCursorCount) { 648954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return 0; 649954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } else { 650954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return IGNORE_ITEM_VIEW_TYPE; 651954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 652954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 653954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 654954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 655954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public boolean areAllItemsEnabled() { 656954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return false; 657954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 658954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey 659954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey @Override 660954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey public boolean isEnabled(int position) { 661954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey return position < mCursorCount; 662954be0232655d316bc5decbbd35579af902c75c2Jeff Sharkey } 6639e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey } 6649d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 6659d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private static class ThumbnailAsyncTask extends AsyncTask<Uri, Void, Bitmap> { 6669d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private final ImageView mTarget; 6674eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey private final Point mThumbSize; 6689d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 6694eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey public ThumbnailAsyncTask(ImageView target, Point thumbSize) { 6709d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mTarget = target; 6714eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey mThumbSize = thumbSize; 6729d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 6739d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 6749d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 6759d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected void onPreExecute() { 6769d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mTarget.setTag(this); 6779d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 6789d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 6799d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 6809d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected Bitmap doInBackground(Uri... params) { 6819d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final Context context = mTarget.getContext(); 6829d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey final Uri uri = params[0]; 6839d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 6849d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Bitmap result = null; 6859d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey try { 686ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey result = DocumentsContract.getDocumentThumbnail( 687ae9b51bfa313c51a31af30875a71255d7b6d2e61Jeff Sharkey context.getContentResolver(), uri, mThumbSize, null); 6889d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (result != null) { 6894eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey final ThumbnailCache thumbs = DocumentsApplication.getThumbnailsCache( 6904eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey context, mThumbSize); 6914eb407a832b7d6a2d62a535e5cab70b00a0bc8edJeff Sharkey thumbs.put(uri, result); 6929d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 6939d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } catch (Exception e) { 6949d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Log.w(TAG, "Failed to load thumbnail: " + e); 6959d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 6969d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey return result; 6979d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 6989d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 6999d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey @Override 7009d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey protected void onPostExecute(Bitmap result) { 7019d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (mTarget.getTag() == this) { 7029d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mTarget.setImageBitmap(result); 7039d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey mTarget.setTag(null); 7049d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7059d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7069d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7079d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7089d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey private static String formatTime(Context context, long when) { 7099d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey // TODO: DateUtils should make this easier 7109d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Time then = new Time(); 7119d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey then.set(when); 7129d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey Time now = new Time(); 7139d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey now.setToNow(); 7149d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7159d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT 7169d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey | DateUtils.FORMAT_ABBREV_ALL; 7179d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7189d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey if (then.year != now.year) { 7199d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE; 7209d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else if (then.yearDay != now.yearDay) { 7219d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_DATE; 7229d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } else { 7239d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey flags |= DateUtils.FORMAT_SHOW_TIME; 7249d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 7259d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey 7269d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey return DateUtils.formatDateTime(context, when, flags); 7279d0843df7e3984293dc4ab6ee2f9502e898b63aaJeff Sharkey } 728b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 729b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey private String findCommonMimeType(List<String> mimeTypes) { 730b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey String[] commonType = mimeTypes.get(0).split("/"); 731b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (commonType.length != 2) { 732b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return "*/*"; 733b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 734b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 735b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey for (int i = 1; i < mimeTypes.size(); i++) { 736b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey String[] type = mimeTypes.get(i).split("/"); 737b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (type.length != 2) continue; 738b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 739b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (!commonType[1].equals(type[1])) { 740b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[1] = "*"; 741b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 742b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 743b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey if (!commonType[0].equals(type[0])) { 744b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[0] = "*"; 745b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey commonType[1] = "*"; 746b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey break; 747b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 748b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 749b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey 750b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey return commonType[0] + "/" + commonType[1]; 751b51331116eb2ebbc41aaf69142916f9af6dffdd5Jeff Sharkey } 7529e0036ed7d3260d79cc5f9ffd8e3bbe760699924Jeff Sharkey} 753