├── AndroidManifest.xml
├── Arabic_locale_sample.png
├── Japan_locale_sample.png
├── LICENSE
├── README.md
├── libs
├── cwac-merge-1.0.4.jar
└── picasso-2.4.0.jar
├── project.properties
├── res
├── drawable-hdpi
│ ├── blank.png
│ ├── btn_check_label_background.9.png
│ ├── btn_check_off_holo_dark.png
│ ├── btn_check_on_holo_dark.png
│ ├── customcheckbox.xml
│ ├── customcheckbox_background.xml
│ ├── document.png
│ ├── document_gray.png
│ └── folder.png
├── drawable-ldpi
│ ├── document.png
│ ├── document_gray.png
│ ├── folder.png
│ └── ic_launcher.png
├── drawable-mdpi
│ ├── document.png
│ ├── document_gray.png
│ ├── folder.png
│ └── ic_launcher.png
├── drawable-xxhdpi
│ └── ic_launcher.png
├── layout
│ ├── activity_file_selection.xml
│ ├── list_single.xml
│ └── list_single_only.xml
├── menu
│ └── main.xml
├── values-ar
│ └── strings.xml
├── values-de
│ └── strings.xml
├── values-es
│ └── strings.xml
├── values-fr
│ └── strings.xml
├── values-id
│ └── strings.xml
├── values-it
│ └── strings.xml
├── values-ja
│ └── strings.xml
├── values-ko
│ └── strings.xml
├── values-pt
│ └── strings.xml
├── values-ru
│ └── strings.xml
├── values-sw600dp
│ └── dimens.xml
├── values-sw720dp-land
│ └── dimens.xml
├── values-v11
│ └── styles.xml
├── values-v14
│ └── styles.xml
├── values-zh
│ └── strings.xml
└── values
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── sample.png
└── src
└── paul
└── arian
└── fileselector
├── CheckableRelativeLayout.java
├── CustomList.java
├── CustomListSingleOnly.java
├── FileSelectionActivity.java
└── FolderSelectionActivity.java
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Arabic_locale_sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/Arabic_locale_sample.png
--------------------------------------------------------------------------------
/Japan_locale_sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/Japan_locale_sample.png
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Paul Asiimwe
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Android Multiple File Selector Dialog
2 |
3 |
4 |
5 | ###Introduction
6 |
7 | 
8 |
9 |
10 | 
11 |
12 |
13 | 
14 |
15 | **Supports API 8(+)**
16 |
17 | This is a free to use,change and reproduce Android Library file selector dialog whose birth arose from this question I posted on Stackoverflow
18 |
19 | http://stackoverflow.com/questions/22095441/android-multiple-file-selector-chooser-dialog
20 |
21 | This library starts a file/folder selector activity and returns the file(s) (Yes Multiple option too) or folder.
22 | Your contribution is highly welcome
23 |
24 | ###Features
25 | Thumbnails for Images
26 |
27 | Language support for English, Arabic, Simplified Chinese, German, French, Indonesian, Italian, Korean, Japanese, Russian, Spanish and Portuguese
28 |
29 | AutoScroll to last ScrollPosition on Back Pressed
30 |
31 | New Folder Button
32 |
33 | Button to access External/Internal Storage **not fully tested** :-)
34 |
35 |
36 | ###Usage
37 | Add these activities in your manifest Within the .
38 | ```
39 |
40 |
42 |
44 |
45 | ```
46 | Add this Permission too
47 | ```
48 |
49 | ```
50 |
51 |
52 | Then also **add merge 1.04.jar** and **picasso jar** located in the repo to this library's build path or module
53 |
54 | #### File Selector
55 |
56 | To start the fileSelector
57 | first import.
58 | ```java
59 | import paul.arian.fileselector.FileSelectionActivity;
60 | ```
61 | use this code
62 |
63 | ```java
64 | Intent intent = new Intent(getBaseContext(), FileSelectionActivity.class);
65 | startActivityForResult(intent, 0);
66 | ```
67 |
68 | To capture the result, use this method.
69 |
70 | ```java
71 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
72 | if(requestCode == 0 && resultCode == RESULT_OK){
73 | ArrayList Files = (ArrayList) data.getSerializableExtra(FILES_TO_UPLOAD); //file array list
74 | String [] files_paths; //string array
75 | int i = 0;
76 |
77 | for(File file : Files){
78 | //String fileName = file.getName();
79 | String uri = file.getAbsolutePath();
80 | files_paths[i] = uri.toString(); //storing the selected file's paths to string array files_paths
81 | i++;
82 | }
83 | }else{
84 | }
85 |
86 | }
87 |
88 | ```
89 |
90 | #### Folder Selector
91 |
92 | To start folder selection activity,
93 |
94 | import:
95 | ```java
96 | import paul.arian.fileselector.FolderSelectionActivity;
97 | ```
98 | to start use this code.
99 | ```java
100 | Intent intent = new Intent(getBaseContext(), FolderSelectionActivity.class);
101 | startActivityForResult(intent, 2);
102 | ```
103 | To capture, use this method.
104 |
105 | ```
106 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
107 | if(requestCode == 2 && resultCode == RESULT_OK){
108 | String FolderPath = data.getSerializableExtra(FILES_TO_UPLOAD).toString(); //The path of folder(directory) is stored in FolderPath string.
109 | }
110 | }
111 | ```
112 |
113 | ###### Credits
114 | Massive credit goes to Arian JM of Madrid who created the majority of this library.
115 |
116 | Here is his Github: https://github.com/ArianJM
117 |
118 | Looking forward to your feedback, collaboration and assistence.
119 |
120 | regards,
121 |
122 | Paul Asiimwe,
123 |
124 | Kampala, Uganda,
125 |
126 | https://google.com/+PaulAsiimwe
127 |
128 | https://twitter.com/_paulasiimwe
129 |
--------------------------------------------------------------------------------
/libs/cwac-merge-1.0.4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/libs/cwac-merge-1.0.4.jar
--------------------------------------------------------------------------------
/libs/picasso-2.4.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/libs/picasso-2.4.0.jar
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-19
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/blank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-hdpi/blank.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/btn_check_label_background.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-hdpi/btn_check_label_background.9.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/btn_check_off_holo_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-hdpi/btn_check_off_holo_dark.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/btn_check_on_holo_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-hdpi/btn_check_on_holo_dark.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/customcheckbox.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/customcheckbox_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/document.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-hdpi/document.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/document_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-hdpi/document_gray.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-hdpi/folder.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/document.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-ldpi/document.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/document_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-ldpi/document_gray.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-ldpi/folder.png
--------------------------------------------------------------------------------
/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/document.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-mdpi/document.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/document_gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-mdpi/document_gray.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-mdpi/folder.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/layout/activity_file_selection.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
19 |
20 |
27 |
28 |
29 |
36 |
37 |
38 |
39 |
45 |
46 |
47 |
48 |
53 |
54 |
60 |
61 |
67 |
68 |
74 |
75 |
--------------------------------------------------------------------------------
/res/layout/list_single.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
19 |
29 |
--------------------------------------------------------------------------------
/res/layout/list_single_only.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
16 |
17 |
--------------------------------------------------------------------------------
/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/res/values-ar/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | مربع حوار تحديد الملفات Parian
4 | الإعدادات
5 | موافق
6 | ملفات
7 | مجلدات
8 | انتقل لأعلى
9 | تحديد الكل
10 | إلغاء
11 | إلغاء تحديد الكل
12 | خارجي
13 | داخلي
14 | مجلد جديد
15 | أدخل اسم المجلد الجديد
16 | إنشاء
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Parian Datei-Auswahl-Dialog
4 | Einstellungen
5 | Ok
6 | Dateien
7 | Ordner
8 | Nach oben
9 | Alle auswählen
10 | Abbrechen
11 |
12 | Extern
13 | Intern
14 | Neuer Ordner
15 | Geben Sie einen neuen Ordner-Namen ein
16 | Erstellen
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/res/values-es/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Diálogo de selección de archivo parian
4 | Ajustes
5 | De acuerdo
6 | Archivos
7 | Carpetas
8 | Ir arriba
9 | Seleccionar Todos
10 | Cancelar
11 | Deseleccionar Todos
12 | Externo
13 | Interno
14 | Nueva carpeta
15 | Introducir nombre de Nueva carpeta
16 | Crear
17 |
18 |
19 |
--------------------------------------------------------------------------------
/res/values-fr/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Dialogue de sélection de fichier de Parian
4 | Paramètres
5 | OK
6 | Fichiers
7 | Dossiers
8 | Monter
9 | Tout cocher
10 | Annuler
11 | Tout décocher
12 | Externe
13 | Interne
14 | Nouveau dossier
15 | Saisissez le nouveau nom de dossier
16 | Créer
17 |
18 |
19 |
--------------------------------------------------------------------------------
/res/values-id/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Dialog Pemilih File Parian
4 | Pengaturan
5 | OKE
6 | File
7 | Folder
8 | Naik
9 | Centang Semua
10 | Batalkan
11 | Hapus Semua Centang
12 | Eksternal
13 | Internal
14 | Folder Baru
15 | Masukkan Nama Folder Baru
16 | Buat
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/res/values-it/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Casella di dialogo del selettore di file Parian
4 | Impostazioni
5 | OK
6 | File
7 | Cartelle
8 | Salire
9 | Selezionare tutto
10 | Cancellare
11 | Deselezionare tutto
12 | Esterno
13 | Interno
14 | Nuova cartella
15 | Inserire il nome della Nuova cartella
16 | Creare
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/res/values-ja/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Parian ファイルセレクターダイアログ
4 | 設定
5 | OK
6 | ファイル
7 | フォルダ
8 | 上へ
9 | 全てチェック
10 | キャンセル
11 | 全てのチェクを外す
12 | 外部
13 | 内部
14 | 新規フォルダ
15 | 新しいフォルダ名を入力
16 | 作成
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/res/values-ko/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Parian File Selector 대화 상자
4 | 설정
5 | OK
6 | 파일
7 | 폴더
8 | 위로 이동
9 | 모두 선택
10 | 취소
11 | 모두 선택 해제
12 | 외부
13 | 내부
14 | 새 폴더
15 | 새 폴더 이름 입력
16 | 생성
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/res/values-pt/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Caixa de diálogo Seletor de ficheiros Parian
4 | Definições
5 | OK
6 | Ficheiros
7 | Pastas
8 | Subir
9 | Selecionar tudo
10 | Cancelar
11 | Desmarcar tudo
12 | Externo
13 | Interno
14 | Nova pasta
15 | Introduza o nome da nova pasta
16 | Criar
17 |
18 |
19 |
--------------------------------------------------------------------------------
/res/values-ru/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Диалог выбора файла Parian
4 | Настройки
5 | Выбрать
6 | Файлы
7 | Папки
8 | Вверх
9 | Отметить все
10 | Отмена
11 | Снять отметку со всех
12 | Карта памяти
13 | Внутренняя
14 | Новая папка
15 | Ввести имя новой папки
16 | Создать
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Parian文件选择器对话框
4 | 设置
5 | 确定
6 | 文件
7 | 文件夹
8 | 向上
9 | 全选
10 | 取消
11 | 取消全选
12 | 外部
13 | 内部
14 | 新建文件夹
15 | 输入新文件夹名称
16 | 创建
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Parian File Selector Dialog
5 | Settings
6 | OK
7 | Files
8 | Folders
9 | Go Up
10 | Check All
11 | Cancel
12 | Uncheck All
13 | External
14 | Internal
15 | New Folder
16 | Enter New Folder Name
17 | Create
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulasiimwe/Android-Multiple-file-Selector-Dialog/15a4c0a89084294482e0f0caa6c0e98c3e142929/sample.png
--------------------------------------------------------------------------------
/src/paul/arian/fileselector/CheckableRelativeLayout.java:
--------------------------------------------------------------------------------
1 | package paul.arian.fileselector;
2 | /**
3 | * Created by Paul on 3/7/14.
4 | */
5 | import java.util.ArrayList;
6 | import java.util.List;
7 |
8 | import android.content.Context;
9 | import android.util.AttributeSet;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.Checkable;
13 | import android.widget.RelativeLayout;
14 |
15 | /**
16 | * Extension of a relative layout to provide a checkable behaviour
17 | *
18 | * @author marvinlabs
19 | */
20 | public class CheckableRelativeLayout extends RelativeLayout implements
21 | Checkable {
22 |
23 | private boolean isChecked;
24 | private List checkableViews;
25 |
26 | public CheckableRelativeLayout(Context context, AttributeSet attrs,
27 | int defStyle) {
28 | super(context, attrs, defStyle);
29 | initialise(attrs);
30 | }
31 |
32 | public CheckableRelativeLayout(Context context, AttributeSet attrs) {
33 | super(context, attrs);
34 | initialise(attrs);
35 | }
36 |
37 | public CheckableRelativeLayout(Context context, int checkableId) {
38 | super(context);
39 | initialise(null);
40 | }
41 |
42 | /*
43 | * @see android.widget.Checkable#isChecked()
44 | */
45 | public boolean isChecked() {
46 | return isChecked;
47 | }
48 |
49 | /*
50 | * @see android.widget.Checkable#setChecked(boolean)
51 | */
52 | public void setChecked(boolean isChecked) {
53 | this.isChecked = isChecked;
54 | for (Checkable c : checkableViews) {
55 | c.setChecked(isChecked);
56 | }
57 | }
58 |
59 | /*
60 | * @see android.widget.Checkable#toggle()
61 | */
62 | public void toggle() {
63 | this.isChecked = !this.isChecked;
64 | for (Checkable c : checkableViews) {
65 | c.toggle();
66 | }
67 | }
68 |
69 | @Override
70 | protected void onFinishInflate() {
71 | super.onFinishInflate();
72 |
73 | final int childCount = this.getChildCount();
74 | for (int i = 0; i < childCount; ++i) {
75 | findCheckableChildren(this.getChildAt(i));
76 | }
77 | }
78 |
79 | /**
80 | * Read the custom XML attributes
81 | */
82 | private void initialise(AttributeSet attrs) {
83 | this.isChecked = false;
84 | this.checkableViews = new ArrayList(5);
85 | }
86 |
87 | /**
88 | * Add to our checkable list all the children of the view that implement the
89 | * interface Checkable
90 | */
91 | private void findCheckableChildren(View v) {
92 | if (v instanceof Checkable) {
93 | this.checkableViews.add((Checkable) v);
94 | }
95 |
96 | if (v instanceof ViewGroup) {
97 | final ViewGroup vg = (ViewGroup) v;
98 | final int childCount = vg.getChildCount();
99 | for (int i = 0; i < childCount; ++i) {
100 | findCheckableChildren(vg.getChildAt(i));
101 | }
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/paul/arian/fileselector/CustomList.java:
--------------------------------------------------------------------------------
1 | package paul.arian.fileselector;
2 |
3 | /**
4 | * Created by Paul on 3/7/14.
5 | */
6 | import android.app.Activity;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ArrayAdapter;
11 | import android.widget.ImageView;
12 | import android.widget.TextView;
13 |
14 | import com.squareup.picasso.Picasso;
15 |
16 | import java.io.File;
17 |
18 | public class CustomList extends ArrayAdapter{
19 | private final Activity context;
20 | private final String[] web;
21 | String ParentFolder;
22 | public CustomList(Activity context, String[] web,String path) {
23 | super(context, R.layout.list_single, web);
24 | this.context = context;
25 | this.web = web;
26 | ParentFolder = path;
27 | }
28 | @Override
29 | public View getView(int position, View view, ViewGroup parent) {
30 | LayoutInflater inflater = context.getLayoutInflater();
31 | View rowView= inflater.inflate(R.layout.list_single, null, true);
32 | TextView txtTitle = (TextView) rowView.findViewById(R.id.txt);
33 | ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
34 | txtTitle.setText(web[position]);
35 | Picasso.with(context).load(
36 | new File(
37 | ParentFolder+"/"+web[position]
38 | )).placeholder(R.drawable.document).resize(50, 50).into(imageView);
39 | return rowView;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/paul/arian/fileselector/CustomListSingleOnly.java:
--------------------------------------------------------------------------------
1 | package paul.arian.fileselector;
2 |
3 | /**
4 | * Created by Paul on 3/7/14.
5 | */
6 | import android.app.Activity;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.ViewGroup;
10 | import android.widget.ArrayAdapter;
11 | import android.widget.ImageView;
12 | import android.widget.TextView;
13 |
14 | import com.squareup.picasso.Picasso;
15 |
16 | import java.io.File;
17 |
18 | public class CustomListSingleOnly extends ArrayAdapter{
19 | private final Activity context;
20 | private final String[] web;
21 | String ParentFolder;
22 | public CustomListSingleOnly(Activity context, String[] web ,String path) {
23 | super(context, R.layout.list_single_only, web);
24 | this.context = context;
25 | this.web = web;
26 | ParentFolder = path;
27 | }
28 |
29 | @Override
30 | public View getView(int position, View view, ViewGroup parent) {
31 | LayoutInflater inflater = context.getLayoutInflater();
32 | View rowView= inflater.inflate(R.layout.list_single_only, null, true);
33 | TextView txtTitle = (TextView) rowView.findViewById(R.id.txt);
34 | ImageView imageView = (ImageView) rowView.findViewById(R.id.img);
35 | txtTitle.setText(web[position]);
36 | if((new File(ParentFolder+"/"+web[position])).isDirectory()){
37 | imageView.setImageResource(R.drawable.folder);//sets to folder
38 | }else if((new File(ParentFolder+"/"+web[position])).isFile()) {//sets to file
39 | Picasso.with(context).load(
40 | new File(
41 | ParentFolder + "/" + web[position]
42 | )).placeholder(R.drawable.document_gray).resize(50, 50).into(imageView);
43 | }
44 | return rowView;
45 | }
46 |
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/src/paul/arian/fileselector/FileSelectionActivity.java:
--------------------------------------------------------------------------------
1 | package paul.arian.fileselector;
2 |
3 | import java.io.File;
4 | import java.io.FileFilter;
5 | import java.util.ArrayList;
6 | import java.util.Arrays;
7 | import java.util.Collections;
8 | import java.util.Comparator;
9 | import java.util.HashSet;
10 | import java.util.Set;
11 | import java.util.regex.Pattern;
12 |
13 | import android.app.Activity;
14 | import android.content.Context;
15 | import android.content.Intent;
16 | import android.os.Build;
17 | import android.os.Bundle;
18 | import android.os.Environment;
19 | import android.text.TextUtils;
20 | import android.util.Log;
21 | import android.view.View;
22 | import android.widget.AdapterView;
23 | import android.widget.AdapterView.OnItemClickListener;
24 | import android.widget.ArrayAdapter;
25 | import android.widget.Button;
26 | import android.widget.ListView;
27 | import android.widget.TextView;
28 | import com.commonsware.cwac.merge.MergeAdapter;
29 |
30 | public class FileSelectionActivity extends Activity {
31 |
32 | private static final String TAG = "FileSelection";
33 | private static final String FILES_TO_UPLOAD = "upload";
34 | File mainPath = new File(Environment.getExternalStorageDirectory()+"");
35 | private ArrayList resultFileList;
36 |
37 | private ListView directoryView;
38 | private ArrayList directoryList = new ArrayList();
39 | private ArrayList directoryNames = new ArrayList();
40 | //private ListView fileView;
41 | private ArrayList fileList = new ArrayList();
42 | private ArrayList fileNames = new ArrayList();
43 | Button ok, all, cancel, storage , New;
44 | TextView path;
45 | Boolean Switch = false;
46 |
47 |
48 | Boolean switcher = false;
49 | String primary_sd;
50 | String secondary_sd;
51 |
52 | int index = 0;
53 | int top = 0;
54 |
55 | @Override
56 | public void onCreate(Bundle savedInstanceState) {
57 | super.onCreate(savedInstanceState);
58 | setContentView(R.layout.activity_file_selection);
59 | //getActionBar().setDisplayHomeAsUpEnabled(true);
60 |
61 |
62 |
63 |
64 | directoryView = (ListView)findViewById(R.id.directorySelectionList);
65 | ok = (Button)findViewById(R.id.ok);
66 | all = (Button)findViewById(R.id.all);
67 | cancel = (Button)findViewById(R.id.cancel);
68 | storage = (Button)findViewById(R.id.storage);
69 | New = (Button)findViewById(R.id.New);
70 | path = (TextView)findViewById(R.id.folderpath);
71 |
72 |
73 | loadLists();
74 | New.setEnabled(false);
75 |
76 |
77 | ExtStorageSearch();
78 | if(secondary_sd==null){
79 | storage.setEnabled(false);
80 | }
81 |
82 |
83 | directoryView.setOnItemClickListener(new OnItemClickListener() {
84 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
85 |
86 | index = directoryView.getFirstVisiblePosition();
87 | View v = directoryView.getChildAt(0);
88 | top = (v == null) ? 0 : v.getTop();
89 |
90 | File lastPath = mainPath;
91 | try {
92 | if (position < directoryList.size()) {
93 | mainPath = directoryList.get(position);
94 | loadLists();
95 | }
96 | }catch (Throwable e){
97 | mainPath = lastPath;
98 | loadLists();
99 | }
100 |
101 | }
102 | });
103 |
104 | ok.setOnClickListener(new View.OnClickListener(){
105 | public void onClick(View v){
106 | ok();
107 | }
108 | });
109 |
110 |
111 |
112 | cancel.setOnClickListener(new View.OnClickListener(){
113 | public void onClick(View v){
114 | finish();
115 | }
116 | });
117 |
118 | storage.setOnClickListener(new View.OnClickListener(){
119 | public void onClick(View v){
120 | try {
121 | if (!switcher) {
122 | mainPath = new File(secondary_sd);
123 | loadLists();
124 | switcher = true;
125 | storage.setText(getString(R.string.Int));
126 | } else {
127 | mainPath = new File(primary_sd);
128 | loadLists();
129 | switcher = false;
130 | storage.setText(getString(R.string.ext));
131 | }
132 | }catch (Throwable e){
133 |
134 | }
135 | }
136 | });
137 |
138 | all.setOnClickListener(new View.OnClickListener() {
139 | public void onClick(View v) {
140 | if(!Switch){
141 | for (int i = directoryList.size(); i < directoryView.getCount(); i++){
142 | directoryView.setItemChecked(i, true);
143 | }
144 | all.setText(getString(R.string.none));
145 | Switch = true;
146 | }else if(Switch){
147 | for (int i = directoryList.size(); i < directoryView.getCount(); i++) {
148 | directoryView.setItemChecked(i, false);
149 | }
150 | all.setText(getString(R.string.all));
151 | Switch = false;
152 | }
153 | }
154 |
155 | });
156 | }
157 |
158 | public void onBackPressed() {
159 | try {
160 | if(mainPath.equals(Environment.getExternalStorageDirectory().getParentFile().getParentFile())){
161 | finish();
162 | }else{
163 | File parent = mainPath.getParentFile();
164 | mainPath = parent;
165 | loadLists();
166 | directoryView.setSelectionFromTop(index, top);
167 | }
168 |
169 | }catch (Throwable e){
170 |
171 | }
172 | }
173 |
174 | public void ok(){
175 | Log.d(TAG, "Upload clicked, finishing activity");
176 |
177 |
178 | resultFileList = new ArrayList();
179 |
180 | for(int i = 0 ; i < directoryView.getCount(); i++){
181 | if(directoryView.isItemChecked(i)){
182 | resultFileList.add(fileList.get(i-directoryList.size()));
183 | }
184 | }
185 | if(resultFileList.isEmpty()){
186 | Log.d(TAG, "Nada seleccionado");
187 | finish();
188 | }
189 | Log.d(TAG, "Files: "+resultFileList.toString());
190 | Intent result = this.getIntent();
191 | result.putExtra(FILES_TO_UPLOAD, resultFileList);
192 | setResult(Activity.RESULT_OK, result);
193 | finish();
194 | }
195 |
196 | private void loadLists(){
197 | FileFilter fileFilter = new FileFilter() {
198 | public boolean accept(File file) {
199 | return file.isFile();
200 | }
201 | };
202 | FileFilter directoryFilter = new FileFilter(){
203 | public boolean accept(File file){
204 | return file.isDirectory();
205 | }
206 | };
207 |
208 | //if(mainPath.exists() && mainPath.length()>0){
209 | //Lista de directorios
210 | File[] tempDirectoryList = mainPath.listFiles(directoryFilter);
211 |
212 | if (tempDirectoryList != null && tempDirectoryList.length > 1) {
213 | Arrays.sort(tempDirectoryList, new Comparator() {
214 | @Override
215 | public int compare(File object1, File object2) {
216 | return object1.getName().compareTo(object2.getName());
217 | }
218 | });
219 | }
220 |
221 | directoryList = new ArrayList();
222 | directoryNames = new ArrayList();
223 | for(File file: tempDirectoryList){
224 | directoryList.add(file);
225 | directoryNames.add(file.getName());
226 | }
227 | ArrayAdapter directoryAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, directoryNames);
228 |
229 |
230 | //Lista de ficheros
231 | File[] tempFileList = mainPath.listFiles(fileFilter);
232 |
233 | if (tempFileList != null && tempFileList.length > 1) {
234 | Arrays.sort(tempFileList, new Comparator() {
235 | @Override
236 | public int compare(File object1, File object2) {
237 | return object1.getName().compareTo(object2.getName());
238 | }
239 | });
240 | }
241 |
242 | fileList = new ArrayList();
243 | fileNames = new ArrayList();
244 | for(File file : tempFileList){
245 | fileList.add(file);
246 | fileNames.add(file.getName());
247 | }
248 |
249 |
250 |
251 | path.setText(mainPath.toString());
252 | iconload();
253 | setTitle(mainPath.getName());
254 | //}
255 | }
256 |
257 | /**@Override
258 | public boolean onCreateOptionsMenu(Menu menu) {
259 | getMenuInflater().inflate(R.menu.activity_file_selection, menu);
260 | return true;
261 | }
262 |
263 | @Override
264 | public boolean onOptionsItemSelected(MenuItem item) {
265 | switch (item.getItemId()) {
266 | case android.R.id.home:
267 | NavUtils.navigateUpFromSameTask(this);
268 | return true;
269 | }
270 | return super.onOptionsItemSelected(item);
271 | }**/
272 |
273 | public void iconload(){
274 | String[] foldernames = new String[directoryNames.size()];
275 | foldernames = directoryNames.toArray(foldernames);
276 |
277 | String[] filenames = new String[fileNames.size()];
278 | filenames = fileNames.toArray(filenames);
279 |
280 | CustomListSingleOnly adapter1 = new CustomListSingleOnly(FileSelectionActivity.this, directoryNames.toArray(foldernames), mainPath.getPath());
281 | CustomList adapter2 = new CustomList(FileSelectionActivity.this, fileNames.toArray(filenames), mainPath.getPath());
282 |
283 |
284 | MergeAdapter adap = new MergeAdapter();
285 |
286 | adap.addAdapter(adapter1);
287 | adap.addAdapter(adapter2);
288 |
289 |
290 | directoryView.setAdapter(adap);
291 | }
292 |
293 | public void ExtStorageSearch() {
294 |
295 |
296 | //First Attempt
297 | primary_sd = System.getenv("EXTERNAL_STORAGE");
298 | secondary_sd = System.getenv("SECONDARY_STORAGE");
299 |
300 |
301 | if (primary_sd == null) {
302 | primary_sd = Environment.getExternalStorageDirectory() + "";
303 | }
304 | if (secondary_sd == null) {//if fail, search among known list of extStorage Locations
305 | for (String string : getStorageDirectories(this)) {
306 | if ((new File(string)).exists() && (new File(string)).isDirectory() && !(string.equals(primary_sd))) {
307 | secondary_sd = string;
308 | break;
309 | }
310 | }
311 | }
312 |
313 | }
314 |
315 | private static final Pattern DIR_SEPORATOR = Pattern.compile("/");
316 |
317 | /**
318 | * Returns all available SD-Cards in the system (include emulated)
319 | *
320 | * Warning: Hack! Based on Android source code of version 4.3 (API 18)
321 | * Because there is no standard way to get it.
322 | * Edited by hendrawd
323 | *
324 | * @return paths to all available SD-Cards in the system (include emulated)
325 | */
326 | public static String[] getStorageDirectories(Context context) {
327 | // Final set of paths
328 | final Set rv = new HashSet<>();
329 | // Primary physical SD-CARD (not emulated)
330 | final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
331 | // All Secondary SD-CARDs (all exclude primary) separated by ":"
332 | final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
333 | // Primary emulated SD-CARD
334 | final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
335 | if (TextUtils.isEmpty(rawEmulatedStorageTarget)) {
336 | //fix of empty raw emulated storage on marshmallow
337 | if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
338 | File[] files = context.getExternalFilesDirs(null);
339 | for (File file : files) {
340 | String applicationSpecificAbsolutePath = file.getAbsolutePath();
341 | String emulatedRootPath = applicationSpecificAbsolutePath.substring(0, applicationSpecificAbsolutePath.indexOf("Android/data"));
342 | rv.add(emulatedRootPath);
343 | }
344 | } else {
345 | // Device has physical external storage; use plain paths.
346 | if (TextUtils.isEmpty(rawExternalStorage)) {
347 | // EXTERNAL_STORAGE undefined; falling back to default.
348 | rv.addAll(Arrays.asList(getPhysicalPaths()));
349 | } else {
350 | rv.add(rawExternalStorage);
351 | }
352 | }
353 | } else {
354 | // Device has emulated storage; external storage paths should have
355 | // userId burned into them.
356 | final String rawUserId;
357 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
358 | rawUserId = "";
359 | } else {
360 | final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
361 | final String[] folders = DIR_SEPORATOR.split(path);
362 | final String lastFolder = folders[folders.length - 1];
363 | boolean isDigit = false;
364 | try {
365 | Integer.valueOf(lastFolder);
366 | isDigit = true;
367 | } catch (NumberFormatException ignored) {
368 | }
369 | rawUserId = isDigit ? lastFolder : "";
370 | }
371 | // /storage/emulated/0[1,2,...]
372 | if (TextUtils.isEmpty(rawUserId)) {
373 | rv.add(rawEmulatedStorageTarget);
374 | } else {
375 | rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
376 | }
377 | }
378 | // Add all secondary storages
379 | if (!TextUtils.isEmpty(rawSecondaryStoragesStr)) {
380 | // All Secondary SD-CARDs splited into array
381 | final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
382 | Collections.addAll(rv, rawSecondaryStorages);
383 | }
384 | return rv.toArray(new String[rv.size()]);
385 | }
386 |
387 | /**
388 | * @return physicalPaths based on phone model
389 | */
390 | private static String[] getPhysicalPaths() {
391 | return new String[]{
392 | "/storage/sdcard0",
393 | "/storage/sdcard1", //Motorola Xoom
394 | "/storage/extsdcard", //Samsung SGS3
395 | "/storage/sdcard0/external_sdcard", //User request
396 | "/mnt/extsdcard",
397 | "/mnt/sdcard/external_sd", //Samsung galaxy family
398 | "/mnt/external_sd",
399 | "/mnt/media_rw/sdcard1", //4.4.2 on CyanogenMod S3
400 | "/removable/microsd", //Asus transformer prime
401 | "/mnt/emmc",
402 | "/storage/external_SD", //LG
403 | "/storage/ext_sd", //HTC One Max
404 | "/storage/removable/sdcard1", //Sony Xperia Z1
405 | "/data/sdext",
406 | "/data/sdext2",
407 | "/data/sdext3",
408 | "/data/sdext4",
409 | "/sdcard1", //Sony Xperia Z
410 | "/sdcard2", //HTC One M8s
411 | "/storage/microsd" //ASUS ZenFone 2
412 | };
413 | }
414 |
415 |
416 |
417 |
418 | }
419 |
--------------------------------------------------------------------------------
/src/paul/arian/fileselector/FolderSelectionActivity.java:
--------------------------------------------------------------------------------
1 | package paul.arian.fileselector;
2 |
3 | import java.io.File;
4 | import java.io.FileFilter;
5 | import java.util.ArrayList;
6 | import java.util.Arrays;
7 | import java.util.Collections;
8 | import java.util.Comparator;
9 | import java.util.HashSet;
10 | import java.util.Set;
11 | import java.util.regex.Pattern;
12 |
13 | import android.app.Activity;
14 | import android.app.AlertDialog;
15 | import android.content.Context;
16 | import android.content.DialogInterface;
17 | import android.content.Intent;
18 | import android.os.Build;
19 | import android.os.Bundle;
20 | import android.os.Environment;
21 | import android.text.TextUtils;
22 | import android.view.View;
23 | import android.widget.AdapterView;
24 | import android.widget.AdapterView.OnItemClickListener;
25 | import android.widget.ArrayAdapter;
26 | import android.widget.Button;
27 | import android.widget.EditText;
28 | import android.widget.ListView;
29 | import android.widget.TextView;
30 |
31 | import com.commonsware.cwac.merge.MergeAdapter;
32 |
33 | public class FolderSelectionActivity extends Activity {
34 |
35 | private static final String TAG = "FileSelection";
36 | private static final String FILES_TO_UPLOAD = "upload";
37 | File mainPath = new File(Environment.getExternalStorageDirectory()+"");
38 | private ArrayList resultFileList;
39 |
40 | private ListView directoryView;
41 | private ArrayList directoryList = new ArrayList();
42 | private ArrayList directoryNames = new ArrayList();
43 | private ArrayList fileList = new ArrayList();
44 | private ArrayList fileNames = new ArrayList();
45 | Button ok, all,cancel,storage,New;
46 | TextView path;
47 |
48 |
49 |
50 |
51 | Boolean switcher = false;
52 | String primary_sd;
53 | String secondary_sd;
54 |
55 | int index = 0;
56 | int top = 0;
57 |
58 | @Override
59 | public void onCreate(Bundle savedInstanceState) {
60 | super.onCreate(savedInstanceState);
61 | setContentView(R.layout.activity_file_selection);
62 | //getActionBar().setDisplayHomeAsUpEnabled(true);
63 |
64 | directoryView = (ListView)findViewById(R.id.directorySelectionList);
65 | ok = (Button)findViewById(R.id.ok);
66 | all = (Button)findViewById(R.id.all);
67 | cancel = (Button)findViewById(R.id.cancel);
68 | storage = (Button)findViewById(R.id.storage);
69 | New = (Button)findViewById(R.id.New);
70 | path = (TextView)findViewById(R.id.folderpath);
71 |
72 | all.setEnabled(false);
73 |
74 |
75 | loadLists();
76 |
77 | ExtStorageSearch();
78 | if(secondary_sd==null){
79 | storage.setEnabled(false);
80 | }
81 |
82 | directoryView.setOnItemClickListener(new OnItemClickListener() {
83 | public void onItemClick(AdapterView> parent, View view, int position, long id) {
84 |
85 | index = directoryView.getFirstVisiblePosition();
86 | View v = directoryView.getChildAt(0);
87 | top = (v == null) ? 0 : v.getTop();
88 |
89 | File lastPath = mainPath;
90 | try {
91 | if (position < directoryList.size()) {
92 | mainPath = directoryList.get(position);
93 | loadLists();
94 | }
95 | }catch(Throwable e){
96 | mainPath = lastPath;
97 | loadLists();
98 | }
99 | }
100 | });
101 |
102 | ok.setOnClickListener(new View.OnClickListener(){
103 | public void onClick(View v){
104 | ok();
105 | }
106 | });
107 |
108 | cancel.setOnClickListener(new View.OnClickListener(){
109 | public void onClick(View v){
110 | finish();
111 | }
112 | });
113 |
114 | storage.setOnClickListener(new View.OnClickListener(){
115 | public void onClick(View v){
116 | try {
117 | if (!switcher) {
118 | mainPath = new File(secondary_sd);
119 | loadLists();
120 | switcher = true;
121 | storage.setText(getString(R.string.Int));
122 | } else {
123 | mainPath = new File(primary_sd);
124 | loadLists();
125 | switcher = false;
126 | storage.setText(getString(R.string.ext));
127 | }
128 | }catch (Throwable e){
129 |
130 | }
131 | }
132 | });
133 |
134 | New.setOnClickListener(new View.OnClickListener(){
135 | public void onClick(View v){
136 | AlertDialog.Builder alert = new AlertDialog.Builder(v.getContext());
137 | alert.setTitle( getString(R.string.New) );
138 | alert.setMessage( getString(R.string.CNew) );
139 |
140 | final EditText input = new EditText(v.getContext());
141 | alert.setView(input);
142 |
143 | alert.setPositiveButton(getString(R.string.create), new DialogInterface.OnClickListener() {
144 | public void onClick(DialogInterface dialog, int whichButton) {
145 | String fileName = input.getText().toString();
146 | // Verify if a value has been entered.
147 | if(fileName != null && fileName.length() > 0) {
148 | // Notify the listeners.
149 | File newFolder = new File(mainPath.getPath()+"/"+fileName+"/");
150 | newFolder.mkdirs();
151 | loadLists();
152 | }
153 | }
154 | });
155 | alert.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() {
156 | public void onClick(DialogInterface dialog, int whichButton) {
157 | // Do nothing, automatically the dialog is going to be closed.
158 | }
159 | });
160 |
161 | // Show the dialog.
162 | alert.show();
163 |
164 | }
165 | });
166 | }
167 |
168 | @Override
169 | public void onBackPressed() {
170 | try {
171 | if(mainPath.equals(Environment.getExternalStorageDirectory().getParentFile().getParentFile())){
172 | finish();
173 | }else{
174 | File parent = mainPath.getParentFile();
175 | mainPath = parent;
176 | loadLists();
177 | directoryView.setSelectionFromTop(index, top);
178 | }
179 |
180 | }catch (Throwable e){
181 |
182 | }
183 | }
184 |
185 | public void ok(){
186 | Intent result = this.getIntent();
187 | result.putExtra(FILES_TO_UPLOAD, mainPath);
188 | setResult(Activity.RESULT_OK, result);
189 | finish();
190 | }
191 |
192 | private void loadLists(){
193 | FileFilter fileFilter = new FileFilter() {
194 | public boolean accept(File file) {
195 | return file.isFile();
196 | }
197 | };
198 | FileFilter directoryFilter = new FileFilter(){
199 | public boolean accept(File file){
200 | return file.isDirectory();
201 | }
202 | };
203 |
204 | //if(mainPath.exists() && mainPath.length()>0){
205 | //Lista de directorios
206 | File[] tempDirectoryList = mainPath.listFiles(directoryFilter);
207 |
208 | if (tempDirectoryList != null && tempDirectoryList.length > 1) {
209 | Arrays.sort(tempDirectoryList, new Comparator() {
210 | @Override
211 | public int compare(File object1, File object2) {
212 | return object1.getName().compareTo(object2.getName());
213 | }
214 | });
215 | }
216 |
217 |
218 | directoryList = new ArrayList();
219 | directoryNames = new ArrayList();
220 | for(File file: tempDirectoryList){
221 | directoryList.add(file);
222 | directoryNames.add(file.getName());
223 | }
224 | ArrayAdapter directoryAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, directoryNames);
225 | directoryView.setAdapter(directoryAdapter);
226 |
227 | //Lista de ficheros
228 | File[] tempFileList = mainPath.listFiles(fileFilter);
229 |
230 | if (tempFileList != null && tempFileList.length > 1) {
231 | Arrays.sort(tempFileList, new Comparator() {
232 | @Override
233 | public int compare(File object1, File object2) {
234 | return object1.getName().compareTo(object2.getName());
235 | }
236 | });
237 | }
238 |
239 | fileList = new ArrayList();
240 | fileNames = new ArrayList();
241 | for(File file : tempFileList){
242 | fileList.add(file);
243 | fileNames.add(file.getName());
244 | }
245 |
246 |
247 |
248 | path.setText(mainPath.toString());
249 | iconload();
250 | // }
251 | }
252 |
253 | public void iconload(){
254 | String[] foldernames = new String[directoryNames.size()];
255 | foldernames = directoryNames.toArray(foldernames);
256 |
257 | String[] filenames = new String[fileNames.size()];
258 | filenames = fileNames.toArray(filenames);
259 |
260 | CustomListSingleOnly adapter1 = new CustomListSingleOnly(FolderSelectionActivity.this, directoryNames.toArray(foldernames), mainPath.getPath());
261 | CustomListSingleOnly adapter2 = new CustomListSingleOnly(FolderSelectionActivity.this, fileNames.toArray(filenames), mainPath.getPath());
262 |
263 |
264 | MergeAdapter adap = new MergeAdapter();
265 |
266 | adap.addAdapter(adapter1);
267 | adap.addAdapter(adapter2);
268 |
269 |
270 | directoryView.setAdapter(adap);
271 | }
272 |
273 | public void ExtStorageSearch() {
274 |
275 |
276 | //First Attempt
277 | primary_sd = System.getenv("EXTERNAL_STORAGE");
278 | secondary_sd = System.getenv("SECONDARY_STORAGE");
279 |
280 |
281 | if (primary_sd == null) {
282 | primary_sd = Environment.getExternalStorageDirectory() + "";
283 | }
284 | if (secondary_sd == null) {//if fail, search among known list of extStorage Locations
285 | for (String string : getStorageDirectories(this)) {
286 | if ((new File(string)).exists() && (new File(string)).isDirectory() && !(string.equals(primary_sd))) {
287 | secondary_sd = string;
288 | break;
289 | }
290 | }
291 | }
292 |
293 | }
294 |
295 | private static final Pattern DIR_SEPORATOR = Pattern.compile("/");
296 |
297 | /**
298 | * Returns all available SD-Cards in the system (include emulated)
299 | *
300 | * Warning: Hack! Based on Android source code of version 4.3 (API 18)
301 | * Because there is no standard way to get it.
302 | * Edited by hendrawd
303 | *
304 | * @return paths to all available SD-Cards in the system (include emulated)
305 | */
306 | public static String[] getStorageDirectories(Context context) {
307 | // Final set of paths
308 | final Set rv = new HashSet<>();
309 | // Primary physical SD-CARD (not emulated)
310 | final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
311 | // All Secondary SD-CARDs (all exclude primary) separated by ":"
312 | final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
313 | // Primary emulated SD-CARD
314 | final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
315 | if (TextUtils.isEmpty(rawEmulatedStorageTarget)) {
316 | //fix of empty raw emulated storage on marshmallow
317 | if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
318 | File[] files = context.getExternalFilesDirs(null);
319 | for (File file : files) {
320 | String applicationSpecificAbsolutePath = file.getAbsolutePath();
321 | String emulatedRootPath = applicationSpecificAbsolutePath.substring(0, applicationSpecificAbsolutePath.indexOf("Android/data"));
322 | rv.add(emulatedRootPath);
323 | }
324 | } else {
325 | // Device has physical external storage; use plain paths.
326 | if (TextUtils.isEmpty(rawExternalStorage)) {
327 | // EXTERNAL_STORAGE undefined; falling back to default.
328 | rv.addAll(Arrays.asList(getPhysicalPaths()));
329 | } else {
330 | rv.add(rawExternalStorage);
331 | }
332 | }
333 | } else {
334 | // Device has emulated storage; external storage paths should have
335 | // userId burned into them.
336 | final String rawUserId;
337 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
338 | rawUserId = "";
339 | } else {
340 | final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
341 | final String[] folders = DIR_SEPORATOR.split(path);
342 | final String lastFolder = folders[folders.length - 1];
343 | boolean isDigit = false;
344 | try {
345 | Integer.valueOf(lastFolder);
346 | isDigit = true;
347 | } catch (NumberFormatException ignored) {
348 | }
349 | rawUserId = isDigit ? lastFolder : "";
350 | }
351 | // /storage/emulated/0[1,2,...]
352 | if (TextUtils.isEmpty(rawUserId)) {
353 | rv.add(rawEmulatedStorageTarget);
354 | } else {
355 | rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
356 | }
357 | }
358 | // Add all secondary storages
359 | if (!TextUtils.isEmpty(rawSecondaryStoragesStr)) {
360 | // All Secondary SD-CARDs splited into array
361 | final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
362 | Collections.addAll(rv, rawSecondaryStorages);
363 | }
364 | return rv.toArray(new String[rv.size()]);
365 | }
366 |
367 | /**
368 | * @return physicalPaths based on phone model
369 | */
370 | private static String[] getPhysicalPaths() {
371 | return new String[]{
372 | "/storage/sdcard0",
373 | "/storage/sdcard1", //Motorola Xoom
374 | "/storage/extsdcard", //Samsung SGS3
375 | "/storage/sdcard0/external_sdcard", //User request
376 | "/mnt/extsdcard",
377 | "/mnt/sdcard/external_sd", //Samsung galaxy family
378 | "/mnt/external_sd",
379 | "/mnt/media_rw/sdcard1", //4.4.2 on CyanogenMod S3
380 | "/removable/microsd", //Asus transformer prime
381 | "/mnt/emmc",
382 | "/storage/external_SD", //LG
383 | "/storage/ext_sd", //HTC One Max
384 | "/storage/removable/sdcard1", //Sony Xperia Z1
385 | "/data/sdext",
386 | "/data/sdext2",
387 | "/data/sdext3",
388 | "/data/sdext4",
389 | "/sdcard1", //Sony Xperia Z
390 | "/sdcard2", //HTC One M8s
391 | "/storage/microsd" //ASUS ZenFone 2
392 | };
393 | }
394 |
395 |
396 |
397 |
398 | }
399 |
--------------------------------------------------------------------------------