diff --git a/folderpicker/build.gradle b/folderpicker/build.gradle index d775d4b..ee4a1fb 100644 --- a/folderpicker/build.gradle +++ b/folderpicker/build.gradle @@ -25,12 +25,12 @@ ext { } android { - compileSdkVersion 27 - buildToolsVersion "27.0.3" + compileSdkVersion 28 + buildToolsVersion "28.0.3" defaultConfig { minSdkVersion 9 - targetSdkVersion 27 + targetSdkVersion 28 versionCode 4 versionName "2.4" diff --git a/folderpicker/src/main/java/lib/folderpicker/FolderAdapter.java b/folderpicker/src/main/java/lib/folderpicker/FolderAdapter.java index 97aee2d..07f9f6a 100644 --- a/folderpicker/src/main/java/lib/folderpicker/FolderAdapter.java +++ b/folderpicker/src/main/java/lib/folderpicker/FolderAdapter.java @@ -1,6 +1,6 @@ package lib.folderpicker; -import android.app.Activity; +import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -12,35 +12,43 @@ public class FolderAdapter extends ArrayAdapter { - Activity context; - ArrayList dataList; + /** + * + */ + private class FileViewHolder { + ImageView iconView; + TextView nameView; + } - public FolderAdapter(Activity context, ArrayList dataList) { + private LayoutInflater mInflater; + private Context mContext; + private ArrayList dataList; + public FolderAdapter(Context context, ArrayList dataList) { super(context, R.layout.fp_filerow, dataList); - this.context = context; + this.mContext = context; + this.mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.dataList = dataList; } @Override public View getView(int position, View convertView, ViewGroup parent) { - LayoutInflater inflater = context.getLayoutInflater(); - convertView = inflater.inflate(R.layout.fp_filerow, parent, false); - - ImageView imageView = (ImageView) convertView.findViewById(R.id.fp_iv_icon); - TextView name = (TextView) convertView.findViewById(R.id.fp_tv_name); - - if( dataList.get(position).isFolder() ) - { - imageView.setImageResource( R.drawable.fp_folder); - } - else - { - imageView.setImageResource( R.drawable.fp_file); + FileViewHolder viewHolder; + if (convertView == null) { + viewHolder = new FileViewHolder(); + convertView = mInflater.inflate(R.layout.fp_filerow, null); + viewHolder.iconView = convertView.findViewById(R.id.fp_iv_icon); + viewHolder.nameView = convertView.findViewById(R.id.fp_tv_name); + convertView.setTag(viewHolder); + } else { + viewHolder = (FileViewHolder) convertView.getTag(); } - name.setText( dataList.get(position).getName() ); + FilePojo item = dataList.get(position); + int iconRes = (item.isFolder()) ? R.drawable.fp_folder : R.drawable.fp_file; + viewHolder.iconView.setImageResource(iconRes); + viewHolder.nameView.setText(item.getName()); return convertView; } diff --git a/folderpicker/src/main/java/lib/folderpicker/FolderPicker.java b/folderpicker/src/main/java/lib/folderpicker/FolderPicker.java index c5d1a21..c105f3c 100644 --- a/folderpicker/src/main/java/lib/folderpicker/FolderPicker.java +++ b/folderpicker/src/main/java/lib/folderpicker/FolderPicker.java @@ -6,6 +6,7 @@ import android.content.Intent; import android.os.Bundle; import android.os.Environment; +import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import android.widget.EditText; @@ -20,17 +21,30 @@ public class FolderPicker extends Activity { + Comparator comparatorAscending = new Comparator() { + @Override + public int compare(FilePojo f1, FilePojo f2) { + return f1.getName().compareTo(f2.getName()); + } + }; + + public static final String EXTRA_DATA = "data"; + public static final String EXTRA_TITLE = "title"; + public static final String EXTRA_DESCRIPTION = "desc"; + public static final String EXTRA_LOCATION = "location"; + public static final String EXTRA_PICK_FILES = "pickFiles"; + public static final String EXTRA_EMPTY_FOLDER = "emptyFolder"; //Folders and Files have separate lists because we show all folders first then files - ArrayList folderAndFileList; - ArrayList foldersList; - ArrayList filesList; + ArrayList mFolderAndFileList; + ArrayList mFoldersList; + ArrayList mFilesList; - TextView tv_title; - TextView tv_location; + TextView mTvLocation; - String location = Environment.getExternalStorageDirectory().getAbsolutePath(); - boolean pickFiles; - Intent receivedIntent; + String mLocation; + boolean mPickFiles; + Intent mReceivedIntent; + boolean mEmptyFolder; @Override protected void onCreate(Bundle savedInstanceState) { @@ -38,49 +52,67 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.fp_main_layout); if (!isExternalStorageReadable()) { - Toast.makeText(this, "Storage access permission not given", Toast.LENGTH_LONG).show(); + Toast.makeText(this, getString(R.string.no_access_to_storage), Toast.LENGTH_LONG).show(); finish(); } - tv_title = (TextView) findViewById(R.id.fp_tv_title); - tv_location = (TextView) findViewById(R.id.fp_tv_location); + String location = Environment.getExternalStorageDirectory().getAbsolutePath(); + + mTvLocation = findViewById(R.id.fp_tv_location); try { - receivedIntent = getIntent(); + mReceivedIntent = getIntent(); + + if (mReceivedIntent.hasExtra(EXTRA_TITLE)) { + String title = mReceivedIntent.getStringExtra(EXTRA_TITLE); + if (title != null) { + ((TextView)findViewById(R.id.fp_tv_title)).setText(title); + } + } - if (receivedIntent.hasExtra("title")) { - String receivedTitle = receivedIntent.getExtras().getString("title"); - if (receivedTitle != null) { - tv_title.setText(receivedTitle); + if (mReceivedIntent.hasExtra(EXTRA_DESCRIPTION)) { + String desc = mReceivedIntent.getStringExtra(EXTRA_DESCRIPTION); + if (desc != null) { + TextView textView = findViewById(R.id.fp_tv_desc); + textView.setVisibility(View.VISIBLE); + textView.setText(desc); } } - if (receivedIntent.hasExtra("location")) { - String reqLocation = receivedIntent.getExtras().getString("location"); - if (reqLocation != null) { - File requestedFolder = new File(reqLocation); - if (requestedFolder.exists()) - location = reqLocation; + if (mReceivedIntent.hasExtra(EXTRA_LOCATION)) { + String newLocation = mReceivedIntent.getStringExtra(EXTRA_LOCATION); + if (newLocation != null) { + File folder = new File(newLocation); + if (folder.exists()) + location = newLocation; } } - if (receivedIntent.hasExtra("pickFiles")) { - pickFiles = receivedIntent.getExtras().getBoolean("pickFiles"); - if (pickFiles) { + if (mReceivedIntent.hasExtra(EXTRA_PICK_FILES)) { + mPickFiles = mReceivedIntent.getBooleanExtra(EXTRA_PICK_FILES, false); + if (mPickFiles) { findViewById(R.id.fp_btn_select).setVisibility(View.GONE); findViewById(R.id.fp_btn_new).setVisibility(View.GONE); } } + if (mReceivedIntent.hasExtra(EXTRA_EMPTY_FOLDER)) { + mEmptyFolder = mReceivedIntent.getBooleanExtra(EXTRA_EMPTY_FOLDER, false); + if (mEmptyFolder) { + findViewById(R.id.fp_tv_empty_dir).setVisibility(View.VISIBLE); + } + } + } catch (Exception e) { e.printStackTrace(); } - loadLists(location); - + checkAndLoadLists(location); } - /* Checks if external storage is available to at least read */ + /** + * Checks if external storage is available to at least read + */ boolean isExternalStorageReadable() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state) || @@ -90,39 +122,76 @@ boolean isExternalStorageReadable() { return false; } - void loadLists(String location) { - try { + boolean checkAndLoadLists(String location, boolean showToast) { + if (checkLocation(location, showToast)) { + mLocation = location; + loadLists(); + return true; + } + return false; + } - File folder = new File(location); + boolean checkAndLoadLists(String location) { + return checkAndLoadLists(location, true); + } - if (!folder.isDirectory()) - exit(); + /** + * Check location and load lists if location is correct. + * @param location + * @param showToast + * @return + */ + private boolean checkLocation(String location, boolean showToast) { + File folder = new File(location); + + if (!folder.exists()) { + if (showToast) { + Toast.makeText(this, R.string.dir_is_not_exist, Toast.LENGTH_LONG).show(); + } + return false; + } + + if (!folder.isDirectory()) { + if (showToast) { + Toast.makeText(this, R.string.is_not_dir, Toast.LENGTH_LONG).show(); + } + return false; + } + return true; + } + + /** + * Load lists and show. + */ + void loadLists() { + try { + File folder = new File(mLocation); - tv_location.setText("Location : " + folder.getAbsolutePath()); + mTvLocation.setText(String.format(getString(R.string.location_mask), folder.getAbsolutePath())); File[] files = folder.listFiles(); - foldersList = new ArrayList<>(); - filesList = new ArrayList<>(); + mFoldersList = new ArrayList<>(); + mFilesList = new ArrayList<>(); for (File currentFile : files) { if (currentFile.isDirectory()) { FilePojo filePojo = new FilePojo(currentFile.getName(), true); - foldersList.add(filePojo); + mFoldersList.add(filePojo); } else { FilePojo filePojo = new FilePojo(currentFile.getName(), false); - filesList.add(filePojo); + mFilesList.add(filePojo); } } // sort & add to final List - as we show folders first add folders first to the final list - Collections.sort(foldersList, comparatorAscending); - folderAndFileList = new ArrayList<>(); - folderAndFileList.addAll(foldersList); + Collections.sort(mFoldersList, comparatorAscending); + mFolderAndFileList = new ArrayList<>(); + mFolderAndFileList.addAll(mFoldersList); //if we have to show files, then add files also to the final list - if (pickFiles) { - Collections.sort( filesList, comparatorAscending ); - folderAndFileList.addAll(filesList); + if (mPickFiles) { + Collections.sort(mFilesList, comparatorAscending ); + mFolderAndFileList.addAll(mFilesList); } showList(); @@ -131,22 +200,15 @@ void loadLists(String location) { e.printStackTrace(); } - } // load List - - - Comparator comparatorAscending = new Comparator() { - @Override - public int compare(FilePojo f1, FilePojo f2) { - return f1.getName().compareTo(f2.getName()); - } - }; - + } + /** + * Show list of folders and files. + */ void showList() { - try { - FolderAdapter FolderAdapter = new FolderAdapter(this, folderAndFileList); - ListView listView = (ListView) findViewById(R.id.fp_listView); + FolderAdapter FolderAdapter = new FolderAdapter(this, mFolderAndFileList); + ListView listView = findViewById(R.id.fp_listView); listView.setAdapter(FolderAdapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @@ -156,108 +218,170 @@ public void onItemClick(AdapterView parent, View view, listClick(position); } }); - } catch (Exception e) { e.printStackTrace(); } - } - + /** + * Click on the list item. + * @param position + */ void listClick(int position) { - - if (pickFiles && !folderAndFileList.get(position).isFolder()) { - String data = location + File.separator + folderAndFileList.get(position).getName(); - receivedIntent.putExtra("data", data); - setResult(RESULT_OK, receivedIntent); + if (mPickFiles && !mFolderAndFileList.get(position).isFolder()) { + String data = mLocation + File.separator + mFolderAndFileList.get(position).getName(); + mReceivedIntent.putExtra(EXTRA_DATA, data); + setResult(RESULT_OK, mReceivedIntent); finish(); } else { - location = location + File.separator + folderAndFileList.get(position).getName(); - loadLists(location); - } - - } - - @Override - public void onBackPressed(){ - goBack(null); - } - - public void goBack(View v) { - - if (location != null && !location.equals("") && !location.equals("/")) { - int start = location.lastIndexOf('/'); - String newLocation = location.substring(0, start); - location = newLocation; - loadLists(location); - }else{ - exit(); + String location = mLocation + File.separator + mFolderAndFileList.get(position).getName(); + checkAndLoadLists(location); +// checkAndloadLists(mLocation); } - } - void exit(){ - setResult(RESULT_CANCELED, receivedIntent); - finish(); + public void home(View v) { + String location = Environment.getExternalStorageDirectory().getAbsolutePath(); + checkAndLoadLists(location); } + /** + * Create new folder. + * @param filename + */ void createNewFolder(String filename) { try { - - File file = new File(location + File.separator + filename); + File file = new File(mLocation + File.separator + filename); file.mkdirs(); - loadLists(location); + checkAndLoadLists(mLocation); } catch (Exception e) { e.printStackTrace(); - Toast.makeText(this, "Error:" + e.toString(), Toast.LENGTH_LONG) + Toast.makeText(this, String.format(getString(R.string.error_string_mask), e.toString()), Toast.LENGTH_LONG) .show(); } - } + /** + * Show dialog fom enter new folder name; + * @param v + */ public void newFolderDialog(View v) { - AlertDialog dialog = new AlertDialog.Builder(this).create(); - dialog.setTitle("Enter Folder Name"); + LayoutInflater inflater = LayoutInflater.from(this); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + View view = inflater.inflate(R.layout.dialog_folder_name, null); + builder.setView(view); + builder.setTitle(getString(R.string.enter_folder_name)); - final EditText et = new EditText(this); - dialog.setView(et); + final EditText et = view.findViewById(R.id.edit_text); - dialog.setButton(DialogInterface.BUTTON_POSITIVE, "Create", + final AlertDialog dialog = builder.create(); + dialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.create), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { createNewFolder(et.getText().toString()); } }); - dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", + dialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel), (DialogInterface.OnClickListener)null); + + dialog.show(); + } + + /** + * Select the destination folder or file. + * @param v + */ + public void select(View v) { + + if (mPickFiles) { + Toast.makeText(this, getString(R.string.select_file), Toast.LENGTH_LONG).show(); + } else if (mReceivedIntent != null) { + if (mEmptyFolder && !isDirEmpty(mLocation)) { + Toast.makeText(this, getString(R.string.select_empty_folder), Toast.LENGTH_LONG).show(); + return; + } + mReceivedIntent.putExtra(EXTRA_DATA, mLocation); + setResult(RESULT_OK, mReceivedIntent); + finish(); + } + } + + /** + * Edit path manually. + * @param v + */ + public void edit(View v) { + LayoutInflater inflater = LayoutInflater.from(this); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + View view = inflater.inflate(R.layout.dialog_edit_location, null); + builder.setView(view); + builder.setTitle(getString(R.string.edit_location)); + + final EditText et = view.findViewById(R.id.edit_text); + if (mLocation != null) { + et.setText(mLocation); + et.setSelection(mLocation.length()); + } + + final AlertDialog dialog = builder.create(); + dialog.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.ok), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { - + String location = et.getText().toString(); +// loadLists(mLocation); + checkAndLoadLists(location); } }); + dialog.setButton(DialogInterface.BUTTON_NEGATIVE, getString(R.string.cancel), (DialogInterface.OnClickListener)null); dialog.show(); - } + /** + * Check if folder is empty. + * @param path + * @return + */ + boolean isDirEmpty(String path) { + File dir = new File(path); + File[] childs = dir.listFiles(); + return (childs == null || childs.length == 0); + } - public void select(View v) { + @Override + public void onBackPressed(){ + goBack(null); + } - if (pickFiles) { - Toast.makeText(this, "You have to select a file", Toast.LENGTH_LONG).show(); - } else if (receivedIntent != null) { - receivedIntent.putExtra("data", location); - setResult(RESULT_OK, receivedIntent); - finish(); + /** + * Load upper level path or exit. + * @param v + */ + public void goBack(View v) { + if (mLocation != null && !mLocation.equals("") && !mLocation.equals("/")) { + int start = mLocation.lastIndexOf('/'); + String newLocation = mLocation.substring(0, start); +// mLocation = newLocation; +// loadLists(newLocation); + if (!checkAndLoadLists(newLocation, false)) { + exit(); + } + } else { + exit(); } } - public void cancel(View v) { exit(); } - -} // class + /** + * Set result and finish activity. + */ + void exit() { + setResult(RESULT_CANCELED, mReceivedIntent); + finish(); + } +} diff --git a/folderpicker/src/main/res/drawable/fp_ic_action_home.xml b/folderpicker/src/main/res/drawable/fp_ic_action_home.xml new file mode 100644 index 0000000..7c20db1 --- /dev/null +++ b/folderpicker/src/main/res/drawable/fp_ic_action_home.xml @@ -0,0 +1,11 @@ + + + diff --git a/folderpicker/src/main/res/layout/dialog_edit_location.xml b/folderpicker/src/main/res/layout/dialog_edit_location.xml new file mode 100644 index 0000000..e688c7b --- /dev/null +++ b/folderpicker/src/main/res/layout/dialog_edit_location.xml @@ -0,0 +1,19 @@ + + + + + + + + + + \ No newline at end of file diff --git a/folderpicker/src/main/res/layout/dialog_folder_name.xml b/folderpicker/src/main/res/layout/dialog_folder_name.xml new file mode 100644 index 0000000..e688c7b --- /dev/null +++ b/folderpicker/src/main/res/layout/dialog_folder_name.xml @@ -0,0 +1,19 @@ + + + + + + + + + + \ No newline at end of file diff --git a/folderpicker/src/main/res/layout/fp_main_layout.xml b/folderpicker/src/main/res/layout/fp_main_layout.xml index 4574fea..cbfe58f 100644 --- a/folderpicker/src/main/res/layout/fp_main_layout.xml +++ b/folderpicker/src/main/res/layout/fp_main_layout.xml @@ -1,4 +1,4 @@ - + + + + + + + android:text="@string/up" /> + android:text="@string/neww" /> + android:text="@string/select" /> + android:text="@string/cancel" /> - + android:layout_height="wrap_content" + android:layout_below="@id/fp_buttonsLayout" /> - + diff --git a/folderpicker/src/main/res/values-ru/strings.xml b/folderpicker/src/main/res/values-ru/strings.xml new file mode 100644 index 0000000..45fc538 --- /dev/null +++ b/folderpicker/src/main/res/values-ru/strings.xml @@ -0,0 +1,22 @@ + + + Отмена + Расположение + Создать + Выбрать + Домой + Выше + Выбрать каталог + Введите имя каталога + Введите путь + Создать + Ok + Выберите файл + Выберите пустой каталог + Нет доступа к хранилищу + Путь: %s + Ошибка: %s + Выберите пустой каталог + Это не каталог + Каталог не существует + \ No newline at end of file diff --git a/folderpicker/src/main/res/values/strings.xml b/folderpicker/src/main/res/values/strings.xml index ada2cdd..c5016b5 100644 --- a/folderpicker/src/main/res/values/strings.xml +++ b/folderpicker/src/main/res/values/strings.xml @@ -1,10 +1,22 @@ - Folder Picker + Folder Picker + Home Up New Select Cancel - Select Folder + Select folder Location - Allow permissions to view files + Enter folder name + Edit location + Create + Ok + You have to select a file + You have to select an empty folder + Storage access permission not given + Location: %s + Error: %s + Select an empty directory + This is not a directory + Directory does not exist diff --git a/folderpicker/src/main/res/values/styles.xml b/folderpicker/src/main/res/values/styles.xml new file mode 100644 index 0000000..c8edbfc --- /dev/null +++ b/folderpicker/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + \ No newline at end of file