| /* |
| * Copyright 2016 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. |
| */ |
| |
| package com.example.android.scopeddirectoryaccess; |
| |
| import android.app.Activity; |
| import android.content.ContentResolver; |
| import android.content.Context; |
| import android.content.Intent; |
| import android.database.Cursor; |
| import android.net.Uri; |
| import android.os.Bundle; |
| import android.os.Environment; |
| import android.os.storage.StorageManager; |
| import android.os.storage.StorageVolume; |
| import android.provider.DocumentsContract; |
| import android.support.v4.app.Fragment; |
| import android.support.v7.widget.LinearLayoutManager; |
| import android.support.v7.widget.RecyclerView; |
| import android.view.LayoutInflater; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.widget.ArrayAdapter; |
| import android.widget.Button; |
| import android.widget.LinearLayout; |
| import android.widget.Spinner; |
| import android.widget.TextView; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * Fragment that displays the directory contents. |
| */ |
| public class ScopedDirectoryAccessFragment extends Fragment { |
| |
| private static final String DIRECTORY_ENTRIES_KEY = "directory_entries"; |
| private static final String SELECTED_DIRECTORY_KEY = "selected_directory"; |
| private static final int OPEN_DIRECTORY_REQUEST_CODE = 1; |
| |
| private static final String[] DIRECTORY_SELECTION = new String[]{ |
| DocumentsContract.Document.COLUMN_DISPLAY_NAME, |
| DocumentsContract.Document.COLUMN_MIME_TYPE, |
| DocumentsContract.Document.COLUMN_DOCUMENT_ID, |
| }; |
| |
| private Activity mActivity; |
| private StorageManager mStorageManager; |
| private TextView mCurrentDirectoryTextView; |
| private TextView mNothingInDirectoryTextView; |
| private TextView mPrimaryVolumeNameTextView; |
| private Spinner mDirectoriesSpinner; |
| private DirectoryEntryAdapter mAdapter; |
| private ArrayList<DirectoryEntry> mDirectoryEntries; |
| |
| public static ScopedDirectoryAccessFragment newInstance() { |
| ScopedDirectoryAccessFragment fragment = new ScopedDirectoryAccessFragment(); |
| return fragment; |
| } |
| |
| public ScopedDirectoryAccessFragment() { |
| // Required empty public constructor |
| } |
| |
| @Override |
| public void onAttach(Context context) { |
| super.onAttach(context); |
| mActivity = getActivity(); |
| mStorageManager = mActivity.getSystemService(StorageManager.class); |
| } |
| |
| @Override |
| public void onActivityResult(int requestCode, int resultCode, Intent data) { |
| super.onActivityResult(requestCode, resultCode, data); |
| if (requestCode == OPEN_DIRECTORY_REQUEST_CODE && resultCode == Activity.RESULT_OK) { |
| getActivity().getContentResolver().takePersistableUriPermission(data.getData(), |
| Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); |
| updateDirectoryEntries(data.getData()); |
| } |
| } |
| |
| @Override |
| public View onCreateView(LayoutInflater inflater, ViewGroup container, |
| Bundle savedInstanceState) { |
| return inflater.inflate(R.layout.fragment_scoped_directory_access, container, false); |
| } |
| |
| @Override |
| public void onViewCreated(final View rootView, Bundle savedInstanceState) { |
| super.onViewCreated(rootView, savedInstanceState); |
| |
| mCurrentDirectoryTextView = (TextView) rootView |
| .findViewById(R.id.textview_current_directory); |
| mNothingInDirectoryTextView = (TextView) rootView |
| .findViewById(R.id.textview_nothing_in_directory); |
| mPrimaryVolumeNameTextView = (TextView) rootView |
| .findViewById(R.id.textview_primary_volume_name); |
| |
| // Set onClickListener for the primary volume |
| Button openPictureButton = (Button) rootView |
| .findViewById(R.id.button_open_directory_primary_volume); |
| openPictureButton.setOnClickListener(new View.OnClickListener() { |
| @Override |
| public void onClick(View view) { |
| String selected = mDirectoriesSpinner.getSelectedItem().toString(); |
| String directoryName = getDirectoryName(selected); |
| StorageVolume storageVolume = mStorageManager.getPrimaryStorageVolume(); |
| Intent intent = storageVolume.createAccessIntent(directoryName); |
| startActivityForResult(intent, OPEN_DIRECTORY_REQUEST_CODE); |
| } |
| }); |
| |
| // Set onClickListener for the external volumes if exists |
| List<StorageVolume> storageVolumes = mStorageManager.getStorageVolumes(); |
| LinearLayout containerVolumes = (LinearLayout) mActivity |
| .findViewById(R.id.container_volumes); |
| for (final StorageVolume volume : storageVolumes) { |
| String volumeDescription = volume.getDescription(mActivity); |
| if (volume.isPrimary()) { |
| // Primary volume area is already added... |
| if (volumeDescription != null) { |
| // ...but with a default name: set it to the real name when available. |
| mPrimaryVolumeNameTextView.setText(volumeDescription); |
| } |
| continue; |
| } |
| LinearLayout volumeArea = (LinearLayout) mActivity.getLayoutInflater() |
| .inflate(R.layout.volume_entry, containerVolumes); |
| TextView volumeName = (TextView) volumeArea.findViewById(R.id.textview_volume_name); |
| volumeName.setText(volumeDescription); |
| Button button = (Button) volumeArea.findViewById(R.id.button_open_directory); |
| button.setOnClickListener(new View.OnClickListener() { |
| @Override |
| public void onClick(View view) { |
| String selected = mDirectoriesSpinner.getSelectedItem().toString(); |
| String directoryName = getDirectoryName(selected); |
| Intent intent = volume.createAccessIntent(directoryName); |
| startActivityForResult(intent, OPEN_DIRECTORY_REQUEST_CODE); |
| } |
| }); |
| } |
| RecyclerView recyclerView = (RecyclerView) rootView |
| .findViewById(R.id.recyclerview_directory_entries); |
| if (savedInstanceState != null) { |
| mDirectoryEntries = savedInstanceState.getParcelableArrayList(DIRECTORY_ENTRIES_KEY); |
| mCurrentDirectoryTextView.setText(savedInstanceState.getString(SELECTED_DIRECTORY_KEY)); |
| mAdapter = new DirectoryEntryAdapter(mDirectoryEntries); |
| if (mAdapter.getItemCount() == 0) { |
| mNothingInDirectoryTextView.setVisibility(View.VISIBLE); |
| } |
| } else { |
| mDirectoryEntries = new ArrayList<>(); |
| mAdapter = new DirectoryEntryAdapter(); |
| } |
| recyclerView.setAdapter(mAdapter); |
| recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); |
| mDirectoriesSpinner = (Spinner) rootView.findViewById(R.id.spinner_directories); |
| ArrayAdapter<CharSequence> directoriesAdapter = ArrayAdapter |
| .createFromResource(getActivity(), |
| R.array.directories, android.R.layout.simple_spinner_item); |
| directoriesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); |
| mDirectoriesSpinner.setAdapter(directoriesAdapter); |
| } |
| |
| @Override |
| public void onSaveInstanceState(Bundle outState) { |
| super.onSaveInstanceState(outState); |
| outState.putString(SELECTED_DIRECTORY_KEY, mCurrentDirectoryTextView.getText().toString()); |
| outState.putParcelableArrayList(DIRECTORY_ENTRIES_KEY, mDirectoryEntries); |
| } |
| |
| private void updateDirectoryEntries(Uri uri) { |
| mDirectoryEntries.clear(); |
| ContentResolver contentResolver = getActivity().getContentResolver(); |
| Uri docUri = DocumentsContract.buildDocumentUriUsingTree(uri, |
| DocumentsContract.getTreeDocumentId(uri)); |
| Uri childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(uri, |
| DocumentsContract.getTreeDocumentId(uri)); |
| |
| try (Cursor docCursor = contentResolver |
| .query(docUri, DIRECTORY_SELECTION, null, null, null)) { |
| while (docCursor != null && docCursor.moveToNext()) { |
| mCurrentDirectoryTextView.setText(docCursor.getString(docCursor.getColumnIndex( |
| DocumentsContract.Document.COLUMN_DISPLAY_NAME))); |
| } |
| } |
| |
| try (Cursor childCursor = contentResolver |
| .query(childrenUri, DIRECTORY_SELECTION, null, null, null)) { |
| while (childCursor != null && childCursor.moveToNext()) { |
| DirectoryEntry entry = new DirectoryEntry(); |
| entry.fileName = childCursor.getString(childCursor.getColumnIndex( |
| DocumentsContract.Document.COLUMN_DISPLAY_NAME)); |
| entry.mimeType = childCursor.getString(childCursor.getColumnIndex( |
| DocumentsContract.Document.COLUMN_MIME_TYPE)); |
| mDirectoryEntries.add(entry); |
| } |
| |
| if (mDirectoryEntries.isEmpty()) { |
| mNothingInDirectoryTextView.setVisibility(View.VISIBLE); |
| } else { |
| mNothingInDirectoryTextView.setVisibility(View.GONE); |
| } |
| mAdapter.setDirectoryEntries(mDirectoryEntries); |
| mAdapter.notifyDataSetChanged(); |
| } |
| } |
| |
| private String getDirectoryName(String name) { |
| switch (name) { |
| case "ALARMS": |
| return Environment.DIRECTORY_ALARMS; |
| case "DCIM": |
| return Environment.DIRECTORY_DCIM; |
| case "DOCUMENTS": |
| return Environment.DIRECTORY_DOCUMENTS; |
| case "DOWNLOADS": |
| return Environment.DIRECTORY_DOWNLOADS; |
| case "MOVIES": |
| return Environment.DIRECTORY_MOVIES; |
| case "MUSIC": |
| return Environment.DIRECTORY_MUSIC; |
| case "NOTIFICATIONS": |
| return Environment.DIRECTORY_NOTIFICATIONS; |
| case "PICTURES": |
| return Environment.DIRECTORY_PICTURES; |
| case "PODCASTS": |
| return Environment.DIRECTORY_PODCASTS; |
| case "RINGTONES": |
| return Environment.DIRECTORY_RINGTONES; |
| default: |
| throw new IllegalArgumentException("Invalid directory representation: " + name); |
| } |
| } |
| } |