package file_manager; import activity.ABase; import adapter.FileAdapter; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.os.AsyncTask; import android.os.CountDownTimer; import android.os.Environment; import android.os.Vibrator; import android.view.View; import android.widget.*; import com.softcsoftware.aio.R; import dialogs.MessageDialog; import dialogs.ProgressDialog; import dialogs.YesNoDialog; import tools.StorageUtils; import view_holder.Views; import java.io.File; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import static view_holder.Views.dialog_fillParent; /** * File manager : All the tasks related to the file system can operate through the FileManager. * File manager now can do some basic soft of tasks.. but this class is designed for extending the * capabilities of itself on day by day. * * @author shibaprasad * @version 1.1 */ @SuppressWarnings({"UnnecessaryLocalVariable", "UnusedDeclaration"}) public class FileManager { public static String SD_ROOT_PATH = Environment.getExternalStorageDirectory().toString(); private Dialog fileManagerDialog; private TextView title; private ListView listView; private FileAdapter fileAdapter; private File openedFile; private ArrayList<File> fileArrayList; private Context context; private Vibrator vibrator; private OnClickListener onClickListener; private int CREATE_MODE = 1, RENAME_MODE = 2; /** * public constructor. * * @param context_ activity context. * @param vibrator vibrator */ public FileManager(final Context context_, Vibrator vibrator) { this.context = context_; this.vibrator = vibrator; fileArrayList = new ArrayList<File>(); openedFile = new File(SD_ROOT_PATH); fileAdapter = new FileAdapter(context, fileArrayList); initFileManagerDialog(); initFileManagerTitle(); initBackButton(); initListView(); listView.setAdapter(fileAdapter); //show the file manager dialog. fileManagerDialog.show(); } /** * Load the files in the list, either from the given file or from the default path. * * @param file the folder that will be loaded to the list view and will show * its child files and folders. */ public void loadFiles(File file) { String defaultPath = (file == null) ? SD_ROOT_PATH : file.getPath(); run(new File(defaultPath)); openedFile = file; } /** * Set the onClickListener object of this class with the given object. * * @param listener the object that will initialize the OnClickListener * of this class. */ public void setOnClickListener(OnClickListener listener) { this.onClickListener = listener; } /** * show the file manager dialog window to the screen. */ public void showFileManager() { if (!this.fileManagerDialog.isShowing()) this.fileManagerDialog.show(); } /** * close the file manager dialog window. */ public void closeFileManager() { if (this.fileManagerDialog.isShowing()) this.fileManagerDialog.dismiss(); } /** * Initialize the file manager dialog, and set the back press button's * onclick callback of the dialog. */ private void initFileManagerDialog() { this.fileManagerDialog = new Dialog(this.context) { int isPress = 0; @Override public void onBackPressed() { if (isPress == 0) { Toast.makeText(context, "Press back once more to exit", Toast.LENGTH_SHORT).show(); isPress = 1; new CountDownTimer(2000, 1000) { @Override public void onTick(long time) { } @Override public void onFinish() { isPress = 0; } }.start(); } else if (isPress == 1) { isPress = 0; fileManagerDialog.dismiss(); } } }; fileManagerDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); fileManagerDialog.setContentView(R.layout.abs_file_manager); fileManagerDialog.setCanceledOnTouchOutside(true); dialog_fillParent(fileManagerDialog); } /** * Init the title of the file manager dialog window. and * set its onclick callbacks. */ private void initFileManagerTitle() { title = (TextView) fileManagerDialog.findViewById(R.id.path_name); Views.setTextView(title, SD_ROOT_PATH, ABase.TITLE_SIZE); title.setSingleLine(false); title.setClickable(true); title.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (openedFile.isDirectory() && openedFile.canExecute() && openedFile.canWrite()) { if (onClickListener != null) { onClickListener.onSelectTitle(openedFile.getPath()); fileManagerDialog.dismiss(); } } else { String messageText = "This is not a valid folder. Please select other folders."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } }); title.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { vibrator.vibrate(20); createOrRenameFiles(null, vibrator, CREATE_MODE); return false; } }); } /** * Init the back button. */ private void initBackButton() { /* Back button of file manager dialog. */ ImageButton backButton = (ImageButton) fileManagerDialog.findViewById(R.id.back); /** * BackButton onClickListener. */ backButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { try { File file = openedFile.getParentFile(); if (file.isDirectory() && file.canExecute()) { run(file); openedFile = file; } else { vibrator.vibrate(20); String messageText = "This is not a valid folder."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } catch (Exception error) { vibrator.vibrate(20); String messageText = "This may be the root path. Can not go back from here."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } }); /** * backButton onLongClickListener. */ backButton.setOnLongClickListener(new View.OnLongClickListener() { public boolean onLongClick(View view) { Toast.makeText(context, "Back", Toast.LENGTH_SHORT).show(); return true; } }); } /** * Init the List. */ private void initListView() { listView = (ListView) fileManagerDialog.findViewById(R.id.quality_list); /** * listView onClickListener. */ listView.setOnItemClickListener(new ListView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapter, View view, int position, long id) { String filePath = fileAdapter.getFilePath(position); File file = new File(filePath); if (file.isDirectory() && file.canExecute()) { try { openedFile = file; run(file); } catch (Exception error) { error.printStackTrace(); vibrator.vibrate(20); String messageText = "This is not a valid folder. Please select other folders."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } else { vibrator.vibrate(20); String messageText = "Something goes wrong. Please report the problem to the developers" + " so that they can fix this as soon as possible.\n"; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } }); /** * listView onLongClickListener. */ listView.setOnItemLongClickListener(new ListView.OnItemLongClickListener() { public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id) { vibrator.vibrate(10); String filePath = ((FileAdapter) listView.getAdapter()).getFilePath(position); showFileOption(vibrator, position, filePath); return true; } }); } /** * Show file task options. */ private void showFileOption(Vibrator vibrator, int index, String filePath) { new FileOptions(context, vibrator, index, filePath); } /** * Show a dialog for either creating or renaming files or folders. * * @param operationFile the file which will be either created or renamed. * @param vibrator_ vibrator for vibrate device. * @param operationCode the operation code. Either CREATE_MODE or RENAME_MODE. */ private void createOrRenameFiles(final File operationFile, final Vibrator vibrator_, final int operationCode) { final Dialog dialog = new Dialog(context); dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); dialog.setContentView(R.layout.abs_create_new_file); dialog_fillParent(dialog); dialog.show(); TextView title = (TextView) dialog.findViewById(R.id.title); if (operationCode == CREATE_MODE) Views.setTextView(title, " Create Folder", ABase.TITLE_SIZE); else if (operationCode == RENAME_MODE) if (operationFile.isFile()) Views.setTextView(title, " Rename File", ABase.DEFAULT_SIZE); else Views.setTextView(title, " Rename Folder", ABase.DEFAULT_SIZE); //init the edit text. final EditText editText = (EditText) dialog.findViewById(R.id.name_edit); Views.setTextView(editText, (operationCode == RENAME_MODE) ? operationFile.getName() : "", 17.44f); //init the create button. TextView createButton = (TextView) dialog.findViewById(R.id.download); if (operationCode == CREATE_MODE) Views.setTextView(createButton, "Create", ABase.DEFAULT_SIZE); else if (operationCode == RENAME_MODE) Views.setTextView(createButton, "Rename", ABase.DEFAULT_SIZE); //create button. createButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { String fileName = editText.getText().toString(); if (fileName.equals("")) { String messageText = "Please give a folder name."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } else if (fileName.contains("/") || fileName.contains("?") || fileName.contains("*") || fileName.contains("?") || fileName.contains("<") || fileName.contains(">") || fileName.contains("|") || fileName.contains("~") || fileName.contains(":") || fileName.contains("ยป")) { String messageText = "You have entered bad input characters in the folder name. Please" + " correct them first."; MessageDialog messageDialog = new MessageDialog(context, "BAD CHARACTER INPUT", messageText); messageDialog.hideTitle(false); messageDialog.show(); } else { if (operationCode == CREATE_MODE) { try { File file = new File(FileManager.this.title.getText() + "/" + fileName); if (file.exists()) { String messageText = "Another file/folder is existed by the same name. Please give " + "different folder name."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } else { vibrator_.vibrate(20); if (file.mkdir()) { Toast.makeText(context, "File has been created.", Toast.LENGTH_SHORT).show(); fileArrayList.add(file); Collections.sort(fileArrayList); fileAdapter.notifyDataSetChanged(); dialog.dismiss(); } else { dialog.dismiss(); String messageText = "Failed to create the folder for an unaccepted error. Please" + " try again later."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } } catch (Exception error) { error.printStackTrace(); dialog.dismiss(); String messageText = "Something goes wrong. Please report the problem to the developers" + " so that they can fix this as soon as possible.\n"; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } else if (operationCode == RENAME_MODE) { try { File file = new File(FileManager.this.title.getText() + "/" + editText.getText().toString()); if (file.exists()) { String messageText = "Another file/folder is existed by the same name. Please give " + "different folder name."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } else { vibrator_.vibrate(20); File oldFile = operationFile; if (operationFile.renameTo(file)) { Toast.makeText(context, "File has been renamed.", Toast.LENGTH_SHORT).show(); fileArrayList.set(fileArrayList.indexOf(oldFile), file); Collections.sort(fileArrayList); fileAdapter.notifyDataSetChanged(); dialog.dismiss(); } else { dialog.dismiss(); String messageText = "Failed to create the folder for an unaccepted error. Please" + " try again later."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } } catch (Exception error) { error.printStackTrace(); dialog.dismiss(); String messageText = "Something goes wrong. Please report the problem to the developers" + " so that they can fix this as soon as possible.\n"; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } } } }); } /** * Call this when need to load the files in the list. * * @param file the parent file from which the child files will be loaded. */ private void run(File file) { new FileLoader().execute(file); } /** * OnClick listener for path selecting and openButton file task. */ public static interface OnClickListener { /** * Callback when user select the title. * * @param selectedPath The text of the title view.. basically the text is a folder path which user * can use to select something. */ public void onSelectTitle(String selectedPath); /** * Callback for viewing a file. * * @param file the file which to be viewed. * @param intent Use the pre structured intent to start new activity or use your new one. */ public void onOpenFile(File file, Intent intent); } /** * File option do some file operation task. */ @SuppressWarnings("UnusedDeclaration") private class FileOptions implements View.OnClickListener, Serializable { private Dialog dialog; private TextView title; private TextView openButton; private TextView selectButton; private TextView createFolderButton; private TextView renameButton; private TextView deleteButton; private Context context; private Vibrator vibrator; private int index; private String filePath; public FileOptions(Context context, Vibrator vibrator, int index, String filePath) { this.context = context; this.vibrator = vibrator; this.index = index; this.filePath = filePath; dialog = new Dialog(this.context); dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); dialog.setContentView(R.layout.abs_file_manager_option); dialog_fillParent(dialog); title = (TextView) dialog.findViewById(R.id.title); openButton = (TextView) dialog.findViewById(R.id.open); selectButton = (TextView) dialog.findViewById(R.id.rename); createFolderButton = (TextView) dialog.findViewById(R.id.create); renameButton = (TextView) dialog.findViewById(R.id.select); deleteButton = (TextView) dialog.findViewById(R.id.delete); Views.setTextView(title, "", ABase.TITLE_SIZE); Views.setTextView(openButton, "Open", ABase.DEFAULT_SIZE); Views.setTextView(selectButton, "Select", ABase.DEFAULT_SIZE); Views.setTextView(createFolderButton, "Add new folder", ABase.DEFAULT_SIZE); Views.setTextView(renameButton, "Rename", ABase.DEFAULT_SIZE); Views.setTextView(deleteButton, "Delete", ABase.DEFAULT_SIZE); openButton.setOnClickListener(this); selectButton.setOnClickListener(this); createFolderButton.setOnClickListener(this); renameButton.setOnClickListener(this); deleteButton.setOnClickListener(this); show(); title.setText(new File(this.filePath).getName()); } public void show() { dialog.show(); } public void closeFileOptions() { dialog.dismiss(); } public void open() { closeFileOptions(); File file = new File(filePath); if (file.isDirectory() && file.canExecute()) { try { openedFile = file; run(file); } catch (Exception error) { error.printStackTrace(); vibrator.vibrate(20); String messageText = "This is not a valid folder. Please select other folders."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } else { vibrator.vibrate(20); String messageText = "Something goes wrong. Please report the problem to the developers" + " so that they can fix this as soon as possible.\n"; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } /* try { File file = new File(filePath); String mimeType = NetworkUtils.getMimeType(Uri.fromFile(file).toString()); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), mimeType); if (onClickListener != null) { onClickListener.onOpenFile(file, intent); } } catch (Exception error) { error.printStackTrace(); new MessageDialog(context, " Failed !!", "Try to open the file from another app.") .dialog.show(); } */ } public void addNew() { closeFileOptions(); createOrRenameFiles(null, vibrator, CREATE_MODE); } public void rename() { closeFileOptions(); createOrRenameFiles(new File(filePath), vibrator, RENAME_MODE); } public void select() { closeFileOptions(); File file = new File(filePath); if (file.isDirectory() && file.canExecute() && file.canWrite()) { if (onClickListener != null) onClickListener.onSelectTitle(file.getPath()); dialog.dismiss(); fileManagerDialog.dismiss(); } else { dialog.dismiss(); vibrator.vibrate(20); String messageText = "This is not a valid folder. Please select other folders."; MessageDialog messageDialog = new MessageDialog(context, "", messageText); messageDialog.hideTitle(true); messageDialog.show(); } } public void delete() { dialog.dismiss(); YesNoDialog builder = new YesNoDialog(context, "Are you sure to delete : \n \"" + filePath + "\" ", new YesNoDialog.OnClick() { @Override public void onYesClick(Dialog dialog, TextView view) { dialog.dismiss(); closeFileOptions(); new AsyncTask<Void, Void, Void>() { private ProgressDialog progressDialog; private int isCancel = 0; private int deleted = 2 , notDeleted = 4 , isDeleted = notDeleted; private File file; @Override protected void onPreExecute() { progressDialog = new ProgressDialog(context, false, "Wait.. files about to deleting."); progressDialog.getDialog().setOnDismissListener(new Dialog.OnDismissListener() { @Override public void onDismiss(DialogInterface dialogInterface) { isCancel = 1; } }); progressDialog.show(); } @Override protected Void doInBackground(Void... voids) { try { file = new File(filePath); if (StorageUtils.delete(file)) isDeleted = deleted; else isDeleted = notDeleted; } catch (Exception error) { error.printStackTrace(); } return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); progressDialog.close(); if (isDeleted == deleted) { fileArrayList.remove(file); Collections.sort(fileArrayList); fileAdapter.notifyDataSetChanged(); Toast.makeText(context, "Deleted.", Toast.LENGTH_SHORT).show(); } else Toast.makeText(context, "Failed to delete the file.", Toast.LENGTH_SHORT).show(); } }.execute(); } @Override public void onNoClick(Dialog dialog, TextView view) { dialog.dismiss(); } }); builder.dialog.show(); } public void onClick(View view) { final TextView textView = (TextView) view; if (textView.equals(openButton)) { open(); } else if (textView.equals(createFolderButton)) { addNew(); } else if (textView.equals(renameButton)) { rename(); } else if (textView.equals(selectButton)) { select(); } else if (textView.equals(deleteButton)) { delete(); } } } /** * */ private class FileLoader extends AsyncTask<File, Void, Void> { protected File file; @Override protected void onPreExecute() { super.onPreExecute(); title.setText("Loading...."); fileArrayList.clear(); } @Override protected Void doInBackground(File... param) { file = param[0]; File[] fileList = file.listFiles(); for (File childFile : fileList) { String fileName = childFile.getName(); if (!fileName.startsWith(".")) { if (childFile.isDirectory()) fileArrayList.add(childFile); } } Collections.sort(fileArrayList); return null; } @Override protected void onPostExecute(Void result) { super.onPostExecute(result); fileAdapter.notifyDataSetChanged(); if (this.file != null) { title.setText(file.getPath()); } } } }