Java tutorial
/** * Copyright 2011 Anders Kalr * * 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 org.cirdles.chroni; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import android.app.ActionBar; import android.app.AlertDialog; import android.app.ListActivity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Environment; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.text.Editable; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; public class FilePickerActivity extends ListActivity { // Sets whether hidden files should be visible in the list or not public final static String EXTRA_SHOW_HIDDEN_FILES = "show_hidden_files"; // The allowed file extensions in an ArrayList of Strings public final static String EXTRA_ACCEPTED_FILE_EXTENSIONS = "accepted_file_extensions"; protected File mainDirectory; protected ArrayList<File> mFiles; protected FilePickerListAdapter mAdapter; protected boolean mShowHiddenFiles = false; protected String[] acceptedFileExtensions; protected String intentContent; protected boolean inDeleteMode = false; protected boolean inMovePickMode = false; protected boolean choosingDirectory = false; // not choosing directory unless otherwise stated protected File copiedFile = null; protected ArrayList<File> cutFiles = null; protected Menu mOptionsMenu = null; // stores the options menu for the Activity protected ActionBar actionBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setTheme(android.R.style.Theme_Holo); // Set the view to be shown if the list is empty LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); View emptyView = inflator.inflate(R.layout.file_picker_empty_view, null); ((ViewGroup) getListView().getParent()).addView(emptyView); getListView().setEmptyView(emptyView); // adds a RelativeLayout to wrap the listView so that a button can be placed at the bottom RelativeLayout outerLayout = (RelativeLayout) inflator.inflate(R.layout.file_picker_regular_view, null); ((ViewGroup) getListView().getParent()).addView(outerLayout); // sets the margin for the listView so that the bottom item isn't covered FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT); params.setMargins(0, 0, 0, 100); getListView().setLayoutParams(params); // defines the action for the bottom button Button previousFolderButton = (Button) findViewById(R.id.filePickerPreviousButton); previousFolderButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // moves to the previous directory (if it exists) and refreshes the list of files if (mainDirectory.getParentFile() != null) { mainDirectory = mainDirectory.getParentFile(); refreshFilesList(); // goes through and remo any stubborn delete imageViews ViewGroup list = getListView(); int number = list.getChildCount(); // gets rid of all the delete images for (int i = 0; i < number; i++) { View child = list.getChildAt(i); View checkbox = child.findViewById(R.id.checkBoxFilePicker); checkbox.setVisibility(View.GONE); } // sets the action bar at the top so that it tells the user what the current directory is actionBar = getActionBar(); if (actionBar != null) actionBar.setTitle("/" + mainDirectory.getName()); } // if in delete mode or move mode, resets back to normal mode if (inDeleteMode) toggleDelete(); if (inMovePickMode) toggleMove(false); // pass false, not actually executing the move } }); // defines what happens to a list item on a long press getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, final View view, int position, long id) { // stores the address of the file/folder that has been chosen final File chosenFile = (File) parent.getItemAtPosition(position); if (!choosingDirectory) { // only gives options if the chosen file is NOT a directory if (!chosenFile.isDirectory()) { // brings up a Dialog box and asks the user if they want to copy or delete the file CharSequence[] options = { "Copy", "Move", "Delete" }; // the user's options new AlertDialog.Builder(FilePickerActivity.this) .setItems(options, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == 0) { // copy has been chosen // resets cutFiles if it contains files if (cutFiles != null) cutFiles = null; copiedFile = chosenFile; Toast.makeText(FilePickerActivity.this, "File Copied!", Toast.LENGTH_SHORT).show(); // sets the pasteButton's visibility to visible once the file has been copied Button pasteButton = (Button) findViewById(R.id.filePickerPasteButton); pasteButton.setVisibility(View.VISIBLE); dialog.dismiss(); } else if (which == 1) { // move has been chosen // resets copiedFile if it has a file in it if (copiedFile != null) copiedFile = null; cutFiles = new ArrayList<>(); cutFiles.add(chosenFile); Toast.makeText(FilePickerActivity.this, "File Copied!", Toast.LENGTH_SHORT).show(); // sets the pasteButton's visibility to visible once the file has been copied Button pasteButton = (Button) findViewById(R.id.filePickerPasteButton); pasteButton.setVisibility(View.VISIBLE); dialog.dismiss(); } else if (which == 2) { // delete has been chosen // shows a new dialog asking if the user would like to delete the file or not new AlertDialog.Builder(FilePickerActivity.this) .setMessage("Are you sure you want to delete this file?") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // if deleting the currently copied file, un-copy it if (copiedFile != null && chosenFile.equals(copiedFile)) { copiedFile = null; Button pasteButton = (Button) findViewById( R.id.filePickerPasteButton); pasteButton.setVisibility(View.GONE); } // deletes the file and updates the adapter chosenFile.delete(); mAdapter.remove(chosenFile); dialog.dismiss(); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).show(); dialog.dismiss(); } } }).show(); } else if (chosenFile.list().length == 0) { // can only delete directory if it's empty // brings up a Dialog box and asks the user if they want to copy or delete the file CharSequence[] options = { "Delete" }; // the user's options new AlertDialog.Builder(FilePickerActivity.this) .setItems(options, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // shows a new dialog asking if the user would like to delete the file or not new AlertDialog.Builder(FilePickerActivity.this) .setMessage("Are you sure you want to delete this file?") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // if deleting a currently copied or cut file, un-copy it if ((copiedFile != null && chosenFile.equals(copiedFile)) || (cutFiles != null && cutFiles.contains(chosenFile))) { // resets the copied/cut file(s) if (copiedFile != null) copiedFile = null; if (cutFiles != null) cutFiles = null; // and gets rid of the paste button on the bottom Button pasteButton = (Button) findViewById( R.id.filePickerPasteButton); pasteButton.setVisibility(View.GONE); } // deletes the file and updates the adapter chosenFile.delete(); mAdapter.remove(chosenFile); Toast.makeText(FilePickerActivity.this, "File Deleted!", Toast.LENGTH_SHORT).show(); dialog.dismiss(); } }).setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).show(); } }).show(); } } return true; } }); // Obtain content from the current intent for later use intentContent = getIntent().getStringExtra("Default_Directory"); // Set initial directory if it hasn't been already defined if (mainDirectory == null) { mainDirectory = Environment.getExternalStorageDirectory(); // Takes user to root directory folder // Sets the initial directory based on what file the user is looking for (Aliquot or Report Settings) if (intentContent.contentEquals("Aliquot_Directory") || intentContent.contentEquals("From_Aliquot_Directory")) mainDirectory = new File(mainDirectory + "/CHRONI/Aliquot"); // Takes user to the Aliquot folder // Report Settings Menu if coming from a Dropdown Menu or the Report Settings Menu else if (intentContent.contentEquals("Report_Settings_Directory") || intentContent.contentEquals("From_Report_Directory")) mainDirectory = new File(mainDirectory + "/CHRONI/Report Settings"); else if (intentContent.contentEquals("Parent_Directory")) choosingDirectory = true; // choosing a directory rather than a file // if none of these are true, the directory will be CHRONI's parent directory (externalStorageDirectory) } // sets the action bar at the top so that it tells the user what the current directory is actionBar = getActionBar(); if (actionBar != null) actionBar.setTitle("/" + mainDirectory.getName()); // Initialize the ArrayList mFiles = new ArrayList<>(); // Set the ListAdapter mAdapter = new FilePickerListAdapter(this, mFiles); setListAdapter(mAdapter); // Initialize the extensions array to allow any file extensions acceptedFileExtensions = new String[] {}; // Get intent extras if (getIntent().hasExtra(EXTRA_SHOW_HIDDEN_FILES)) { mShowHiddenFiles = getIntent().getBooleanExtra(EXTRA_SHOW_HIDDEN_FILES, false); } if (getIntent().hasExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS)) { ArrayList<String> collection = getIntent().getStringArrayListExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS); acceptedFileExtensions = collection.toArray(new String[collection.size()]); } // if no file permissions, asks for them if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[] { android.Manifest.permission.WRITE_EXTERNAL_STORAGE }, 1); } } @Override protected void onResume() { refreshFilesList(); super.onResume(); } /** * Updates the list view to the current directory */ protected void refreshFilesList() { // sets the action bar at the top so that it tells the user what the current directory is actionBar = getActionBar(); if (actionBar != null) actionBar.setTitle("/" + mainDirectory.getName()); // Clear the files ArrayList mFiles.clear(); // Set the extension file filter ExtensionFilenameFilter filter = new ExtensionFilenameFilter(acceptedFileExtensions); // Get the files in the directory File[] files = mainDirectory.listFiles(filter); if (files != null && files.length > 0) { for (File f : files) { if (f.isHidden() && !mShowHiddenFiles) // Don't add the file continue; // Add the file the ArrayAdapter IF not choosing an import directory for importFilesActivity if (!choosingDirectory) mFiles.add(f); else if (f.isDirectory()) mFiles.add(f); // if choosing directory, only adds if it is a directory } Collections.sort(mFiles, new FileComparator()); } mAdapter.notifyDataSetChanged(); } @Override protected void onListItemClick(final ListView l, final View v, final int position, long id) { final File newFile = (File) l.getItemAtPosition(position); // checks off the view's checkbox if in either delete or move mode if (inDeleteMode || inMovePickMode) { if (newFile.isFile() || newFile.list().length == 0) { CheckBox checkBox = (CheckBox) v.findViewById(R.id.checkBoxFilePicker); // checks the box if not already checked if (!checkBox.isChecked()) checkBox.setChecked(true); // un-checks the box if already checked else checkBox.setChecked(false); } } else { // If item selected is a file (and not a directory), allows user to select file if (newFile.isFile()) { // Sends back selected file name if (intentContent.contentEquals("From_Aliquot_Directory")) { Intent returnAliquotIntent = new Intent("android.intent.action.ALIQUOTMENU"); returnAliquotIntent.putExtra("AliquotXMLFileName", newFile.getAbsolutePath()); setResult(RESULT_OK, returnAliquotIntent); // Returns Extra to AliquotMenuActivity } else if (intentContent.contentEquals("Aliquot_Directory")) { Intent newAliquotIntent = new Intent("android.intent.action.ALIQUOTMENU"); newAliquotIntent.putExtra("AliquotXMLFileName", newFile.getAbsolutePath()); startActivity(newAliquotIntent); // starts a new Aliquot activity because the user was not originally in one // If coming from any menu (by using the dropdown menu) } else if (intentContent.contentEquals("Report_Settings_Directory")) { Intent openRSMenu = new Intent("android.intent.action.REPORTSETTINGSMENU"); openRSMenu.putExtra("ReportSettingsXMLFileName", newFile.getAbsolutePath()); startActivity(openRSMenu); // Start a new Report Settings Menu with the selected Report Settings // If coming FROM a Report Settings Menu (by pressing the + button) } else if (intentContent.contentEquals("From_Report_Directory")) { Intent returnRSIntent = new Intent("android.intent.action.REPORTSETTINGSMENU"); returnRSIntent.putExtra("NewReportSettingsXMLFileName", newFile.getAbsolutePath()); setResult(RESULT_OK, returnRSIntent); // Return to previous Report Settings Menu with the new Report Settings } finish(); } else { // if the user is trying the choose a directory, sends the directory's path back if (choosingDirectory) { // when choosing a directory for importing, display the option to step into directory CharSequence[] options = { "Choose Directory", "Step Into Directory" }; // the user's options new AlertDialog.Builder(FilePickerActivity.this) .setItems(options, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (which == 0) { // coming from ImportFilesActivity, so return the chosen directory Intent returnImportIntent = new Intent("android.intent.action.IMPORTMENU"); returnImportIntent.putExtra("ImportDirectory", newFile.getAbsolutePath()); setResult(RESULT_OK, returnImportIntent); finish(); } else if (which == 1) { // steps into the new directory and refreshes files mainDirectory = newFile; refreshFilesList(); dialog.dismiss(); } } }).show(); } else { // if not choosing a directory, updates the files list mainDirectory = newFile; refreshFilesList(); } } super.onListItemClick(l, v, position, id); } } public void onPasteButtonClick(View v) { Button button = (Button) v; String buttonText = button.getText().toString(); // the button is acting as a paste button if (buttonText.equals("Paste")) { // cutting files instead of copying if (cutFiles != null) { boolean success = true; // tells whether all files have been copied or not boolean allDeleted = true; // tells whether all files have been deleted or not boolean filesMoved = false; // tells if any files have been moved at all // pastes each file to the new directory one at a time for (File file : cutFiles) { // only move if NOT in the same directory if (!file.getAbsolutePath().equals(mainDirectory.getAbsolutePath() + "/" + file.getName())) { // once success becomes false, it will aways be false success = success && copyFileToCurrentDirectory(file); // same with allDeleted allDeleted = allDeleted && file.delete(); // deletes the file after copying filesMoved = true; // files have now been moved } } // inform the user of any errors (deleting or copying) if (!success || !allDeleted) Toast.makeText(this, "ERROR: Could not successfully move all files", Toast.LENGTH_SHORT).show(); else if (filesMoved) Toast.makeText(this, "File(s) Moved!", Toast.LENGTH_SHORT).show(); // reset cutFiles ArrayList and Paste Button cutFiles = null; button.setVisibility(View.GONE); } // copying a file instead of cutting, only copies if it is NOT the same directory else if (copiedFile != null && !copiedFile.getAbsolutePath() .equals(mainDirectory.getAbsolutePath() + "/" + copiedFile.getName())) { // copies the file to the current directory boolean success = copyFileToCurrentDirectory(copiedFile); if (!success) // if file could not be copied, alert the user Toast.makeText(this, "ERROR: Could not copy file", Toast.LENGTH_SHORT).show(); } } else { // the button is acting as a done button (in either move or delete) if (inDeleteMode) { toggleDelete(); } if (inMovePickMode) toggleMove(true); // pass true, actually executing the cut } } /** * Copies the file given to the mainDirectory, which is the current directory that the user is in. * * @param fileCopying the file that is being copied * @return a boolean telling whether the copy was successful or not */ public boolean copyFileToCurrentDirectory(File fileCopying) { boolean result = true; // result is true until proven false // copies the file through the use of Streams InputStream input = null; OutputStream output = null; try { // input file is the copied file, and output file is a new file at the current directory File newFile = new File(mainDirectory.getAbsolutePath() + "/" + fileCopying.getName()); input = new FileInputStream(fileCopying); output = new FileOutputStream(newFile.getAbsolutePath()); // copies the file's contents to the new directory byte[] buf = new byte[1024]; int bytesRead; while ((bytesRead = input.read(buf)) > 0) { output.write(buf, 0, bytesRead); } // adds the file to the adapter immediately after it has been copied mAdapter.add(newFile); } catch (IOException e) { e.printStackTrace(); result = false; // error occurred, could not copy the file } finally { try { input.close(); output.close(); } catch (Exception e) { e.printStackTrace(); } } return result; } public void onNewFolderButtonClicked(View v) { AlertDialog.Builder dialog = new AlertDialog.Builder(this).setMessage("Enter the new folder's name below."); // creates the layout for the EditText, will be added to the dialog box final EditText newFolderText = new EditText(this); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); params.setMargins(25, 10, 20, 25); LinearLayout dialogLayout = new LinearLayout(this); dialogLayout.addView(newFolderText); newFolderText.setLayoutParams(params); dialog.setView(dialogLayout); // adds EditText to dialog box dialog.setPositiveButton("Create", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Editable newFolderName = newFolderText.getText(); File newFolder = new File(mainDirectory.getAbsolutePath() + "/" + newFolderName.toString()); // creates the folder if the length of the text is greater than 0 AND the folder does not already exist if (newFolderName.length() > 0 && !newFolder.exists()) { // creates the actual folder boolean createdSuccessfully = newFolder.mkdir(); // alerts the user if the folder was not created if (!createdSuccessfully) Toast.makeText(FilePickerActivity.this, "ERROR: Folder could not be created", Toast.LENGTH_SHORT).show(); else { // if it succeeded, updates the adapter mAdapter.add(newFolder); Toast.makeText(FilePickerActivity.this, "Folder Created!", Toast.LENGTH_SHORT).show(); } } else Toast.makeText(FilePickerActivity.this, "ERROR: Invalid folder name", Toast.LENGTH_SHORT) .show(); dialog.dismiss(); } }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); dialog.show(); } private class FilePickerListAdapter extends ArrayAdapter<File> { private List<File> mObjects; public FilePickerListAdapter(Context context, List<File> objects) { super(context, R.layout.file_picker_list_item, android.R.id.text1, objects); mObjects = objects; } @Override public View getView(int position, View convertView, ViewGroup parent) { View row; if (convertView == null) { LayoutInflater inflater = (LayoutInflater) getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); row = inflater.inflate(R.layout.file_picker_list_item, parent, false); } else row = convertView; File object = mObjects.get(position); TextView textView = (TextView) row.findViewById(R.id.file_picker_text); // Set single line textView.setSingleLine(true); textView.setTextSize(24); textView.setText(object.getName()); return row; } } private class FileComparator implements Comparator<File> { @Override public int compare(File f1, File f2) { if (f1 == f2) return 0; if (f1.isDirectory() && f2.isFile()) // Show directories above files return -1; if (f1.isFile() && f2.isDirectory()) // Show files below directories return 1; // Sort the directories alphabetically return f1.getName().compareToIgnoreCase(f2.getName()); } } private class ExtensionFilenameFilter implements FilenameFilter { private String[] mExtensions; public ExtensionFilenameFilter(String[] extensions) { super(); mExtensions = extensions; } @Override public boolean accept(File dir, String filename) { if (new File(dir, filename).isDirectory()) { // Accept all directory names return true; } if (mExtensions != null && mExtensions.length > 0) { for (String extension : mExtensions) if (filename.endsWith(extension)) // The filename ends with the extension return true; // The filename did not match any of the extensions return false; } // No extensions has been set. Accept all file extensions. return true; } } /** * This method either shows all of the checkboxes on the list items, or adds every file that has been checked off * * @param executeMove a boolean that specifies whether to add the files to the ArrayList or not */ public void toggleMove(boolean executeMove) { ViewGroup list = getListView(); int number = list.getChildCount(); if (inMovePickMode) { mOptionsMenu.findItem(R.id.deleteFilePickerMenu).setVisible(true); // puts the delete items option back cutFiles = new ArrayList<>(); // initializes cutFiles to add files to // only adds files IF the user has pressed done (executeMove will be true) if (executeMove) { // gets rid of all of the move checkboxes and add files to cutFiles for (int i = 0; i < number; i++) { View child = list.getChildAt(i); CheckBox checkbox = (CheckBox) child.findViewById(R.id.checkBoxFilePicker); // adds the file to cutFiles IF the checkbox is checked if (checkbox.isChecked()) { File fileToCut = mAdapter.getItem(i); cutFiles.add(fileToCut); // un-checks the checkbox checkbox.setChecked(false); } checkbox.setVisibility(View.GONE); } } // resets cutFiles if no files have been added if (cutFiles.size() == 0) cutFiles = null; else Toast.makeText(this, "File(s) Copied!", Toast.LENGTH_SHORT).show(); // changes the bottom button text back to "Paste" and gives it the correct visibility Button bottomButton = (Button) findViewById(R.id.filePickerPasteButton); bottomButton.setText("Paste"); if (copiedFile == null && cutFiles == null) bottomButton.setVisibility(View.GONE); else bottomButton.setVisibility(View.VISIBLE); } else { mOptionsMenu.findItem(R.id.deleteFilePickerMenu).setVisible(false); // removes the delete items menu option // displays all of the move checkboxes for (int i = 0; i < number; i++) { View child = list.getChildAt(i); View checkbox = child.findViewById(R.id.checkBoxFilePicker); checkbox.setVisibility(View.VISIBLE); } // changes the bottom button text to "Done" Button bottomButton = (Button) findViewById(R.id.filePickerPasteButton); bottomButton.setText("Done"); bottomButton.setVisibility(View.VISIBLE); } inMovePickMode = !inMovePickMode; } /** * This method either displays an X on the right hand side of each list item or * gets rid of it. */ public void toggleDelete() { final ViewGroup list = getListView(); final int number = list.getChildCount(); if (inDeleteMode) { mOptionsMenu.findItem(R.id.moveFilePickerMenu).setVisible(true); // puts the move items menu option back // first makes sure that there are checked off items boolean hasCheckedItems = false; for (int i = 0; i < number; i++) { View child = list.getChildAt(i); CheckBox checkbox = (CheckBox) child.findViewById(R.id.checkBoxFilePicker); hasCheckedItems = hasCheckedItems || checkbox.isChecked(); // once this turns true, will always be true } // only deletes items IF there are any checked off if (hasCheckedItems) { final ArrayList<File> filesToDelete = new ArrayList<>(); // stores the files that will be deleted // gets rid of all the checkboxes and adds the checked off files to the delete list for (int i = 0; i < number; i++) { View child = list.getChildAt(i); CheckBox checkbox = (CheckBox) child.findViewById(R.id.checkBoxFilePicker); if (checkbox.isChecked()) { // adds the file to the list of files that will be deleted filesToDelete.add(mAdapter.getItem(i)); // un-checks the checkbox if checked checkbox.setChecked(false); } // gets rid of the checkbox checkbox.setVisibility(View.GONE); } new AlertDialog.Builder(this).setMessage("File(s) will be deleted, do you wish to continue?") .setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { boolean allDeleted = true; // tells whether all files have been deleted or not // goes through and deletes the files in the list for (File file : filesToDelete) { // once allDeleted becomes false, it will aways be false allDeleted = allDeleted && file.delete(); mAdapter.remove(file); } if (!allDeleted) // alerts the user if all the files could not be deleted Toast.makeText(FilePickerActivity.this, "ERROR: Could not delete all files", Toast.LENGTH_SHORT).show(); else Toast.makeText(FilePickerActivity.this, "File(s) Deleted!", Toast.LENGTH_SHORT) .show(); dialog.dismiss(); } }).setNegativeButton("No", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).show(); } else { // gets rid of all the checkboxes but doesn't add any files to delete for (int i = 0; i < number; i++) { View child = list.getChildAt(i); CheckBox checkbox = (CheckBox) child.findViewById(R.id.checkBoxFilePicker); if (checkbox.isChecked()) // un-checks the checkbox if checked checkbox.setChecked(false); // gets rid of the checkbox checkbox.setVisibility(View.GONE); } } // changes the bottom button text back to "Paste" Button bottomButton = (Button) findViewById(R.id.filePickerPasteButton); bottomButton.setText("Paste"); // gives it the correct visibility if (copiedFile == null && cutFiles == null) bottomButton.setVisibility(View.GONE); else bottomButton.setVisibility(View.VISIBLE); } else { mOptionsMenu.findItem(R.id.moveFilePickerMenu).setVisible(false); // removes the move items menu option // displays all of the delete images for (int i = 0; i < number; i++) { View child = list.getChildAt(i); View checkbox = child.findViewById(R.id.checkBoxFilePicker); checkbox.setVisibility(View.VISIBLE); } // changes the bottom button text to "Done" Button bottomButton = (Button) findViewById(R.id.filePickerPasteButton); bottomButton.setText("Done"); bottomButton.setVisibility(View.VISIBLE); } inDeleteMode = !inDeleteMode; } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.file_delete, menu); mOptionsMenu = menu; // saves the menu for later use return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handles menu item selection switch (item.getItemId()) { case R.id.moveFilePickerMenu: toggleMove(true); // pass true, actually chose to execute the cut return true; case R.id.deleteFilePickerMenu: // Takes user to main menu toggleDelete(); return true; case R.id.exitFilePickerMenu: // Exits the File Picker Activity finish(); return true; default: return super.onOptionsItemSelected(item); } } }