Home | History | Annotate | Download | only in com.example.android.directoryselection
      1 /*
      2 * Copyright 2014 The Android Open Source Project
      3 *
      4 * Licensed under the Apache License, Version 2.0 (the "License");
      5 * you may not use this file except in compliance with the License.
      6 * You may obtain a copy of the License at
      7 *
      8 *     http://www.apache.org/licenses/LICENSE-2.0
      9 *
     10 * Unless required by applicable law or agreed to in writing, software
     11 * distributed under the License is distributed on an "AS IS" BASIS,
     12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 * See the License for the specific language governing permissions and
     14 * limitations under the License.
     15 */
     16 
     17 package com.example.android.directoryselection;
     18 
     19 import android.app.Activity;
     20 import android.app.AlertDialog;
     21 import android.content.ContentResolver;
     22 import android.content.DialogInterface;
     23 import android.content.Intent;
     24 import android.database.Cursor;
     25 import android.net.Uri;
     26 import android.os.Bundle;
     27 import android.provider.DocumentsContract;
     28 import android.provider.DocumentsContract.Document;
     29 import android.support.v4.app.Fragment;
     30 import android.support.v7.widget.RecyclerView;
     31 import android.util.Log;
     32 import android.view.LayoutInflater;
     33 import android.view.View;
     34 import android.view.ViewGroup;
     35 import android.widget.Button;
     36 import android.widget.EditText;
     37 import android.widget.TextView;
     38 import android.widget.Toast;
     39 
     40 import java.util.ArrayList;
     41 import java.util.List;
     42 
     43 /**
     44  * Fragment that demonstrates how to use Directory Selection API.
     45  */
     46 public class DirectorySelectionFragment extends Fragment {
     47 
     48     private static final String TAG = DirectorySelectionFragment.class.getSimpleName();
     49 
     50     public static final int REQUEST_CODE_OPEN_DIRECTORY = 1;
     51 
     52     Uri mCurrentDirectoryUri;
     53     TextView mCurrentDirectoryTextView;
     54     Button mCreateDirectoryButton;
     55     RecyclerView mRecyclerView;
     56     DirectoryEntryAdapter mAdapter;
     57     RecyclerView.LayoutManager mLayoutManager;
     58 
     59     /**
     60      * Use this factory method to create a new instance of
     61      * this fragment using the provided parameters.
     62      *
     63      * @return A new instance of fragment {@link DirectorySelectionFragment}.
     64      */
     65     public static DirectorySelectionFragment newInstance() {
     66         DirectorySelectionFragment fragment = new DirectorySelectionFragment();
     67         return fragment;
     68     }
     69 
     70     public DirectorySelectionFragment() {
     71         // Required empty public constructor
     72     }
     73 
     74     @Override
     75     public void onCreate(Bundle savedInstanceState) {
     76         super.onCreate(savedInstanceState);
     77     }
     78 
     79     @Override
     80     public View onCreateView(LayoutInflater inflater, ViewGroup container,
     81             Bundle savedInstanceState) {
     82         // Inflate the layout for this fragment
     83         return inflater.inflate(R.layout.fragment_directory_selection, container, false);
     84     }
     85 
     86     @Override
     87     public void onViewCreated(View rootView, Bundle savedInstanceState) {
     88         super.onViewCreated(rootView, savedInstanceState);
     89 
     90         rootView.findViewById(R.id.button_open_directory)
     91                 .setOnClickListener(new View.OnClickListener() {
     92                     @Override
     93                     public void onClick(View v) {
     94                         Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
     95                         startActivityForResult(intent, REQUEST_CODE_OPEN_DIRECTORY);
     96                     }
     97                 });
     98 
     99         mCurrentDirectoryTextView = (TextView) rootView
    100                 .findViewById(R.id.textview_current_directory);
    101         mCreateDirectoryButton = (Button) rootView.findViewById(R.id.button_create_directory);
    102         mCreateDirectoryButton.setOnClickListener(new View.OnClickListener() {
    103             @Override
    104             public void onClick(View v) {
    105                 final EditText editView = new EditText(getActivity());
    106                 new AlertDialog.Builder(getActivity())
    107                         .setTitle(R.string.create_directory)
    108                         .setView(editView)
    109                         .setPositiveButton(android.R.string.ok,
    110                                 new DialogInterface.OnClickListener() {
    111                                     public void onClick(DialogInterface dialog, int whichButton) {
    112                                         createDirectory(mCurrentDirectoryUri,
    113                                                 editView.getText().toString());
    114                                         updateDirectoryEntries(mCurrentDirectoryUri);
    115                                     }
    116                                 })
    117                         .setNegativeButton(android.R.string.cancel,
    118                                 new DialogInterface.OnClickListener() {
    119                                     public void onClick(DialogInterface dialog, int whichButton) {
    120                                     }
    121                                 })
    122                         .show();
    123             }
    124         });
    125         mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview_directory_entries);
    126         mLayoutManager = mRecyclerView.getLayoutManager();
    127         mRecyclerView.scrollToPosition(0);
    128         mAdapter = new DirectoryEntryAdapter(new ArrayList<DirectoryEntry>());
    129         mRecyclerView.setAdapter(mAdapter);
    130     }
    131 
    132     @Override
    133     public void onActivityResult(int requestCode, int resultCode, Intent data) {
    134         super.onActivityResult(requestCode, resultCode, data);
    135         if (requestCode == REQUEST_CODE_OPEN_DIRECTORY && resultCode == Activity.RESULT_OK) {
    136             Log.d(TAG, String.format("Open Directory result Uri : %s", data.getData()));
    137             updateDirectoryEntries(data.getData());
    138             mAdapter.notifyDataSetChanged();
    139         }
    140     }
    141 
    142 
    143     /**
    144      * Updates the current directory of the uri passed as an argument and its children directories.
    145      * And updates the {@link #mRecyclerView} depending on the contents of the children.
    146      *
    147      * @param uri The uri of the current directory.
    148      */
    149     //VisibileForTesting
    150     void updateDirectoryEntries(Uri uri) {
    151         ContentResolver contentResolver = getActivity().getContentResolver();
    152         Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
    153                 DocumentsContract.getTreeDocumentId(uri));
    154         Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri,
    155                 DocumentsContract.getTreeDocumentId(uri));
    156 
    157         Cursor docCursor = contentResolver.query(docUri, new String[]{
    158                 Document.COLUMN_DISPLAY_NAME, Document.COLUMN_MIME_TYPE}, null, null, null);
    159         try {
    160             while (docCursor.moveToNext()) {
    161                 Log.d(TAG, "found doc =" + docCursor.getString(0) + ", mime=" + docCursor
    162                         .getString(1));
    163                 mCurrentDirectoryUri = uri;
    164                 mCurrentDirectoryTextView.setText(docCursor.getString(0));
    165                 mCreateDirectoryButton.setEnabled(true);
    166             }
    167         } finally {
    168             closeQuietly(docCursor);
    169         }
    170 
    171         Cursor childCursor = contentResolver.query(childrenUri, new String[]{
    172                 Document.COLUMN_DISPLAY_NAME, Document.COLUMN_MIME_TYPE}, null, null, null);
    173         try {
    174             List<DirectoryEntry> directoryEntries = new ArrayList<>();
    175             while (childCursor.moveToNext()) {
    176                 Log.d(TAG, "found child=" + childCursor.getString(0) + ", mime=" + childCursor
    177                         .getString(1));
    178                 DirectoryEntry entry = new DirectoryEntry();
    179                 entry.fileName = childCursor.getString(0);
    180                 entry.mimeType = childCursor.getString(1);
    181                 directoryEntries.add(entry);
    182             }
    183             mAdapter.setDirectoryEntries(directoryEntries);
    184             mAdapter.notifyDataSetChanged();
    185         } finally {
    186             closeQuietly(childCursor);
    187         }
    188     }
    189 
    190     /**
    191      * Creates a directory under the directory represented as the uri in the argument.
    192      *
    193      * @param uri The uri of the directory under which a new directory is created.
    194      * @param directoryName The directory name of a new directory.
    195      */
    196     //VisibileForTesting
    197     void createDirectory(Uri uri, String directoryName) {
    198         ContentResolver contentResolver = getActivity().getContentResolver();
    199         Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri,
    200                 DocumentsContract.getTreeDocumentId(uri));
    201         Uri directoryUri = DocumentsContract
    202                 .createDocument(contentResolver, docUri, Document.MIME_TYPE_DIR, directoryName);
    203         if (directoryUri != null) {
    204             Log.i(TAG, String.format(
    205                     "Created directory : %s, Document Uri : %s, Created directory Uri : %s",
    206                     directoryName, docUri, directoryUri));
    207             Toast.makeText(getActivity(), String.format("Created a directory [%s]",
    208                     directoryName), Toast.LENGTH_SHORT).show();
    209         } else {
    210             Log.w(TAG, String.format("Failed to create a directory : %s, Uri %s", directoryName,
    211                     docUri));
    212             Toast.makeText(getActivity(), String.format("Failed to created a directory [%s] : ",
    213                     directoryName), Toast.LENGTH_SHORT).show();
    214         }
    215 
    216     }
    217 
    218     public void closeQuietly(AutoCloseable closeable) {
    219         if (closeable != null) {
    220             try {
    221                 closeable.close();
    222             } catch (RuntimeException rethrown) {
    223                 throw rethrown;
    224             } catch (Exception ignored) {
    225             }
    226         }
    227     }
    228 }
    229 
    230