├── app
├── .gitignore
├── src
│ ├── main
│ │ ├── res
│ │ │ ├── drawable-xhdpi
│ │ │ │ ├── tab_up.9.png
│ │ │ │ ├── title_bg.png
│ │ │ │ ├── back_normal.png
│ │ │ │ ├── back_pressed.png
│ │ │ │ ├── ic_launcher.png
│ │ │ │ ├── next_normal.png
│ │ │ │ ├── next_pressed.png
│ │ │ │ ├── tab_down.9.png
│ │ │ │ ├── tab_middle.9.png
│ │ │ │ ├── tab_normal.png
│ │ │ │ ├── common_input.9.png
│ │ │ │ ├── iboxiao_normal.png
│ │ │ │ ├── setting_normal.png
│ │ │ │ ├── bxfile_file_apk.png
│ │ │ │ ├── bxfile_file_dir.png
│ │ │ │ ├── bxfile_file_doc.png
│ │ │ │ ├── bxfile_file_html.png
│ │ │ │ ├── bxfile_file_jpg.png
│ │ │ │ ├── bxfile_file_mp3.png
│ │ │ │ ├── bxfile_file_pdf.png
│ │ │ │ ├── bxfile_file_ppt.png
│ │ │ │ ├── bxfile_file_txt.png
│ │ │ │ ├── bxfile_file_video.png
│ │ │ │ ├── bxfile_file_xls.png
│ │ │ │ ├── bxfile_file_zip.png
│ │ │ │ ├── iboxiao_choosed.png
│ │ │ │ ├── myschool_choosed.png
│ │ │ │ ├── myschool_normal.png
│ │ │ │ ├── privatemsg_normal.png
│ │ │ │ ├── setting_choosed.png
│ │ │ │ ├── tab_up_pressed.9.png
│ │ │ │ ├── url_image_failed.png
│ │ │ │ ├── bx_bottom_msg_bg.9.png
│ │ │ │ ├── bxfile_file_unknow.png
│ │ │ │ ├── ic_launcher_offline.png
│ │ │ │ ├── privatemsg_choosed.png
│ │ │ │ ├── tab_down_pressed.9.png
│ │ │ │ ├── bxfile_file_icon_music.png
│ │ │ │ ├── bxfile_file_icon_ram.png
│ │ │ │ ├── bxfile_file_icon_video.png
│ │ │ │ ├── bxfile_list_checkbox.png
│ │ │ │ ├── tab_middle_pressed.9.png
│ │ │ │ ├── bxfile_file_default_pic.jpg
│ │ │ │ ├── bxfile_file_icon_picture.png
│ │ │ │ ├── bxfile_file_icon_sdcard.png
│ │ │ │ ├── bxfile_arrow_right_normal.png
│ │ │ │ ├── bxfile_arrow_right_pressed.png
│ │ │ │ ├── bxfile_file_icon_download.png
│ │ │ │ ├── bxfile_file_no_file_record.png
│ │ │ │ └── bxfile_list_checkbox_selected.png
│ │ │ ├── drawable-hdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── drawable-mdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── drawable-xxhdpi
│ │ │ │ └── ic_launcher.png
│ │ │ ├── drawable
│ │ │ │ ├── corner_purple_bg.xml
│ │ │ │ ├── corner_yellow_bg.xml
│ │ │ │ ├── corner_solidblue_only.xml
│ │ │ │ ├── corner_gray_only.xml
│ │ │ │ ├── next_btn.xml
│ │ │ │ ├── selector_back.xml
│ │ │ │ ├── corner_btn_bg.xml
│ │ │ │ ├── fileexplorer_item_bg.xml
│ │ │ │ ├── localefile_send_bg.xml
│ │ │ │ ├── localefile_cb_bg.xml
│ │ │ │ ├── selector_tab_up.xml
│ │ │ │ ├── selector_tab_down.xml
│ │ │ │ └── selector_tab_middle.xml
│ │ │ ├── color
│ │ │ │ └── localefile_send_color.xml
│ │ │ ├── menu
│ │ │ │ └── menu_main.xml
│ │ │ ├── values-w820dp
│ │ │ │ └── dimens.xml
│ │ │ ├── values
│ │ │ │ ├── dimens.xml
│ │ │ │ ├── strings.xml
│ │ │ │ ├── color.xml
│ │ │ │ └── styles.xml
│ │ │ ├── layout
│ │ │ │ ├── gallery_item.xml
│ │ │ │ ├── localfile_bottom.xml
│ │ │ │ ├── localefile_gallery.xml
│ │ │ │ ├── localefile_browser.xml
│ │ │ │ ├── bxfile_viewer.xml
│ │ │ │ ├── locale_file_item.xml
│ │ │ │ └── localefile_main.xml
│ │ │ └── values-en
│ │ │ │ └── strings.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── tracy
│ │ │ │ └── fileexplorer
│ │ │ │ ├── util
│ │ │ │ ├── Utils.java
│ │ │ │ ├── Constants.java
│ │ │ │ ├── TimeUtils.java
│ │ │ │ ├── MIMEUtils.java
│ │ │ │ └── FileUtils.java
│ │ │ │ ├── FEApplication.java
│ │ │ │ ├── BaseActivity.java
│ │ │ │ ├── LocaleFileAdapter.java
│ │ │ │ ├── TFileViewer.java
│ │ │ │ ├── TFile.java
│ │ │ │ ├── LocaleMediaFileBrowser.java
│ │ │ │ ├── FileManager.java
│ │ │ │ ├── LocaleFileMain.java
│ │ │ │ ├── SyncImageLoader.java
│ │ │ │ ├── LocaleFileBrowser.java
│ │ │ │ └── LocaleFileGallery.java
│ │ └── AndroidManifest.xml
│ └── androidTest
│ │ └── java
│ │ └── com
│ │ └── tracy
│ │ └── fileexplorer
│ │ └── ApplicationTest.java
├── build.gradle
├── proguard-rules.pro
└── app.iml
├── settings.gradle
├── .gradle
└── 2.3
│ └── taskArtifacts
│ ├── cache.properties
│ ├── fileHashes.bin
│ ├── fileSnapshots.bin
│ ├── taskArtifacts.bin
│ ├── cache.properties.lock
│ └── outputFileStates.bin
├── screenshot.png
├── .idea
├── copyright
│ └── profiles_settings.xml
├── scopes
│ └── scope_settings.xml
├── encodings.xml
├── vcs.xml
├── misc.xml
├── libraries
│ ├── support_annotations_21_0_3.xml
│ ├── appcompat_v7_21_0_3.xml
│ └── support_v4_21_0_3.xml
├── modules.xml
├── gradle.xml
└── compiler.xml
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── local.properties
├── README.md
├── gradle.properties
├── FileExplorer.iml
├── gradlew.bat
└── gradlew
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/.gradle/2.3/taskArtifacts/cache.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 08 15:58:39 CST 2015
2 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/screenshot.png
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/.gradle/2.3/taskArtifacts/fileHashes.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/.gradle/2.3/taskArtifacts/fileHashes.bin
--------------------------------------------------------------------------------
/.gradle/2.3/taskArtifacts/fileSnapshots.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/.gradle/2.3/taskArtifacts/fileSnapshots.bin
--------------------------------------------------------------------------------
/.gradle/2.3/taskArtifacts/taskArtifacts.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/.gradle/2.3/taskArtifacts/taskArtifacts.bin
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/tab_up.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/tab_up.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/title_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/title_bg.png
--------------------------------------------------------------------------------
/.gradle/2.3/taskArtifacts/cache.properties.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/.gradle/2.3/taskArtifacts/cache.properties.lock
--------------------------------------------------------------------------------
/.gradle/2.3/taskArtifacts/outputFileStates.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/.gradle/2.3/taskArtifacts/outputFileStates.bin
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/back_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/back_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/back_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/back_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/next_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/next_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/next_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/next_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/tab_down.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/tab_down.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/tab_middle.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/tab_middle.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/tab_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/tab_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/common_input.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/common_input.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/iboxiao_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/iboxiao_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/setting_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/setting_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_apk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_apk.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_dir.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_dir.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_doc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_doc.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_html.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_html.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_jpg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_jpg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_mp3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_mp3.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_pdf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_pdf.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_ppt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_ppt.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_txt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_txt.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_video.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_xls.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_xls.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_zip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_zip.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/iboxiao_choosed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/iboxiao_choosed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/myschool_choosed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/myschool_choosed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/myschool_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/myschool_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/privatemsg_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/privatemsg_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/setting_choosed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/setting_choosed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/tab_up_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/tab_up_pressed.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/url_image_failed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/url_image_failed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bx_bottom_msg_bg.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bx_bottom_msg_bg.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_unknow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_unknow.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher_offline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/ic_launcher_offline.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/privatemsg_choosed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/privatemsg_choosed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/tab_down_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/tab_down_pressed.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_icon_music.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_icon_music.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_icon_ram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_icon_ram.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_icon_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_icon_video.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_list_checkbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_list_checkbox.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/tab_middle_pressed.9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/tab_middle_pressed.9.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_default_pic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_default_pic.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_icon_picture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_icon_picture.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_icon_sdcard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_icon_sdcard.png
--------------------------------------------------------------------------------
/.idea/scopes/scope_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_arrow_right_normal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_arrow_right_normal.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_arrow_right_pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_arrow_right_pressed.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_icon_download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_icon_download.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_file_no_file_record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_file_no_file_record.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/bxfile_list_checkbox_selected.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TracyZhangLei/FileExplorer/HEAD/app/src/main/res/drawable-xhdpi/bxfile_list_checkbox_selected.png
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/corner_purple_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/corner_yellow_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/corner_solidblue_only.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 10 15:27:10 PDT 2013
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/corner_gray_only.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/color/localefile_send_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/next_btn.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_back.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/corner_btn_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/fileexplorer_item_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/localefile_send_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/localefile_cb_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/libraries/support_annotations_21_0_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_tab_up.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_tab_down.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_tab_middle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/tracy/fileexplorer/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/.idea/libraries/appcompat_v7_21_0_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file should *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | sdk.dir=/Users/tracy/tools/adt-bundle-mac/sdk
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/util/Utils.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer.util;
2 |
3 | import android.app.Activity;
4 | import android.view.Display;
5 | import android.view.WindowManager;
6 |
7 | public class Utils {
8 |
9 | /**
10 | * @param cxt
11 | * @return 屏幕宽
12 | */
13 | public static int getScreenWidth(Activity cxt) {
14 | WindowManager m = cxt.getWindowManager();
15 | Display d = m.getDefaultDisplay();
16 | return d.getWidth();
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/FEApplication.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import java.util.concurrent.ExecutorService;
4 | import java.util.concurrent.Executors;
5 |
6 | import android.app.Application;
7 |
8 | public class FEApplication extends Application {
9 |
10 | private ExecutorService es = Executors.newFixedThreadPool(3);
11 |
12 | // app对外 执行任务入口
13 | public void execRunnable(Runnable r) {
14 | if (!es.isShutdown()) {
15 | es.execute(r);
16 | }
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/util/Constants.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer.util;
2 |
3 | import android.os.Environment;
4 |
5 | public class Constants {
6 |
7 | // 文件下载目录
8 | public static final String FILE_BASEPATH = Environment.getExternalStorageDirectory() + "/tracyZhang/";// 基本目录
9 | public static final String AVATAR_SAVEPATH = FILE_BASEPATH + "avatar/"; // 头像目录
10 | public static final String DOWNLOAD_PATH = FILE_BASEPATH + "download/"; // 下载目录
11 | public static final String FILERECV_PATH = FILE_BASEPATH + "fileRecv/"; // 接收文件目录
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/.idea/libraries/support_v4_21_0_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import android.support.v7.app.ActionBarActivity;
4 | import android.widget.Toast;
5 |
6 | /**
7 | * Created by tracy on 15/3/30.
8 | */
9 | public class BaseActivity extends ActionBarActivity {
10 |
11 | //show toast
12 | protected void showToast(final int strId) {
13 | runOnUiThread(new Runnable() {
14 | @Override
15 | public void run() {
16 | Toast.makeText(BaseActivity.this, getString(strId), Toast.LENGTH_SHORT).show();
17 | }
18 | });
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 21
5 | buildToolsVersion "21.1.2"
6 |
7 | defaultConfig {
8 | applicationId "com.tracy.fileexplorer"
9 | minSdkVersion 14
10 | targetSdkVersion 21
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile 'com.android.support:appcompat-v7:21.0.3'
25 | }
26 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /Users/tracy/tools/adt-bundle-mac/sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FileExplorer
2 | * android file explorer,we can choose files by mime type such as photos,audios,videos,by sdcard path and extsdcard. it's easy to use and configure chosen file limit and file size.
3 |
4 | * android 本地文件浏览选择器,可配置选择文件数量、大小限制,并根据不同类型进行展示
5 |
6 |
7 | ## Usage
8 |
9 | ```
10 | startActivity(cxt , LocaleFileMain.class),get chosen files list by FileManager.getInstance().getChoosedFiles()
11 | ```
12 |
13 | ## Configuration
14 |
15 | ```
16 | set chosen limits by FileManager.getInstance().initConfiguration(int maxChoosedCnt , long maxFileSize), default is DEFAULT_MAX_CHOOSED_CNT, DEFAULT_MAX_FILESIZE, reset to default by FileManager.getInstance().reSetDefaultConfiguration()
17 | ```
18 |
19 |
20 | 
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/FileExplorer.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
7 | 10sp
8 | 12sp
9 | 14sp
10 | 16sp
11 | 18sp
12 | 20sp
13 | 22sp
14 |
15 | 4dp
16 | 6dp
17 | 8dp
18 | 10dp
19 | 20dp
20 | 26dp
21 | 36dp
22 | 40dp
23 | 50dp
24 | 60dp
25 |
26 | 55dp
27 | 36dp
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/gallery_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
15 |
16 |
24 |
25 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | TracyFileExplorer
5 | Settings
6 |
7 | 取消
8 |
9 | 本地文件
10 | 该分类没有文件
11 | 当前文件夹没有文件
12 | 已下载文件
13 | 手机内存
14 | SD卡内存
15 | 扩展卡内存
16 | 图片
17 | 音乐
18 | 视频
19 | (%1$s)
20 | 已选
21 | 发送(%1$s)
22 | 文件查看
23 | 重新发送
24 | 用其他应用打开
25 | 发送
26 | 下载
27 | 文件打开失败
28 | SDCard未加载
29 | 文件大小超出了限制,请重选
30 | 文件个数超出了限制,请重选
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
30 |
33 |
36 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/values-en/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | TracyFileExplorer
5 | Settings
6 |
7 | Cancel
8 | TracyFileExplorer
9 | No files
10 | No Files
11 | Downloaded
12 | Root
13 | Sdcard
14 | ExtSdcard
15 | Photo
16 | Music
17 | Video
18 | (%1$s)
19 | Choosed
20 | Send(%1$s)
21 | File Viewer
22 | Resend
23 | Open by other app
24 | Send
25 | Download
26 | File open failed
27 | SDCard not mounted
28 | File size is too large
29 | Chosen count is over limit
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/localfile_bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
24 |
25 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/localefile_gallery.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
22 |
23 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/localefile_browser.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
24 |
25 |
34 |
35 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/values/color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #33000000
4 | #00000000
5 | #4db0ec
6 |
7 |
8 | #FFFFFF
9 | #000000
10 | #f0f0f0
11 | #bebebe
12 | #009CFF
13 | #009CFF
14 |
15 |
16 | #55bebebe
17 | #00bfff
18 | #9acd32
19 |
20 | #ffadba88
21 |
22 |
23 | #2c7ca0
24 |
25 | #990000
26 | #999999
27 |
28 | #88cfcfcf
29 |
30 |
31 | #f1f1f1
32 |
33 | #c19151
34 |
35 |
36 | #FFFFFF
37 | #38657C
38 | #F39035
39 | #00000000
40 |
41 | #a7a7a7
42 | #e9e9e9
43 | #2ebfec
44 | #2c7ca0
45 | #FF7A00
46 | #8f8f8f
47 | #878787
48 |
49 | #e6e6e6
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/util/TimeUtils.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer.util;
2 |
3 | import java.text.SimpleDateFormat;
4 | import java.util.Date;
5 |
6 | import android.util.Log;
7 |
8 |
9 | /**
10 | * 时间工具类
11 | * @author tracyZhang
12 | *
13 | */
14 | public class TimeUtils {
15 |
16 | public static SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm");
17 | public static SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
18 | public static SimpleDateFormat format2 = new SimpleDateFormat("HH:mm");
19 |
20 | public static String getTimeDiffStr(long time) {
21 | StringBuilder result = new StringBuilder();
22 | long diff = System.currentTimeMillis() - time;
23 | long MIN = 60*1000;
24 | long HOUR = 60*MIN;
25 | long DAY = 24*HOUR;
26 | long MONTH = 30*DAY;
27 | try{
28 | if(diff<0) {
29 | result.append(format.format(new Date(time)));
30 | }else if(diff
2 |
3 |
4 |
7 |
8 |
9 |
15 |
16 |
17 |
27 |
32 |
33 |
34 |
39 |
40 |
41 |
43 |
44 |
51 |
52 |
53 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/bxfile_viewer.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
19 |
20 |
26 |
27 |
32 |
33 |
39 |
40 |
47 |
48 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/LocaleFileAdapter.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import java.util.List;
4 |
5 | import com.tracy.fileexplorer.TFile.MimeType;
6 |
7 |
8 | import android.content.Context;
9 | import android.view.LayoutInflater;
10 | import android.view.View;
11 | import android.view.ViewGroup;
12 | import android.widget.BaseAdapter;
13 | import android.widget.CheckBox;
14 | import android.widget.ImageView;
15 | import android.widget.TextView;
16 |
17 |
18 | /**
19 | * 本地文件adapter
20 | *
21 | * @author zhanglei
22 | *
23 | */
24 | public class LocaleFileAdapter extends BaseAdapter {
25 |
26 | private FileManager bfm;
27 | private List data;
28 | private Context cxt;
29 | private List choosedFiles;
30 | int w;
31 | private SyncImageLoader syncImageLoader;
32 | private SyncImageLoader.OnImageLoadListener imageLoadListener;
33 |
34 | public LocaleFileAdapter(List data, Context cxt , SyncImageLoader syncImageLoader , SyncImageLoader.OnImageLoadListener imageLoadListener) {
35 | super();
36 | this.data = data;
37 | this.cxt = cxt;
38 | this.syncImageLoader = syncImageLoader;
39 | this.imageLoadListener = imageLoadListener;
40 | bfm = FileManager.getInstance();
41 | choosedFiles = bfm.getChoosedFiles();
42 | w = cxt.getResources().getDimensionPixelSize(R.dimen.view_36dp);
43 | }
44 |
45 | @Override
46 | public int getCount() {
47 | // TODO Auto-generated method stub
48 | if(null!=data)
49 | return data.size();
50 | return 0;
51 | }
52 |
53 | @Override
54 | public Object getItem(int arg0) {
55 | // TODO Auto-generated method stub
56 | return arg0;
57 | }
58 |
59 | @Override
60 | public long getItemId(int arg0) {
61 | // TODO Auto-generated method stub
62 | return 0;
63 | }
64 |
65 | //目录:显示目录view;文件:显示文件view及勾选状况
66 | @Override
67 | public View getView(int pos, View view, ViewGroup arg2) {
68 | // TODO Auto-generated method stub
69 | if(null == view){
70 | view = LayoutInflater.from(cxt).inflate(R.layout.locale_file_item, null);
71 | }
72 | View dirView = view.findViewById(R.id.dirRl);
73 | TextView dirName = (TextView) view.findViewById(R.id.dirName);
74 |
75 | View fileView = view.findViewById(R.id.fileLl);
76 |
77 | view.setTag(pos);
78 | TFile bxFile = data.get(pos);
79 | if(bxFile.isDir()){
80 | dirView.setVisibility(View.VISIBLE);
81 | dirName.setText(bxFile.getFileName());
82 | fileView.setVisibility(View.GONE);
83 | }else{
84 | dirView.setVisibility(View.GONE);
85 | fileView.setVisibility(View.VISIBLE);
86 |
87 | CheckBox fileCheckBox = (CheckBox) view.findViewById(R.id.fileCheckBox);
88 | ImageView fileType = (ImageView) view.findViewById(R.id.fileType);
89 | TextView fileName = (TextView) view.findViewById(R.id.fileName);
90 | TextView fileSize = (TextView) view.findViewById(R.id.fileSize);
91 | TextView fileModifyDate = (TextView) view.findViewById(R.id.fileModifyDate);
92 | fileName.setText(bxFile.getFileName());
93 | fileSize.setText(bxFile.getFileSizeStr());
94 | fileModifyDate.setText(bxFile.getLastModifyTimeStr());
95 | if(bxFile.getMimeType().equals(MimeType.IMAGE)){
96 | fileType.setImageResource(R.drawable.bxfile_file_default_pic);
97 | if(null!=syncImageLoader && null!=imageLoadListener)
98 | syncImageLoader.loadDiskImage(pos, bxFile.getFilePath(), imageLoadListener);
99 | }else{
100 | fileType.setImageResource(bfm.getMimeDrawable(bxFile.getMimeType()));
101 | }
102 | fileCheckBox.setChecked(choosedFiles.contains(bxFile));//是否勾选chechBox
103 | }
104 | return view;
105 | }
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/locale_file_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
13 |
14 |
20 |
21 |
30 |
31 |
37 |
38 |
39 |
51 |
52 |
58 |
59 |
66 |
67 |
71 |
72 |
80 |
81 |
88 |
89 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/TFileViewer.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import java.io.File;
4 |
5 | import com.tracy.fileexplorer.TFile.FileState;
6 | import com.tracy.fileexplorer.TFile.MimeType;
7 | import com.tracy.fileexplorer.util.MIMEUtils;
8 |
9 |
10 | import android.app.Activity;
11 | import android.content.Intent;
12 | import android.os.Bundle;
13 | import android.util.Log;
14 | import android.view.View;
15 | import android.widget.Button;
16 | import android.widget.ImageView;
17 | import android.widget.TextView;
18 | import android.widget.Toast;
19 |
20 |
21 | /**
22 | * 单个文件查看器
23 | *
24 | * @author zhanglei
25 | *
26 | */
27 | public class TFileViewer extends Activity {
28 |
29 | private String tag = "BXFileViewer";
30 |
31 | private View otherTypeStub;
32 | private TFile bxFile;
33 | private Button fileOpBtn;
34 | private ImageView fileType;
35 | private TextView fileName;
36 | private TextView fileSize;
37 |
38 | @Override
39 | protected void onCreate(Bundle savedInstanceState) {
40 | // TODO Auto-generated method stub
41 | super.onCreate(savedInstanceState);
42 | setContentView(R.layout.bxfile_viewer);
43 | initViews();
44 | initData();
45 | }
46 |
47 | private void initData() {
48 | bxFile = (TFile) getIntent().getSerializableExtra("bxFile");
49 | TFile.FileState state = bxFile.getFileState();
50 | if(state.equals(FileState.UNLOAD)){
51 |
52 | otherTypeStub.setVisibility(View.VISIBLE);
53 | fileType = (ImageView) otherTypeStub.findViewById(R.id.fileType);
54 | fileOpBtn = (Button) otherTypeStub.findViewById(R.id.fileOpBtn);
55 | fileName = (TextView) otherTypeStub.findViewById(R.id.fileName);
56 | fileSize = (TextView) otherTypeStub.findViewById(R.id.fileSize);
57 | fileType.setImageResource(FileManager.getInstance().getMimeDrawable(bxFile.getMimeType()));
58 | fileName.setText(bxFile.getFileName());
59 | fileSize.setText(bxFile.getFileSizeStr());
60 | fileOpBtn.setText(getString(R.string.download));
61 | fileOpBtn.setOnClickListener(new View.OnClickListener() {
62 | @Override
63 | public void onClick(View v) {//下载
64 | }
65 | });
66 |
67 | }else if(state.equals(FileState.SENDED) || state.equals(FileState.DOWNLOADED)){
68 | if(bxFile.getMimeType().equals(MimeType.IMAGE)){
69 | openFile();
70 | }else{
71 | otherTypeStub.setVisibility(View.VISIBLE);
72 | fileType = (ImageView) otherTypeStub.findViewById(R.id.fileType);
73 | fileOpBtn = (Button) otherTypeStub.findViewById(R.id.fileOpBtn);
74 | fileName = (TextView) otherTypeStub.findViewById(R.id.fileName);
75 | fileSize = (TextView) otherTypeStub.findViewById(R.id.fileSize);
76 | fileType.setImageResource(FileManager.getInstance().getMimeDrawable(bxFile.getMimeType()));
77 | fileName.setText(bxFile.getFileName());
78 | fileSize.setText(bxFile.getFileSizeStr());
79 | fileOpBtn.setOnClickListener(new View.OnClickListener() {//打开
80 | @Override
81 | public void onClick(View v) {
82 | openFile();
83 | }
84 | });
85 | }
86 | }else if(state.equals(FileState.UNSEND)){
87 | otherTypeStub.setVisibility(View.VISIBLE);
88 | fileType = (ImageView) otherTypeStub.findViewById(R.id.fileType);
89 | fileOpBtn = (Button) otherTypeStub.findViewById(R.id.fileOpBtn);
90 | fileName = (TextView) otherTypeStub.findViewById(R.id.fileName);
91 | fileSize = (TextView) otherTypeStub.findViewById(R.id.fileSize);
92 | fileType.setImageResource(FileManager.getInstance().getMimeDrawable(bxFile.getMimeType()));
93 | fileName.setText(bxFile.getFileName());
94 | fileSize.setText(bxFile.getFileSizeStr());
95 | fileOpBtn.setText(getString(R.string.fileReSend));
96 | fileOpBtn.setOnClickListener(new View.OnClickListener() {
97 | @Override
98 | public void onClick(View v) {//重新发送
99 |
100 | }
101 | });
102 | }
103 | }
104 |
105 | private void initViews() {
106 | setTitle(getString(R.string.fileViewer));
107 | otherTypeStub = findViewById(R.id.stub_othertype);
108 | }
109 |
110 | public void onClick(View v){
111 | }
112 |
113 | private void openFile(){
114 | Intent intent = MIMEUtils.getInstance().getPendingIntent(TFileViewer.this, new File(bxFile.getFilePath()));
115 | try{
116 | startActivity(intent);
117 | finish();
118 | }catch(Exception e){
119 | Log.e(tag, e.toString());
120 | Toast.makeText(TFileViewer.this, TFileViewer.this.getString(R.string.attach_open_err), Toast.LENGTH_SHORT).show();
121 | }
122 | }
123 |
124 | }
125 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/util/MIMEUtils.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer.util;
2 |
3 | import java.io.File;
4 |
5 | import android.app.Activity;
6 | import android.content.Intent;
7 | import android.net.Uri;
8 | import android.text.TextUtils;
9 |
10 |
11 | /***
12 | *MIME工具类
13 | *
14 | */
15 | public class MIMEUtils {
16 |
17 | private static MIMEUtils instance;
18 |
19 | private MIMEUtils() {
20 | }
21 |
22 | public static MIMEUtils getInstance() {
23 | if (null == instance) {
24 | instance = new MIMEUtils();
25 | }
26 | return instance;
27 | }
28 |
29 | private final String[][] MIME_MapTable = {
30 | // {后缀名,MIME类型}
31 | { ".3gp", "video/3gpp" },
32 | { ".apk", "application/vnd.android.package-archive" },
33 | { ".asf", "video/x-ms-asf" },
34 | { ".avi", "video/x-msvideo" },
35 | { ".bin", "application/octet-stream" },
36 | { ".bmp", "image/bmp" },
37 | { ".c", "text/plain" },
38 | { ".class", "application/octet-stream" },
39 | { ".conf", "text/plain" },
40 | { ".cpp", "text/plain" },
41 | { ".doc", "application/msword" },
42 | { ".docx",
43 | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
44 | { ".xls", "application/vnd.ms-excel" },
45 | { ".xlsx",
46 | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
47 | { ".exe", "application/octet-stream" },
48 | { ".gif", "image/gif" },
49 | { ".gtar", "application/x-gtar" },
50 | { ".gz", "application/x-gzip" },
51 | { ".h", "text/plain" },
52 | { ".htm", "text/html" },
53 | { ".html", "text/html" },
54 | { ".jar", "application/java-archive" },
55 | { ".java", "text/plain" },
56 | { ".jpeg", "image/jpeg" },
57 | { ".jpg", "image/jpeg" },
58 | { ".js", "application/x-javascript" },
59 | { ".log", "text/plain" },
60 | { ".m3u", "audio/x-mpegurl" },
61 | { ".m4a", "audio/mp4a-latm" },
62 | { ".m4b", "audio/mp4a-latm" },
63 | { ".m4p", "audio/mp4a-latm" },
64 | { ".m4u", "video/vnd.mpegurl" },
65 | { ".m4v", "video/x-m4v" },
66 | { ".mov", "video/quicktime" },
67 | { ".mp2", "audio/x-mpeg" },
68 | { ".mp3", "audio/x-mpeg" },
69 | { ".mp4", "video/mp4" },
70 | { ".mpc", "application/vnd.mpohun.certificate" },
71 | { ".mpe", "video/mpeg" },
72 | { ".mpeg", "video/mpeg" },
73 | { ".mpg", "video/mpeg" },
74 | { ".mpg4", "video/mp4" },
75 | { ".mpga", "audio/mpeg" },
76 | { ".msg", "application/vnd.ms-outlook" },
77 | { ".ogg", "audio/ogg" },
78 | { ".pdf", "application/pdf" },
79 | { ".png", "image/png" },
80 | { ".pps", "application/vnd.ms-powerpoint" },
81 | { ".ppt", "application/vnd.ms-powerpoint" },
82 | { ".pptx",
83 | "application/vnd.openxmlformats-officedocument.presentationml.presentation" },
84 | { ".prop", "text/plain" }, { ".rc", "text/plain" },
85 | { ".rmvb", "audio/x-pn-realaudio" }, { ".rtf", "application/rtf" },
86 | { ".sh", "text/plain" }, { ".tar", "application/x-tar" },
87 | { ".tgz", "application/x-compressed" }, { ".txt", "text/plain" },
88 | { ".wav", "audio/x-wav" }, { ".wma", "audio/x-ms-wma" },
89 | { ".wmv", "audio/x-ms-wmv" },
90 | { ".wps", "application/vnd.ms-works" }, { ".xml", "text/plain" },
91 | { ".z", "application/x-compress" },
92 | { ".zip", "application/x-zip-compressed" }, { "", "*/*" } };
93 |
94 | //rar、
95 |
96 | /**
97 | * 根据文件后缀名获得对应的MIME类型
98 | *
99 | * @param file
100 | */
101 | private String getMIMEType(File file) {
102 | String type = "*/*";
103 | if(null==file) {
104 | return type;
105 | }
106 | String fName = file.getName();
107 | if(null == fName ) {
108 | return type;
109 | }
110 | int dotIndex = fName.lastIndexOf(".");
111 | if (dotIndex < 0) {
112 | return type;
113 | }
114 | String end = fName.substring(dotIndex, fName.length()).toLowerCase();
115 | if (TextUtils.isEmpty(end))
116 | return type;
117 | for (int i = 0; i < MIME_MapTable.length; i++) {
118 | if (end.equals(MIME_MapTable[i][0]))
119 | type = MIME_MapTable[i][1];
120 | }
121 | return type;
122 | }
123 |
124 | /**
125 | * 浏览文件
126 | *
127 | * @param cxt
128 | * @param file
129 | */
130 | public Intent getPendingIntent(Activity cxt, File file) {
131 | Intent intent = new Intent();
132 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
133 | intent.setAction(Intent.ACTION_VIEW);
134 | String type = getMIMEType(file);
135 | intent.setDataAndType(Uri.fromFile(file), type);
136 | return intent;
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/TFile.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import java.io.File;
4 | import java.io.Serializable;
5 |
6 | import android.text.TextUtils;
7 |
8 | import com.tracy.fileexplorer.util.FileUtils;
9 | import com.tracy.fileexplorer.util.TimeUtils;
10 |
11 | /***
12 | *
13 | * @author zhanglei
14 | *
15 | */
16 | public class TFile implements Comparable, Serializable {
17 |
18 | public enum MimeType{
19 | APK,//apk
20 | TXT,//文本文件
21 | IMAGE,//图片
22 | RAR,//压缩文件
23 | DOC,//doc
24 | PPT,//ppt
25 | XLS,//xls
26 | HTML,//html
27 | MUSIC,//mp3
28 | VIDEO,//video
29 | PDF,//pdf
30 | UNKNOWN//未知
31 | }
32 |
33 | //文件发送接收状态
34 | public enum FileState{
35 | DOWNLOADED,//已下载
36 | UNLOAD,//未下载
37 | SENDED,//已发送
38 | UNSEND//发送失败
39 | }
40 |
41 | private TFile(){}
42 |
43 | private String fileName; //文件名
44 | private String fileUrl; //文件url下载路径
45 | private String filePath; //文件本地路径
46 | private boolean isDir;//是否是文件夹
47 | private long lastModifyTime;//最后修改时间
48 | private long fileSize;//大小
49 | private String fileSizeStr;//大小字符串
50 | private String lastModifyTimeStr;//最后修改时间字符串
51 | private MimeType mimeType;//mimeType
52 | private FileState fileState;//文件状态
53 |
54 | public FileState getFileState() {
55 | return fileState;
56 | }
57 | public void setFileState(FileState fileState) {
58 | this.fileState = fileState;
59 | }
60 | public String getFileUrl() {
61 | return fileUrl;
62 | }
63 | public String getFileName() {
64 | return fileName;
65 | }
66 | public String getFilePath() {
67 | return filePath;
68 | }
69 | public boolean isDir() {
70 | return isDir;
71 | }
72 | public long getLastModifyTime() {
73 | return lastModifyTime;
74 | }
75 | public long getFileSize() {
76 | return fileSize;
77 | }
78 | public String getFileSizeStr() {
79 | return fileSizeStr;
80 | }
81 | public MimeType getMimeType() {
82 | return mimeType;
83 | }
84 | public String getLastModifyTimeStr() {
85 | return lastModifyTimeStr;
86 | }
87 |
88 | //本地文件builder模式
89 | public static class Builder{
90 | TFile bxFile;
91 |
92 | public Builder(String path){
93 | if(FileUtils.isFileExist(path)){
94 | File file = new File(path);
95 | bxFile = new TFile();
96 | bxFile.fileName = file.getName();
97 | bxFile.filePath = file.getAbsolutePath();
98 | boolean isDir = file.isDirectory();
99 | bxFile.isDir = isDir;
100 | if(!isDir){
101 | bxFile.fileSize = file.length();
102 | bxFile.fileSizeStr = FileUtils.getFileSizeStr(bxFile.fileSize);
103 | bxFile.lastModifyTime = file.lastModified();
104 | bxFile.lastModifyTimeStr = TimeUtils.getDateTime(bxFile.lastModifyTime);
105 | String exspansion = FileUtils.getExspansion(bxFile.fileName);
106 | if(TextUtils.isEmpty(exspansion))
107 | bxFile.mimeType = MimeType.UNKNOWN;
108 | else{
109 | MimeType mimeType = FileManager.getInstance().getMimeType(exspansion);
110 | bxFile.mimeType = null==mimeType?MimeType.UNKNOWN:mimeType;
111 | }
112 | }
113 | }
114 | }
115 |
116 | public TFile build(){
117 | return bxFile;
118 | }
119 | }
120 |
121 | //url文件builder模式(用于短消息附带的文件信息初始化)
122 | public static class UrlBuilder{
123 | TFile bxFile;
124 |
125 | public UrlBuilder(String fileUrl , String fileName , long fileSize , String savedPath , FileState fileState){
126 | bxFile = new TFile();
127 | bxFile.fileUrl = fileUrl;
128 | bxFile.fileName = fileName;
129 | bxFile.fileSize = fileSize;
130 | bxFile.fileState = fileState;
131 | bxFile.fileSizeStr = FileUtils.getFileSizeStr(fileSize);
132 | bxFile.filePath = savedPath;
133 | String exspansion = FileUtils.getExspansion(fileName);
134 | if(TextUtils.isEmpty(exspansion))
135 | bxFile.mimeType = MimeType.UNKNOWN;
136 | else{
137 | MimeType mimeType = FileManager.getInstance().getMimeType(exspansion);
138 | bxFile.mimeType = null==mimeType?MimeType.UNKNOWN:mimeType;
139 | }
140 | }
141 |
142 | public TFile build(){
143 | return bxFile;
144 | }
145 | }
146 |
147 | @Override
148 | public int compareTo(TFile another) {
149 | if(isDir()){
150 | if(another.isDir())
151 | return fileName.compareToIgnoreCase(another.getFileName());
152 | else
153 | return -1;
154 | }else{
155 | if(another.isDir())
156 | return 1;
157 | else
158 | return fileName.compareToIgnoreCase(another.getFileName());
159 | }
160 | }
161 | @Override
162 | public boolean equals(Object o) {
163 | // TODO Auto-generated method stub
164 | if(null == o)
165 | return false;
166 | if(o instanceof TFile){
167 | TFile other = (TFile)o;
168 | return other.filePath.equals(filePath);
169 | }else{
170 | return false;
171 | }
172 | }
173 | @Override
174 | public int hashCode() {
175 | return filePath.hashCode();
176 | }
177 |
178 | public boolean isFileSizeValid(){
179 | return fileSize data;
34 | private LocaleFileAdapter adapter;
35 | private TextView emptyView;
36 | private FileManager bfm;
37 | private TextView localefile_bottom_tv;
38 | private Button localefile_bottom_btn;
39 |
40 | private Handler handler = new Handler(){
41 |
42 | @Override
43 | public void handleMessage(Message msg) {
44 | // TODO Auto-generated method stub
45 | if(1 == msg.what){
46 | lv.setVisibility(View.VISIBLE);
47 | emptyView.setVisibility(View.GONE);
48 | adapter = new LocaleFileAdapter(data,LocaleMediaFileBrowser.this,null,null);
49 | lv.setAdapter(adapter);
50 | }else if(0 == msg.what){
51 | lv.setVisibility(View.GONE);
52 | emptyView.setVisibility(View.VISIBLE);
53 | emptyView.setText(getString(R.string.curCatagoryNoFiles));
54 | }
55 | super.handleMessage(msg);
56 | }
57 |
58 | };
59 |
60 | @Override
61 | protected void onCreate(Bundle savedInstanceState) {
62 | // TODO Auto-generated method stub
63 | super.onCreate(savedInstanceState);
64 | setContentView(R.layout.localefile_browser);
65 | bfm = FileManager.getInstance();
66 | initViews();
67 | initData();
68 | onFileClick();
69 | }
70 |
71 | private void initData() {
72 | // TODO Auto-generated method stub
73 | Intent intent = getIntent();
74 | setTitle(intent.getStringExtra("title"));
75 |
76 | setData(intent.getData());
77 | }
78 |
79 | private void setData(final Uri uri){
80 | FEApplication app = (FEApplication) getApplication();
81 | app.execRunnable(new Runnable(){
82 |
83 | @Override
84 | public void run() {
85 | // TODO Auto-generated method stub
86 | data= bfm.getMediaFiles(LocaleMediaFileBrowser.this, uri);
87 | if(null != data){
88 | Collections.sort(data);
89 | handler.sendEmptyMessage(1);
90 | }
91 | else
92 | handler.sendEmptyMessage(0);
93 | }
94 |
95 | });
96 | }
97 |
98 | private void initViews() {
99 | // TODO Auto-generated method stub
100 | TextView curDir = (TextView) findViewById(R.id.curDir);
101 | curDir.setVisibility(View.GONE);
102 | lv = (ListView) findViewById(R.id.listView);
103 | lv.setOnItemClickListener(this);
104 | emptyView = (TextView) findViewById(R.id.emptyView);
105 | localefile_bottom_btn = (Button) findViewById(R.id.localefile_bottom_btn);
106 | localefile_bottom_tv = (TextView) findViewById(R.id.localefile_bottom_tv);
107 | }
108 |
109 | public void onClick(View v){
110 | switch(v.getId()){
111 | case R.id.localefile_bottom_btn:
112 | setResult(2);
113 | finish();
114 | break;
115 | }
116 | }
117 |
118 | @Override
119 | public boolean onCreateOptionsMenu(Menu menu) {
120 | // TODO Auto-generated method stub
121 | menu.add(0, 0, 0, getString(R.string.cancel));
122 | return super.onCreateOptionsMenu(menu);
123 | }
124 |
125 | @Override
126 | public boolean onOptionsItemSelected(MenuItem item) {
127 | // TODO Auto-generated method stub
128 | if(0 == item.getItemId()){
129 | setResult(1);
130 | finish();
131 | }
132 | return super.onOptionsItemSelected(item);
133 | }
134 |
135 | //点击文件进行勾选操作
136 | @Override
137 | public void onItemClick(AdapterView> arg0, View view, int pos, long arg3) {
138 | CheckBox fileCheckBox = (CheckBox) view.findViewById(R.id.fileCheckBox);
139 | TFile bxfile = data.get(pos);
140 | if(bxfile.isFileSizeValid()){
141 | List choosedFiles = bfm.getChoosedFiles();
142 | if(choosedFiles.contains(bxfile)){
143 | choosedFiles.remove(bxfile);
144 | fileCheckBox.setChecked(false);
145 | }else{
146 | if(bfm.isOverMaxCnt()){
147 | showToast(R.string.maxFileCntWarn);
148 | return ;
149 | }else{
150 | choosedFiles.add(bxfile);
151 | fileCheckBox.setChecked(true);
152 | }
153 | }
154 | onFileClick();
155 | }else{
156 | showToast(R.string.maxFileSizeWarn);
157 | }
158 | }
159 |
160 | //点击文件,触发ui更新
161 | //onResume,触发ui更新
162 | private void onFileClick() {
163 | localefile_bottom_tv.setText(bfm.getFilesSizes());
164 | int cnt = bfm.getFilesCnt();
165 | localefile_bottom_btn.setText(String.format(getString(R.string.bxfile_choosedCnt), cnt));
166 | localefile_bottom_btn.setEnabled(cnt>0);
167 | }
168 |
169 | @Override
170 | protected void onDestroy() {
171 | // TODO Auto-generated method stub
172 | super.onDestroy();
173 | if(null!=data){
174 | data.clear();
175 | }
176 | data = null;
177 | adapter = null;
178 | handler = null;
179 | }
180 |
181 | }
182 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/FileManager.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import android.app.Activity;
4 | import android.database.Cursor;
5 | import android.net.Uri;
6 | import android.provider.MediaStore;
7 |
8 | import com.tracy.fileexplorer.TFile.MimeType;
9 | import com.tracy.fileexplorer.util.FileUtils;
10 |
11 | import java.util.ArrayList;
12 | import java.util.HashMap;
13 | import java.util.List;
14 | import java.util.Map;
15 |
16 |
17 | /***
18 | * 本地文件管理器
19 | *
20 | * @author zhanglei
21 | *
22 | */
23 | public class FileManager {
24 |
25 | public static final int DEFAULT_MAX_CHOOSED_CNT = 5;//一次最多选5个文件(默认)
26 | public static final long DEFAULT_MAX_FILESIZE = 10*1024*1024;//单个最大文件为10M(默认)
27 |
28 | private int maxFileCnt = DEFAULT_MAX_CHOOSED_CNT ;
29 | private long maxFileSize = DEFAULT_MAX_FILESIZE;
30 |
31 | private static FileManager instance;
32 | private final Map map;//mimeType集合
33 | private final Map resMap;//mimeType对应图片资源集合
34 | private final List choosedFiles;//已选择文件集合
35 | public static FileManager getInstance(){
36 | if(null == instance){
37 | instance = new FileManager();
38 | }
39 | return instance;
40 | }
41 |
42 | /**
43 | * 恢复默认文件选择设置
44 | */
45 | public void reSetDefaultConfiguration(){
46 | maxFileCnt = DEFAULT_MAX_CHOOSED_CNT ;
47 | maxFileSize = DEFAULT_MAX_FILESIZE;
48 | }
49 |
50 | /***
51 | * 重新配置文件选择设置
52 | * @param maxChoosedCnt
53 | * @param maxFileSize
54 | */
55 | public void initConfiguration(int maxChoosedCnt , long maxFileSize){
56 | if(maxChoosedCnt>0)
57 | this.maxFileCnt = maxChoosedCnt;
58 | if(maxFileSize>0)
59 | this.maxFileSize = maxFileSize;
60 | }
61 |
62 | public int getMaxFileCnt() {
63 | return maxFileCnt;
64 | }
65 |
66 | public long getMaxFileSize() {
67 | return maxFileSize;
68 | }
69 |
70 | //初始化数据
71 | private FileManager(){
72 | map = new HashMap();
73 | map.put(".amr", MimeType.MUSIC);
74 | map.put(".mp3", MimeType.MUSIC);
75 | map.put(".ogg", MimeType.MUSIC);
76 | map.put(".wav", MimeType.MUSIC);
77 | map.put(".3gp", MimeType.VIDEO);
78 | map.put(".mp4", MimeType.VIDEO);
79 | map.put(".rmvb", MimeType.VIDEO);
80 | map.put(".mpeg", MimeType.VIDEO);
81 | map.put(".mpg", MimeType.VIDEO);
82 | map.put(".asf", MimeType.VIDEO);
83 | map.put(".avi", MimeType.VIDEO);
84 | map.put(".wmv", MimeType.VIDEO);
85 | map.put(".apk", MimeType.APK);
86 | map.put(".bmp", MimeType.IMAGE);
87 | map.put(".gif", MimeType.IMAGE);
88 | map.put(".jpeg", MimeType.IMAGE);
89 | map.put(".jpg", MimeType.IMAGE);
90 | map.put(".png", MimeType.IMAGE);
91 | map.put(".doc", MimeType.DOC);
92 | map.put(".docx", MimeType.DOC);
93 | map.put(".rtf", MimeType.DOC);
94 | map.put(".wps", MimeType.DOC);
95 | map.put(".xls", MimeType.XLS);
96 | map.put(".xlsx", MimeType.XLS);
97 | map.put(".gtar", MimeType.RAR);
98 | map.put(".gz", MimeType.RAR);
99 | map.put(".zip", MimeType.RAR);
100 | map.put(".tar", MimeType.RAR);
101 | map.put(".rar", MimeType.RAR);
102 | map.put(".jar", MimeType.RAR);
103 | map.put(".htm", MimeType.HTML);
104 | map.put(".html", MimeType.HTML);
105 | map.put(".xhtml", MimeType.HTML);
106 | map.put(".java", MimeType.TXT);
107 | map.put(".txt", MimeType.TXT);
108 | map.put(".xml", MimeType.TXT);
109 | map.put(".log", MimeType.TXT);
110 | map.put(".pdf", MimeType.PDF);
111 | map.put(".ppt", MimeType.PPT);
112 | map.put(".pptx", MimeType.PPT);
113 |
114 | resMap = new HashMap();
115 | resMap.put(MimeType.APK, R.drawable.bxfile_file_apk);
116 | resMap.put(MimeType.DOC, R.drawable.bxfile_file_doc);
117 | resMap.put(MimeType.HTML, R.drawable.bxfile_file_html);
118 | resMap.put(MimeType.IMAGE, R.drawable.bxfile_file_unknow);
119 | resMap.put(MimeType.MUSIC, R.drawable.bxfile_file_mp3);
120 | resMap.put(MimeType.VIDEO, R.drawable.bxfile_file_video);
121 | resMap.put(MimeType.PDF, R.drawable.bxfile_file_pdf);
122 | resMap.put(MimeType.PPT, R.drawable.bxfile_file_ppt);
123 | resMap.put(MimeType.RAR, R.drawable.bxfile_file_zip);
124 | resMap.put(MimeType.TXT, R.drawable.bxfile_file_txt);
125 | resMap.put(MimeType.XLS, R.drawable.bxfile_file_xls);
126 | resMap.put(MimeType.UNKNOWN, R.drawable.bxfile_file_unknow);
127 |
128 | choosedFiles = new ArrayList();
129 | }
130 |
131 | public MimeType getMimeType(String exspansion){
132 | return map.get(exspansion.toLowerCase());
133 | }
134 | public Integer getMimeDrawable(MimeType type){
135 | return resMap.get(type);
136 | }
137 |
138 | //已选择文件集合
139 | public List getChoosedFiles() {
140 | return choosedFiles;
141 | }
142 |
143 | //已选择文件大小
144 | public String getFilesSizes(){
145 | long sum = 0;
146 | for(TFile f:choosedFiles){
147 | sum+=f.getFileSize();
148 | }
149 | return FileUtils.getFileSizeStr(sum);
150 | }
151 |
152 | //已选择文件数
153 | public int getFilesCnt(){
154 | return choosedFiles.size();
155 | }
156 |
157 | public void clear(){
158 | choosedFiles.clear();
159 | }
160 |
161 | //一次最多选10个文件
162 | public boolean isOverMaxCnt(){
163 | return getFilesCnt()>=maxFileCnt;
164 | }
165 |
166 | //查找external多媒体文件
167 | public synchronized List getMediaFiles(Activity cxt , Uri uri) {
168 | Cursor mCursor = cxt.managedQuery(
169 | uri,
170 | new String[] {MediaStore.Audio.Media.DATA}, null,
171 | null, " date_modified desc");
172 | cxt.startManagingCursor(mCursor);
173 | int count = mCursor.getCount();
174 | if(count>0){
175 | List data = new ArrayList();
176 | if (mCursor.moveToFirst()) {
177 | do {
178 | TFile.Builder builder = new TFile.Builder(mCursor.getString(0));
179 | TFile bxfile = builder.build();
180 | if(null != bxfile)
181 | data.add(bxfile);
182 | } while (mCursor.moveToNext());
183 | }
184 | return data;
185 | }else{
186 | return null;
187 | }
188 | }
189 |
190 | //external多媒体文件计数
191 | public synchronized int getMediaFilesCnt(Activity cxt , Uri uri) {
192 | Cursor mCursor = cxt.managedQuery(
193 | uri,
194 | new String[] {MediaStore.Audio.Media.DATA}, null,
195 | null, null);
196 | cxt.startManagingCursor(mCursor);
197 | int cnt = mCursor.getCount();
198 | return cnt;
199 | }
200 |
201 | }
202 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/LocaleFileMain.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import java.io.File;
4 |
5 | import com.tracy.fileexplorer.util.FileUtils;
6 |
7 |
8 | import android.app.Activity;
9 | import android.content.Intent;
10 | import android.os.Bundle;
11 | import android.os.Environment;
12 | import android.provider.MediaStore;
13 | import android.text.TextUtils;
14 | import android.view.Menu;
15 | import android.view.MenuItem;
16 | import android.view.View;
17 | import android.widget.Button;
18 | import android.widget.TextView;
19 | import android.widget.Toast;
20 |
21 |
22 | /**
23 | * 本地文件 首页
24 | *
25 | * @author zhanglei
26 | *
27 | */
28 |
29 | public class LocaleFileMain extends Activity {
30 |
31 | private String extSdCardPath;
32 | private TextView localefile_bottom_tv;
33 | private Button localefile_bottom_btn;
34 | private FileManager bfm;
35 |
36 | private final int REQUEST = 1;
37 |
38 | @Override
39 | protected void onCreate(Bundle savedInstanceState) {
40 | // TODO Auto-generated method stub
41 | super.onCreate(savedInstanceState);
42 | setContentView(R.layout.localefile_main);
43 | setTitle(getString(R.string.localeFile));
44 | bfm = FileManager.getInstance();
45 | localefile_bottom_btn = (Button) findViewById(R.id.localefile_bottom_btn);
46 | localefile_bottom_tv = (TextView) findViewById(R.id.localefile_bottom_tv);
47 | localefile_bottom_btn.setText(String.format(getString(R.string.bxfile_choosedCnt),0));
48 |
49 | TextView picCnt = (TextView) findViewById(R.id.localefile_pic_cnt);
50 | picCnt.setText(String.format(getString(R.string.bxfile_media_cnt), bfm.getMediaFilesCnt(this, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)));
51 | TextView musicCnt = (TextView) findViewById(R.id.localefile_music_cnt);
52 | musicCnt.setText(String.format(getString(R.string.bxfile_media_cnt), bfm.getMediaFilesCnt(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI)));
53 | TextView videoCnt = (TextView) findViewById(R.id.localefile_video_cnt);
54 | videoCnt.setText(String.format(getString(R.string.bxfile_media_cnt), bfm.getMediaFilesCnt(this, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)));
55 |
56 | extSdCardPath = FileUtils.getExtSdCardPath();
57 | if(!TextUtils.isEmpty(extSdCardPath)){
58 | View localefile_sdcard = findViewById(R.id.localefile_sdcard);
59 | View localefile_sdcard2 = findViewById(R.id.localefile_sdcard2);
60 | View localefile_extSdcard = findViewById(R.id.localefile_extSdcard);
61 | localefile_sdcard2.setVisibility(View.VISIBLE);
62 | localefile_extSdcard.setVisibility(View.VISIBLE);
63 | localefile_sdcard.setVisibility(View.GONE);
64 | }
65 | }
66 |
67 | //显示底部 已选文件大小 数目
68 | @Override
69 | protected void onResume() {
70 | // TODO Auto-generated method stub
71 | super.onResume();
72 | localefile_bottom_tv.setText(bfm.getFilesSizes());
73 | int cnt = bfm.getFilesCnt();
74 | localefile_bottom_btn.setText(String.format(getString(R.string.bxfile_choosedCnt), cnt));
75 | localefile_bottom_btn.setEnabled(cnt>0);
76 | }
77 |
78 | @Override
79 | public boolean onCreateOptionsMenu(Menu menu) {
80 | // TODO Auto-generated method stub
81 | menu.add(0, 0, 0, getString(R.string.cancel));
82 | return super.onCreateOptionsMenu(menu);
83 | }
84 |
85 | @Override
86 | public boolean onOptionsItemSelected(MenuItem item) {
87 | // TODO Auto-generated method stub
88 | if(0 == item.getItemId()){
89 | bfm.clear();
90 | finish();
91 | }
92 | return super.onOptionsItemSelected(item);
93 | }
94 |
95 | public void onClick(View v){
96 | switch(v.getId()){
97 | case R.id.localefile_music:
98 | Intent intent5 = new Intent(this,LocaleMediaFileBrowser.class);
99 | intent5.putExtra("title", getString(R.string.bxfile_music));
100 | intent5.setData(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
101 | startActivityForResult(intent5,REQUEST);
102 | break;
103 | case R.id.localefile_video:
104 | Intent intent6 = new Intent(this,LocaleMediaFileBrowser.class);
105 | intent6.putExtra("title", getString(R.string.bxfile_video));
106 | intent6.setData(MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
107 | startActivityForResult(intent6,REQUEST);
108 | break;
109 | case R.id.localefile_picture:
110 | Intent intent7 = new Intent(this,LocaleFileGallery.class);
111 | intent7.putExtra("title", getString(R.string.bxfile_image));
112 | startActivityForResult(intent7,REQUEST);
113 | break;
114 | case R.id.localefile_download:
115 | if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
116 | Intent intent1 = new Intent(this,LocaleFileBrowser.class);
117 | intent1.putExtra("title", getString(R.string.bxfile_download));
118 | String base = Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator;
119 | String downloadPath = base+"download";
120 | File file = new File(downloadPath);
121 | if(!file.exists())
122 | file.mkdir();
123 | intent1.putExtra("startPath", downloadPath);
124 | startActivityForResult(intent1,REQUEST);
125 | }else{
126 | Toast.makeText(this, getString(R.string.SDCardNotMounted), Toast.LENGTH_SHORT).show();
127 | }
128 | break;
129 | case R.id.localefile_ram:
130 | Intent intent2 = new Intent(this,LocaleFileBrowser.class);
131 | intent2.putExtra("title", getString(R.string.bxfile_ram));
132 | intent2.putExtra("startPath", "/");
133 | startActivityForResult(intent2,REQUEST);
134 | break;
135 | case R.id.localefile_sdcard:
136 | case R.id.localefile_sdcard2:
137 | if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
138 | Intent intent3 = new Intent(this,LocaleFileBrowser.class);
139 | intent3.putExtra("title", getString(R.string.bxfile_sdcard));
140 | intent3.putExtra("startPath", Environment.getExternalStorageDirectory().getAbsolutePath());
141 | startActivityForResult(intent3,REQUEST);
142 | }else{
143 | Toast.makeText(this, getString(R.string.SDCardNotMounted), Toast.LENGTH_SHORT).show();
144 | }
145 | break;
146 | case R.id.localefile_extSdcard:
147 | Intent intent4 = new Intent(this,LocaleFileBrowser.class);
148 | intent4.putExtra("title", getString(R.string.bxfile_extsdcard));
149 | intent4.putExtra("startPath", extSdCardPath);
150 | startActivityForResult(intent4,REQUEST);
151 | break;
152 |
153 | case R.id.localefile_bottom_btn:
154 | finish();
155 | break;
156 | }
157 | }
158 |
159 | @Override
160 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
161 | // TODO Auto-generated method stub
162 | if(REQUEST == requestCode && 1==resultCode){
163 | bfm.clear();
164 | finish();
165 | }else if(REQUEST == requestCode && 2==resultCode){
166 | finish();
167 | }
168 | super.onActivityResult(requestCode, resultCode, data);
169 | }
170 |
171 | @Override
172 | protected void onDestroy() {
173 | super.onDestroy();
174 | System.gc();
175 | }
176 |
177 | }
178 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/SyncImageLoader.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.FileNotFoundException;
7 | import java.io.FileOutputStream;
8 | import java.io.InputStream;
9 | import java.lang.ref.SoftReference;
10 | import java.net.URL;
11 | import java.util.HashMap;
12 | import java.util.concurrent.ExecutorService;
13 | import java.util.concurrent.Executors;
14 |
15 |
16 | import android.graphics.Bitmap;
17 | import android.graphics.BitmapFactory;
18 | import android.graphics.drawable.BitmapDrawable;
19 | import android.graphics.drawable.Drawable;
20 | import android.os.Environment;
21 | import android.os.Handler;
22 | import android.util.Log;
23 |
24 |
25 | /***
26 | * 图片加载器
27 | *
28 | * @author zhanglei
29 | *
30 | */
31 | public class SyncImageLoader {
32 |
33 | private String tag = "SyncImageLoader";
34 | private Object lock = new Object();
35 | private boolean mAllowLoad = true;
36 | private boolean firstLoad = true;
37 | private int mStartLoadLimit = 0;
38 | private int mStopLoadLimit = 0;
39 | final Handler handler = new Handler();
40 | private HashMap> imageCache = new HashMap>();
41 | private ExecutorService pool = Executors.newScheduledThreadPool(20);
42 |
43 | public interface OnImageLoadListener {
44 | public void onImageLoad(Integer t, Drawable drawable);
45 | public void onError(Integer t);
46 | }
47 |
48 | public void setLoadLimit(int startLoadLimit,int stopLoadLimit){
49 | if(startLoadLimit > stopLoadLimit){
50 | return;
51 | }
52 | mStartLoadLimit = startLoadLimit;
53 | mStopLoadLimit = stopLoadLimit;
54 | }
55 |
56 | public void restore(){
57 | mAllowLoad = true;
58 | firstLoad = true;
59 | }
60 |
61 | public void lock(){
62 | mAllowLoad = false;
63 | firstLoad = false;
64 | }
65 |
66 | public void unlock(){
67 | mAllowLoad = true;
68 | synchronized (lock) {
69 | lock.notifyAll();
70 | }
71 | }
72 |
73 | //从网络url加载
74 | public void loadImageFromUrl(final Integer mt,final String mImageUrl,
75 | final OnImageLoadListener mListener) {
76 | pool.execute((new Runnable() {
77 |
78 | @Override
79 | public void run() {
80 | if(!mAllowLoad){
81 | synchronized (lock) {
82 | try {
83 | lock.wait();
84 | } catch (InterruptedException e) {
85 | Log.e(tag, Log.getStackTraceString(e));
86 | }
87 | }
88 | }
89 |
90 | if(mAllowLoad && firstLoad){
91 | loadImage(mImageUrl, mt, mListener);
92 | }
93 |
94 | if(mAllowLoad && mt <= mStopLoadLimit && mt >= mStartLoadLimit){
95 | loadImage(mImageUrl, mt, mListener);
96 | }
97 | }
98 | }));
99 | }
100 |
101 | private void loadImage(final String mImageUrl,final Integer mt,final OnImageLoadListener mListener){
102 |
103 | if (imageCache.containsKey(mImageUrl)) {
104 | SoftReference softReference = imageCache.get(mImageUrl);
105 | final Drawable d = softReference.get();
106 | if (d != null) {
107 | handler.post(new Runnable() {
108 | @Override
109 | public void run() {
110 | if(mAllowLoad){
111 | mListener.onImageLoad(mt, d);
112 | }
113 | }
114 | });
115 | return;
116 | }
117 | }
118 | try {
119 | final Drawable d = loadImageFromUrl(mImageUrl);
120 | if(d != null){
121 | imageCache.put(mImageUrl, new SoftReference(d));
122 | }
123 | handler.post(new Runnable() {
124 | @Override
125 | public void run() {
126 | if(mAllowLoad){
127 | mListener.onImageLoad(mt, d);
128 | }
129 | }
130 | });
131 | } catch (Exception e) {
132 | handler.post(new Runnable() {
133 | @Override
134 | public void run() {
135 | mListener.onError(mt);
136 | }
137 | });
138 | Log.e(tag, Log.getStackTraceString(e));
139 | }
140 | }
141 |
142 | private Drawable loadImageFromUrl(String url) throws Exception {
143 | if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
144 | String FileUrl = Environment.getExternalStorageDirectory()+"/BoXiao/cache/";
145 | File folder = new File(FileUrl);
146 | if(!folder.exists()){
147 | folder.mkdir();
148 | }
149 | File f = new File(FileUrl);
150 | if(f.exists()){
151 | return Drawable.createFromStream(new FileInputStream(f), "src");
152 | }
153 | URL m = new URL(url);
154 | InputStream i = (InputStream) m.getContent();
155 | DataInputStream in = new DataInputStream(i);
156 | FileOutputStream out = new FileOutputStream(f);
157 | byte[] buffer = new byte[1024];
158 | int byteread=0;
159 | while ((byteread = in.read(buffer)) != -1) {
160 | out.write(buffer, 0, byteread);
161 | }
162 | in.close();
163 | out.close();
164 | return Drawable.createFromStream(i, "src");
165 | }
166 | else{
167 | URL m = new URL(url);
168 | InputStream i = (InputStream) m.getContent();
169 | Drawable d = Drawable.createFromStream(i, "src");
170 | return d;
171 | }
172 |
173 | }
174 |
175 |
176 |
177 |
178 |
179 |
180 | //加载本地图片
181 | public void loadDiskImage(final Integer t, final String localeImagePath,
182 | final OnImageLoadListener listener) {
183 | pool.execute((new Runnable() {
184 | @Override
185 | public void run() {
186 | if(!mAllowLoad){
187 | synchronized (lock) {
188 | try {
189 | lock.wait();
190 | } catch (InterruptedException e) {
191 | Log.e(tag, Log.getStackTraceString(e));
192 | }
193 | }
194 | }
195 |
196 | if(mAllowLoad && firstLoad){
197 | loadLocaleImage(localeImagePath, t, listener);
198 | }
199 |
200 | if(mAllowLoad && t <= mStopLoadLimit && t >= mStartLoadLimit){
201 | loadLocaleImage(localeImagePath, t, listener);
202 | }
203 | }
204 | }));
205 | }
206 |
207 | private void loadLocaleImage(final String localeImagePath,final Integer mt,final OnImageLoadListener mListener){
208 | if (imageCache.containsKey(localeImagePath)) {
209 | SoftReference softReference = imageCache.get(localeImagePath);
210 | final Drawable d = softReference.get();
211 | if (d != null) {
212 | handler.post(new Runnable() {
213 | @Override
214 | public void run() {
215 | if(mAllowLoad){
216 | mListener.onImageLoad(mt, d);
217 | }
218 | }
219 | });
220 | return;
221 | }
222 | }
223 | try {
224 | final Drawable d = loadImageFromDisk(localeImagePath , 100);
225 | if(d != null){
226 | imageCache.put(localeImagePath, new SoftReference(d));
227 | }
228 | handler.post(new Runnable() {
229 | @Override
230 | public void run() {
231 | if(mAllowLoad){
232 | mListener.onImageLoad(mt, d);
233 | }
234 | }
235 | });
236 | } catch (Exception e) {
237 | handler.post(new Runnable() {
238 | @Override
239 | public void run() {
240 | mListener.onError(mt);
241 | }
242 | });
243 | Log.e(tag, Log.getStackTraceString(e));
244 | }
245 | }
246 |
247 | public Drawable loadImageFromDisk(String path , int requiredSize) throws Exception {
248 | if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
249 | return decodeFile(path , requiredSize);
250 | else
251 | return null;
252 | }
253 |
254 | private Drawable decodeFile(String path , int requiredSize) throws FileNotFoundException {
255 | // Decode image size
256 | File f = new File(path);
257 | if(!f.exists())
258 | return null;
259 | BitmapFactory.Options o = new BitmapFactory.Options();
260 | o.inJustDecodeBounds = true;
261 | BitmapFactory.decodeStream(new FileInputStream(f), null, o);
262 |
263 | // The new size we want to scale to
264 |
265 | // Find the correct scale value. It should be the power of 2.
266 | int scale = 1;
267 | while (o.outWidth / scale / 2 >= requiredSize
268 | && o.outHeight / scale / 2 >= requiredSize)
269 | scale *= 2;
270 |
271 | // Decode with inSampleSize
272 | // BitmapFactory.Options o2 = new BitmapFactory.Options();
273 | o.inJustDecodeBounds = false;
274 | o.inSampleSize = scale;
275 | Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(f),
276 | null, o);
277 | o = null;
278 | return new BitmapDrawable(bitmap);
279 | }
280 | }
281 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/LocaleFileBrowser.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import java.io.File;
4 | import java.util.ArrayList;
5 | import java.util.Collections;
6 | import java.util.List;
7 |
8 | import android.content.Intent;
9 | import android.graphics.drawable.Drawable;
10 | import android.os.Bundle;
11 | import android.os.Environment;
12 | import android.util.Log;
13 | import android.view.Menu;
14 | import android.view.MenuItem;
15 | import android.view.View;
16 | import android.widget.AbsListView;
17 | import android.widget.AdapterView;
18 | import android.widget.AdapterView.OnItemClickListener;
19 | import android.widget.Button;
20 | import android.widget.CheckBox;
21 | import android.widget.ImageView;
22 | import android.widget.ListView;
23 | import android.widget.TextView;
24 |
25 | import com.tracy.fileexplorer.util.FileUtils;
26 |
27 |
28 | /***
29 | * 本地文件 浏览器
30 | * 可以由外部传入一个dir path
31 | *
32 | * @author zhanglei
33 | *
34 | */
35 | public class LocaleFileBrowser extends BaseActivity implements OnItemClickListener {
36 | private String tag = "LocaleFileBrowser";
37 | private File curFile;//当前目录
38 | private String startPath;//初始path
39 | private TextView curDir;
40 | private ListView lv;
41 | private List data;
42 | private LocaleFileAdapter adapter;
43 | private TextView emptyView;
44 | private FileManager bfm;
45 | private TextView localefile_bottom_tv;
46 | private Button localefile_bottom_btn;
47 |
48 | private SyncImageLoader.OnImageLoadListener imageLoadListener;
49 | private SyncImageLoader syncImageLoader;
50 | private AbsListView.OnScrollListener onScrollListener;
51 |
52 | private int firstImageFileIndex;//第一个图片文件的index(滚动时只对于普通文件loadImage)
53 |
54 | @Override
55 | protected void onCreate(Bundle savedInstanceState) {
56 | // TODO Auto-generated method stub
57 | super.onCreate(savedInstanceState);
58 | setContentView(R.layout.localefile_browser);
59 | bfm = FileManager.getInstance();
60 | initViews();
61 | initData();
62 | onFileClick();
63 | }
64 |
65 | private void initData() {
66 | // TODO Auto-generated method stub
67 | Intent intent = getIntent();
68 | setTitle(intent.getStringExtra("title"));
69 | startPath = intent.getStringExtra("startPath");
70 | if(!FileUtils.isDir(startPath)){
71 | startPath = Environment.getExternalStorageDirectory().getAbsolutePath();
72 | }
73 | syncImageLoader = new SyncImageLoader();
74 | imageLoadListener= new SyncImageLoader.OnImageLoadListener() {
75 | @Override
76 | public void onImageLoad(Integer t, Drawable drawable) {
77 | View view = lv.findViewWithTag(t);
78 | if (view != null) {
79 | ImageView iv = (ImageView) view
80 | .findViewById(R.id.fileType);
81 | iv.setImageDrawable(drawable);
82 | }else{
83 | Log.i(tag, "View not exists");
84 | }
85 | }
86 |
87 | @Override
88 | public void onError(Integer t) {
89 | View view = lv.findViewWithTag(t);
90 | if (view != null) {
91 | ImageView iv = (ImageView) view
92 | .findViewById(R.id.fileType);
93 | iv.setImageResource(R.drawable.bxfile_file_unknow);
94 | }else{
95 | Log.i(tag, " onError View not exists");
96 | }
97 | }
98 | };
99 | onScrollListener = new AbsListView.OnScrollListener() {
100 | @Override
101 | public void onScrollStateChanged(AbsListView view, int scrollState) {
102 | switch (scrollState) {
103 | case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
104 | syncImageLoader.lock();
105 | break;
106 | case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
107 | loadImage();
108 | break;
109 | case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
110 | syncImageLoader.lock();
111 | break;
112 | default:
113 | break;
114 | }
115 | }
116 |
117 | @Override
118 | public void onScroll(AbsListView view, int firstVisibleItem,
119 | int visibleItemCount, int totalItemCount) {
120 |
121 | }
122 | };
123 | setData(startPath);
124 | }
125 |
126 | //在文件夹区域,不用load
127 | public void loadImage() {
128 | int start = lv.getFirstVisiblePosition();
129 | int end = lv.getLastVisiblePosition();
130 | if(end= data.size()) {
137 | end = data.size() - 1;
138 | }
139 | // Log.i(tag, "loadImage start:"+start+" , end:"+end);
140 | syncImageLoader.setLoadLimit(start, end);
141 | syncImageLoader.unlock();
142 | }
143 |
144 | private void setData(String dirPath){
145 | curDir.setText(dirPath);
146 | curFile = new File(dirPath);
147 | File[] childs = curFile.listFiles();
148 | if(null == childs || 0==childs.length){
149 | lv.setVisibility(View.GONE);
150 | emptyView.setVisibility(View.VISIBLE);
151 | }else{
152 | lv.setVisibility(View.VISIBLE);
153 | emptyView.setVisibility(View.GONE);
154 | if(null!=data)
155 | data.clear();
156 | else
157 | data = new ArrayList();
158 | for(File f:childs){
159 | TFile.Builder builder = new TFile.Builder(f.getAbsolutePath());
160 | TFile bxfile = builder.build();
161 | if(null != bxfile)
162 | data.add(bxfile);
163 | }
164 | Collections.sort(data);
165 | initFirstFileIndex();
166 | if(null == adapter){
167 | syncImageLoader.restore();
168 | adapter = new LocaleFileAdapter(data,this,syncImageLoader,imageLoadListener);
169 | lv.setAdapter(adapter);
170 | lv.setOnScrollListener(onScrollListener);
171 | loadImage();
172 | }else{
173 | syncImageLoader.restore();
174 | loadImage();
175 | adapter.notifyDataSetChanged();
176 | lv.setSelection(0);
177 | }
178 | }
179 | }
180 |
181 | //找到第一个图片类型文件index
182 | private void initFirstFileIndex(){
183 | firstImageFileIndex = -1;
184 | for(int i=0;i arg0, View view, int pos, long arg3) {
233 | TFile bxfile = data.get(pos);
234 | if(bxfile.isDir()){
235 | setData(bxfile.getFilePath());
236 | }else{
237 | if(bxfile.isFileSizeValid()){
238 | List choosedFiles = bfm.getChoosedFiles();
239 | CheckBox fileCheckBox = (CheckBox) view.findViewById(R.id.fileCheckBox);
240 | if(choosedFiles.contains(bxfile)){
241 | choosedFiles.remove(bxfile);
242 | fileCheckBox.setChecked(false);
243 | }else{
244 | if(bfm.isOverMaxCnt()){
245 | showToast(R.string.maxFileCntWarn);
246 | return ;
247 | }else{
248 | choosedFiles.add(bxfile);
249 | fileCheckBox.setChecked(true);
250 | }
251 | }
252 | onFileClick();
253 | }else{
254 | showToast(R.string.maxFileSizeWarn);
255 | }
256 | }
257 | }
258 |
259 | //点击文件,触发ui更新
260 | //onResume,触发ui更新
261 | private void onFileClick() {
262 | localefile_bottom_tv.setText(bfm.getFilesSizes());
263 | int cnt = bfm.getFilesCnt();
264 | localefile_bottom_btn.setText(String.format(getString(R.string.bxfile_choosedCnt), cnt));
265 | localefile_bottom_btn.setEnabled(cnt>0);
266 | }
267 |
268 | //退到初始目录,finish() , else显示上级目录
269 | @Override
270 | public void onBackPressed() {
271 | if(startPath.equals(curFile.getAbsolutePath())){
272 | super.onBackPressed();
273 | }else{
274 | setData(curFile.getParentFile().getAbsolutePath());
275 | }
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/LocaleFileGallery.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer;
2 |
3 | import java.util.List;
4 |
5 | import android.graphics.drawable.Drawable;
6 | import android.os.Bundle;
7 | import android.os.Handler;
8 | import android.os.Message;
9 | import android.provider.MediaStore;
10 | import android.util.Log;
11 | import android.view.LayoutInflater;
12 | import android.view.Menu;
13 | import android.view.MenuItem;
14 | import android.view.View;
15 | import android.view.ViewGroup;
16 | import android.widget.AbsListView;
17 | import android.widget.AdapterView;
18 | import android.widget.AdapterView.OnItemClickListener;
19 | import android.widget.BaseAdapter;
20 | import android.widget.Button;
21 | import android.widget.GridView;
22 | import android.widget.ImageView;
23 | import android.widget.TextView;
24 |
25 | import com.tracy.fileexplorer.util.Utils;
26 |
27 |
28 | /***
29 | * 本地图片浏览
30 | *
31 | * @author zhanglei
32 | *
33 | */
34 | public class LocaleFileGallery extends BaseActivity implements OnItemClickListener {
35 |
36 | private String tag = "LocaleFileGallery";
37 | private GridView gv;
38 | private MyGVAdapter adapter;
39 | private List data;
40 | private TextView emptyView;
41 | private FileManager bfm;
42 | private TextView localefile_bottom_tv;
43 | private Button localefile_bottom_btn;
44 |
45 | private List choosedFiles;
46 | private SyncImageLoader syncImageLoader;
47 | private int gridSize;
48 | private AbsListView.LayoutParams gridItemParams;//主要根据不同分辨率设置item宽高
49 | private Handler handler = new Handler(){
50 | @Override
51 | public void handleMessage(Message msg) {
52 | // TODO Auto-generated method stub
53 | if(1 == msg.what){
54 | syncImageLoader = new SyncImageLoader();
55 | choosedFiles = bfm.getChoosedFiles();
56 | gridItemParams = new AbsListView.LayoutParams(gridSize,gridSize);
57 | adapter = new MyGVAdapter();
58 | gv.setAdapter(adapter);
59 | gv.setOnScrollListener(adapter.onScrollListener);
60 | gv.setOnItemClickListener(LocaleFileGallery.this);
61 | }else if(0 == msg.what){
62 | gv.setVisibility(View.GONE);
63 | emptyView.setVisibility(View.VISIBLE);
64 | emptyView.setText(getString(R.string.curCatagoryNoFiles));
65 | }
66 | super.handleMessage(msg);
67 | }
68 | };
69 |
70 | @Override
71 | protected void onCreate(Bundle savedInstanceState) {
72 | super.onCreate(savedInstanceState);
73 | setContentView(R.layout.localefile_gallery);
74 | setTitle(getIntent().getStringExtra("title"));
75 | bfm = FileManager.getInstance();
76 | gv = (GridView) findViewById(R.id.gridView);
77 | emptyView = (TextView) findViewById(R.id.emptyView);
78 | localefile_bottom_btn = (Button) findViewById(R.id.localefile_bottom_btn);
79 | localefile_bottom_tv = (TextView) findViewById(R.id.localefile_bottom_tv);
80 | //计算一下在不同分辨率下gridItem应该站的宽度,在adapter里重置一下item宽高
81 | gridSize = (Utils.getScreenWidth(this) - getResources().getDimensionPixelSize(R.dimen.view_8dp)*5)/4 ;// 4列3个间隔,加上左右padding,共计5个
82 | // Log.i(tag, "gridSize:"+gridSize);
83 | onFileClick();
84 | }
85 |
86 | @Override
87 | protected void onResume() {
88 | // TODO Auto-generated method stub
89 | super.onResume();
90 | if(null == data){
91 | FEApplication bxApp = (FEApplication) getApplication();
92 | bxApp.execRunnable(new Runnable(){
93 | @Override
94 | public void run() {
95 | // TODO Auto-generated method stub
96 | data = bfm.getMediaFiles(LocaleFileGallery.this, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
97 | if(null!=data)
98 | handler.sendEmptyMessage(1);
99 | else
100 | handler.sendEmptyMessage(0);
101 | }
102 |
103 | });
104 | }
105 | }
106 |
107 | //点击文件,触发ui更新
108 | //onResume,触发ui更新
109 | private void onFileClick() {
110 | localefile_bottom_tv.setText(bfm.getFilesSizes());
111 | int cnt = bfm.getFilesCnt();
112 | localefile_bottom_btn.setText(String.format(getString(R.string.bxfile_choosedCnt), cnt));
113 | localefile_bottom_btn.setEnabled(cnt>0);
114 | }
115 |
116 | @Override
117 | protected void onDestroy() {
118 | // TODO Auto-generated method stub
119 | if(null!=data)
120 | data.clear();
121 | syncImageLoader = null;
122 | handler = null;
123 | data = null;
124 | adapter = null;
125 | super.onDestroy();
126 | }
127 |
128 | public void onClick(View v){
129 | switch(v.getId()){
130 | case R.id.localefile_bottom_btn:
131 | setResult(2);
132 | finish();
133 | break;
134 | }
135 | }
136 |
137 | @Override
138 | public boolean onCreateOptionsMenu(Menu menu) {
139 | // TODO Auto-generated method stub
140 | menu.add(0, 0, 0, getString(R.string.cancel));
141 | return super.onCreateOptionsMenu(menu);
142 | }
143 |
144 | @Override
145 | public boolean onOptionsItemSelected(MenuItem item) {
146 | // TODO Auto-generated method stub
147 | if(0 == item.getItemId()){
148 | setResult(1);
149 | finish();
150 | }
151 | return super.onOptionsItemSelected(item);
152 | }
153 |
154 | class MyGVAdapter extends BaseAdapter{
155 |
156 | AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() {
157 | @Override
158 | public void onScrollStateChanged(AbsListView view, int scrollState) {
159 | switch (scrollState) {
160 | case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
161 | syncImageLoader.lock();
162 | break;
163 | case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
164 | loadImage();
165 | break;
166 | case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
167 | syncImageLoader.lock();
168 | break;
169 | default:
170 | break;
171 | }
172 |
173 | }
174 |
175 | @Override
176 | public void onScroll(AbsListView view, int firstVisibleItem,
177 | int visibleItemCount, int totalItemCount) {
178 |
179 | }
180 | };
181 |
182 | public void loadImage() {
183 | int start = gv.getFirstVisiblePosition();
184 | int end = gv.getLastVisiblePosition();
185 | if (end >= getCount()) {
186 | end = getCount() - 1;
187 | }
188 | syncImageLoader.setLoadLimit(start, end);
189 | syncImageLoader.unlock();
190 | }
191 |
192 | @Override
193 | public int getCount() {
194 | // TODO Auto-generated method stub
195 | if(null!=data)
196 | return data.size();
197 | return 0;
198 | }
199 |
200 | @Override
201 | public Object getItem(int position) {
202 | // TODO Auto-generated method stub
203 | return data.get(position);
204 | }
205 |
206 | @Override
207 | public long getItemId(int position) {
208 | // TODO Auto-generated method stub
209 | return 0;
210 | }
211 |
212 | @Override
213 | public View getView(int position, View convertView, ViewGroup parent) {
214 | // TODO Auto-generated method stub
215 | if(null == convertView){
216 | convertView = LayoutInflater.from(LocaleFileGallery.this).inflate(R.layout.gallery_item, null);
217 | }
218 | ImageView img = (ImageView) convertView.findViewById(R.id.img);
219 | img.setImageResource(R.drawable.bxfile_file_default_pic);
220 | View itemView = convertView.findViewById(R.id.itemView);
221 | //重置宽高
222 | itemView.setLayoutParams(gridItemParams);
223 | TFile bxfile = data.get(position);
224 | img.setTag(position);
225 | syncImageLoader.loadDiskImage(position, bxfile.getFilePath(), imageLoadListener);
226 | View checkView = convertView.findViewById(R.id.checkView);
227 | if(choosedFiles.contains(bxfile)){
228 | checkView.setVisibility(View.VISIBLE);
229 | }else{
230 | checkView.setVisibility(View.GONE);
231 | }
232 | return convertView;
233 | }
234 |
235 |
236 | SyncImageLoader.OnImageLoadListener imageLoadListener = new SyncImageLoader.OnImageLoadListener() {
237 | @Override
238 | public void onImageLoad(Integer t, Drawable drawable) {
239 | View view = gv.findViewWithTag(t);
240 | if (view != null) {
241 | ImageView iv = (ImageView) view
242 | .findViewById(R.id.img);
243 | iv.setImageDrawable(drawable);
244 | }else{
245 | Log.i(tag, "View not exists");
246 | }
247 | }
248 |
249 | @Override
250 | public void onError(Integer t) {
251 | View view = gv.findViewWithTag(t);
252 | if (view != null) {
253 | ImageView iv = (ImageView) view
254 | .findViewById(R.id.img);
255 | iv.setImageResource(R.drawable.bxfile_file_default_pic);
256 | }else{
257 | Log.i(tag, " onError View not exists");
258 | }
259 | }
260 |
261 | };
262 | }
263 |
264 | @Override
265 | public void onItemClick(AdapterView> arg0, View convertView, int pos, long arg3) {
266 | View checkView = convertView.findViewById(R.id.checkView);
267 | TFile bxfile = data.get(pos);
268 | if (bxfile.isFileSizeValid()) {
269 | if (choosedFiles.contains(bxfile)) {
270 | choosedFiles.remove(bxfile);
271 | checkView.setVisibility(View.GONE);
272 | } else {
273 | if (bfm.isOverMaxCnt()) {
274 | showToast(R.string.maxFileCntWarn);
275 | return;
276 | } else {
277 | choosedFiles.add(bxfile);
278 | checkView.setVisibility(View.VISIBLE);
279 | }
280 | }
281 | onFileClick();
282 | } else {
283 | showToast(R.string.maxFileSizeWarn);
284 | }
285 | }
286 |
287 | }
288 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/localefile_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
18 |
19 |
24 |
25 |
29 |
30 |
35 |
36 |
44 |
45 |
49 |
50 |
51 |
56 |
57 |
61 |
62 |
67 |
68 |
76 |
77 |
81 |
82 |
83 |
88 |
89 |
93 |
94 |
99 |
100 |
108 |
109 |
113 |
114 |
115 |
121 |
122 |
126 |
127 |
133 |
134 |
138 |
139 |
140 |
145 |
146 |
150 |
151 |
157 |
158 |
162 |
163 |
164 |
169 |
170 |
174 |
175 |
181 |
182 |
186 |
187 |
188 |
194 |
195 |
199 |
200 |
206 |
207 |
211 |
212 |
213 |
219 |
220 |
224 |
225 |
231 |
232 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tracy/fileexplorer/util/FileUtils.java:
--------------------------------------------------------------------------------
1 | package com.tracy.fileexplorer.util;
2 |
3 | import java.io.File;
4 | import java.util.ArrayList;
5 | import java.util.Arrays;
6 | import java.util.List;
7 |
8 | import android.os.Environment;
9 | import android.text.TextUtils;
10 | import android.util.Log;
11 |
12 | /**
13 | * 文件操作工具包
14 | *
15 | * @author tracyZhang
16 | *
17 | */
18 | public class FileUtils {
19 | static String tag = "FileUtils";
20 |
21 | // /**
22 | // * 写文本文件 在Android系统中,文件保存在 /data/data/PACKAGE_NAME/files 目录下
23 | // *
24 | // * @param context
25 | // * @param msg
26 | // */
27 | // public static void write(Context context, String fileName, String content) {
28 | // if (content == null)
29 | // content = "";
30 | //
31 | // try {
32 | // FileOutputStream fos = context.openFileOutput(fileName,
33 | // Context.MODE_PRIVATE);
34 | // fos.write(content.getBytes());
35 | //
36 | // fos.close();
37 | // } catch (Exception e) {
38 | // Log.e(tag, Log.getStackTraceString(e));
39 | // }
40 | // }
41 |
42 | // /**
43 | // * 读取文本文件
44 | // *
45 | // * @param context
46 | // * @param fileName
47 | // * @return
48 | // */
49 | // public static String read(Context context, String fileName) {
50 | // try {
51 | // FileInputStream in = context.openFileInput(fileName);
52 | // return readInStream(in);
53 | // } catch (Exception e) {
54 | // Log.e(tag, Log.getStackTraceString(e));
55 | // }
56 | // return "";
57 | // }
58 |
59 | // private static String readInStream(FileInputStream inStream) {
60 | // try {
61 | // ByteArrayOutputStream outStream = new ByteArrayOutputStream();
62 | // byte[] buffer = new byte[512];
63 | // int length = -1;
64 | // while ((length = inStream.read(buffer)) != -1) {
65 | // outStream.write(buffer, 0, length);
66 | // }
67 | //
68 | // outStream.close();
69 | // inStream.close();
70 | // return outStream.toString();
71 | // } catch (IOException e) {
72 | // Log.i("FileTest", e.getMessage());
73 | // }
74 | // return null;
75 | // }
76 |
77 | public static File createFile(String folderPath, String fileName) {
78 | File destDir = new File(folderPath);
79 | if (!destDir.exists()) {
80 | destDir.mkdirs();
81 | }
82 | return new File(folderPath, fileName + fileName);
83 | }
84 |
85 | // /**
86 | // * 向手机写图片
87 | // *
88 | // * @param buffer
89 | // * @param folder
90 | // * @param fileName
91 | // * @return
92 | // */
93 | // public static boolean writeFile(byte[] buffer, String folder,
94 | // String fileName) {
95 | // boolean writeSucc = false;
96 | //
97 | // boolean sdCardExist = Environment.getExternalStorageState().equals(
98 | // android.os.Environment.MEDIA_MOUNTED);
99 | //
100 | // String folderPath = "";
101 | // if (sdCardExist) {
102 | // folderPath = Environment.getExternalStorageDirectory()
103 | // + File.separator + folder + File.separator;
104 | // } else {
105 | // writeSucc = false;
106 | // }
107 | //
108 | // File fileDir = new File(folderPath);
109 | // if (!fileDir.exists()) {
110 | // fileDir.mkdirs();
111 | // }
112 | //
113 | // File file = new File(folderPath + fileName);
114 | // FileOutputStream out = null;
115 | // try {
116 | // out = new FileOutputStream(file);
117 | // out.write(buffer);
118 | // writeSucc = true;
119 | // } catch (Exception e) {
120 | // Log.e(tag, Log.getStackTraceString(e));
121 | // } finally {
122 | // try {
123 | // out.close();
124 | // } catch (IOException e) {
125 | // Log.e(tag, Log.getStackTraceString(e));
126 | // }
127 | // }
128 | //
129 | // return writeSucc;
130 | // }
131 |
132 | // /**
133 | // * 根据文件绝对路径获取文件名
134 | // *
135 | // * @param filePath
136 | // * @return
137 | // */
138 | // public static String getFileName(String filePath) {
139 | // if (TextUtils.isEmpty(filePath))
140 | // return "";
141 | // return filePath.substring(filePath.lastIndexOf(File.separator) + 1);
142 | // }
143 |
144 | // /**
145 | // * 根据文件的绝对路径获取文件名但不包含扩展名
146 | // *
147 | // * @param filePath
148 | // * @return
149 | // */
150 | // public static String getFileNameNoFormat(String filePath) {
151 | // if (TextUtils.isEmpty(filePath)) {
152 | // return "";
153 | // }
154 | // int point = filePath.lastIndexOf('.');
155 | // return filePath.substring(filePath.lastIndexOf(File.separator) + 1,
156 | // point);
157 | // }
158 |
159 | /**
160 | * 获取文件扩展名
161 | *
162 | * @param fileName
163 | * @return
164 | */
165 | public static String getFileFormat(String fileName) {
166 | if (TextUtils.isEmpty(fileName))
167 | return "";
168 |
169 | int point = fileName.lastIndexOf('.');
170 | return fileName.substring(point + 1);
171 | }
172 |
173 | // /**
174 | // * 获取文件大小
175 | // *
176 | // * @param filePath
177 | // * @return
178 | // */
179 | // public static long getFileSize(String filePath) {
180 | // long size = 0;
181 | //
182 | // File file = new File(filePath);
183 | // if (file != null && file.exists()) {
184 | // size = file.length();
185 | // }
186 | // return size;
187 | // }
188 |
189 | /**
190 | * 获取文件大小
191 | *
192 | * @param size
193 | * 字节
194 | * @return
195 | */
196 | public static String getFileSizeStr(long size) {
197 | if (size <= 0)
198 | return "0.0B";
199 | java.text.DecimalFormat df = new java.text.DecimalFormat("##.##");
200 | float temp = (float) size / 1024;
201 | if (temp >= 1024) {
202 | return df.format(temp / 1024) + "M";
203 | } else {
204 | return df.format(temp) + "K";
205 | }
206 | }
207 |
208 | // /**
209 | // * 转换文件大小
210 | // *
211 | // * @param fileS
212 | // * @return B/KB/MB/GB
213 | // */
214 | // public static String formatFileSize(long fileS) {
215 | // java.text.DecimalFormat df = new java.text.DecimalFormat("#.00");
216 | // String fileSizeString = "";
217 | // if (fileS < 1024) {
218 | // fileSizeString = df.format((double) fileS) + "B";
219 | // } else if (fileS < 1048576) {
220 | // fileSizeString = df.format((double) fileS / 1024) + "KB";
221 | // } else if (fileS < 1073741824) {
222 | // fileSizeString = df.format((double) fileS / 1048576) + "MB";
223 | // } else {
224 | // fileSizeString = df.format((double) fileS / 1073741824) + "G";
225 | // }
226 | // return fileSizeString;
227 | // }
228 |
229 | // /**
230 | // * 获取目录文件大小
231 | // *
232 | // * @param dir
233 | // * @return
234 | // */
235 | // public static long getDirSize(File dir) {
236 | // if (dir == null) {
237 | // return 0;
238 | // }
239 | // if (!dir.isDirectory()) {
240 | // return 0;
241 | // }
242 | // long dirSize = 0;
243 | // File[] files = dir.listFiles();
244 | // for (File file : files) {
245 | // if (file.isFile()) {
246 | // dirSize += file.length();
247 | // } else if (file.isDirectory()) {
248 | // dirSize += file.length();
249 | // dirSize += getDirSize(file); // 递归调用继续统计
250 | // }
251 | // }
252 | // return dirSize;
253 | // }
254 |
255 | // /**
256 | // * 获取目录文件个数
257 | // *
258 | // * @param f
259 | // * @return
260 | // */
261 | // public long getFileList(File dir) {
262 | // long count = 0;
263 | // File[] files = dir.listFiles();
264 | // count = files.length;
265 | // for (File file : files) {
266 | // if (file.isDirectory()) {
267 | // count = count + getFileList(file);// 递归
268 | // count--;
269 | // }
270 | // }
271 | // return count;
272 | // }
273 |
274 | // public static byte[] toBytes(InputStream in) throws IOException {
275 | // ByteArrayOutputStream out = new ByteArrayOutputStream();
276 | // int ch;
277 | // while ((ch = in.read()) != -1) {
278 | // out.write(ch);
279 | // }
280 | // byte buffer[] = out.toByteArray();
281 | // out.close();
282 | // return buffer;
283 | // }
284 |
285 | // /**
286 | // * 检查文件是否存在
287 | // *
288 | // * @param name
289 | // * @return
290 | // */
291 | // public static boolean checkFileExists(String name) {
292 | // boolean status;
293 | // if (!name.equals("")) {
294 | // File path = Environment.getExternalStorageDirectory();
295 | // File newPath = new File(path.toString() + name);
296 | // status = newPath.exists();
297 | // } else {
298 | // status = false;
299 | // }
300 | // return status;
301 | // }
302 |
303 | // /**
304 | // * 检查路径是否存在
305 | // *
306 | // * @param path
307 | // * @return
308 | // */
309 | // public static boolean checkFilePathExists(String path) {
310 | // return new File(path).exists();
311 | // }
312 |
313 | // /**
314 | // * 计算SD卡的剩余空间
315 | // *
316 | // * @return 返回-1,说明没有安装sd卡
317 | // */
318 | // public static long getFreeDiskSpace() {
319 | // String status = Environment.getExternalStorageState();
320 | // long freeSpace = 0;
321 | // if (status.equals(Environment.MEDIA_MOUNTED)) {
322 | // try {
323 | // File path = Environment.getExternalStorageDirectory();
324 | // StatFs stat = new StatFs(path.getPath());
325 | // long blockSize = stat.getBlockSize();
326 | // long availableBlocks = stat.getAvailableBlocks();
327 | // freeSpace = availableBlocks * blockSize / 1024;
328 | // } catch (Exception e) {
329 | // Log.e(tag, Log.getStackTraceString(e));
330 | // }
331 | // } else {
332 | // return -1;
333 | // }
334 | // return (freeSpace);
335 | // }
336 |
337 | // /**
338 | // * 新建目录
339 | // *
340 | // * @param directoryName
341 | // * @return
342 | // */
343 | // public static boolean createDirectory(String directoryName) {
344 | // boolean status;
345 | // if (!directoryName.equals("")) {
346 | // File path = Environment.getExternalStorageDirectory();
347 | // File newPath = new File(path.toString() + directoryName);
348 | // status = newPath.mkdir();
349 | // status = true;
350 | // } else
351 | // status = false;
352 | // return status;
353 | // }
354 |
355 | // /**
356 | // * 检查是否安装SD卡
357 | // *
358 | // * @return
359 | // */
360 | // public static boolean checkSaveLocationExists() {
361 | // String sDCardStatus = Environment.getExternalStorageState();
362 | // boolean status;
363 | // if (sDCardStatus.equals(Environment.MEDIA_MOUNTED)) {
364 | // status = true;
365 | // } else
366 | // status = false;
367 | // return status;
368 | // }
369 |
370 | // /**
371 | // * 删除目录(包括:目录里的所有文件)
372 | // *
373 | // * @param fileName
374 | // * @return
375 | // */
376 | // public static boolean deleteDirectory(String fileName) {
377 | // boolean status;
378 | // SecurityManager checker = new SecurityManager();
379 | //
380 | // if (!fileName.equals("")) {
381 | //
382 | // File path = Environment.getExternalStorageDirectory();
383 | // File newPath = new File(path.toString() + fileName);
384 | // checker.checkDelete(newPath.toString());
385 | // if (newPath.isDirectory()) {
386 | // String[] listfile = newPath.list();
387 | // // delete all files within the specified directory and then
388 | // // delete the directory
389 | // try {
390 | // for (int i = 0; i < listfile.length; i++) {
391 | // File deletedFile = new File(newPath.toString() + "/"
392 | // + listfile[i].toString());
393 | // deletedFile.delete();
394 | // }
395 | // newPath.delete();
396 | // Log.i("DirectoryManager deleteDirectory", fileName);
397 | // status = true;
398 | // } catch (Exception e) {
399 | // Log.e(tag, Log.getStackTraceString(e));
400 | // status = false;
401 | // }
402 | //
403 | // } else
404 | // status = false;
405 | // } else
406 | // status = false;
407 | // return status;
408 | // }
409 |
410 | // /**
411 | // * 删除文件
412 | // *
413 | // * @param fileName
414 | // * @return
415 | // */
416 | // public static boolean deleteFile(String fileName) {
417 | // boolean status;
418 | // SecurityManager checker = new SecurityManager();
419 | //
420 | // if (!fileName.equals("")) {
421 | //
422 | // File path = Environment.getExternalStorageDirectory();
423 | // File newPath = new File(path.toString() + fileName);
424 | // checker.checkDelete(newPath.toString());
425 | // if (newPath.isFile()) {
426 | // try {
427 | // Log.i("DirectoryManager deleteFile", fileName);
428 | // newPath.delete();
429 | // status = true;
430 | // } catch (SecurityException se) {
431 | // sLog.e(tag, Log.getStackTraceString(e));
432 | // status = false;
433 | // }
434 | // } else
435 | // status = false;
436 | // } else
437 | // status = false;
438 | // return status;
439 | // }
440 |
441 | // /**
442 | // * 删除空目录
443 | // *
444 | // * 返回 0代表成功 ,1 代表没有删除权限, 2代表不是空目录,3 代表未知错误
445 | // *
446 | // * @return
447 | // */
448 | // public static int deleteBlankPath(String path) {
449 | // File f = new File(path);
450 | // if (!f.canWrite()) {
451 | // return 1;
452 | // }
453 | // if (f.list() != null && f.list().length > 0) {
454 | // return 2;
455 | // }
456 | // if (f.delete()) {
457 | // return 0;
458 | // }
459 | // return 3;
460 | // }
461 |
462 | // /**
463 | // * 重命名
464 | // *
465 | // * @param oldName
466 | // * @param newName
467 | // * @return
468 | // */
469 | // public static boolean reNamePath(String oldName, String newName) {
470 | // File f = new File(oldName);
471 | // return f.renameTo(new File(newName));
472 | // }
473 |
474 | // /**
475 | // * 删除文件
476 | // *
477 | // * @param filePath
478 | // */
479 | // public static boolean deleteFileWithPath(String filePath) {
480 | // SecurityManager checker = new SecurityManager();
481 | // File f = new File(filePath);
482 | // checker.checkDelete(filePath);
483 | // if (f.isFile()) {
484 | // Log.i("DirectoryManager deleteFile", filePath);
485 | // f.delete();
486 | // return true;
487 | // }
488 | // return false;
489 | // }
490 |
491 | // /**
492 | // * 获取SD卡的根目录,末尾带\
493 | // *
494 | // * @return
495 | // */
496 | // public static String getSDRoot() {
497 | // return Environment.getExternalStorageDirectory().getAbsolutePath()
498 | // + File.separator;
499 | // }
500 |
501 | /**
502 | * 列出root目录下所有子目录
503 | *
504 | * @param path
505 | * @return 绝对路径
506 | */
507 | public static List listPath(String root) {
508 | List allDir = new ArrayList();
509 | SecurityManager checker = new SecurityManager();
510 | File path = new File(root);
511 | checker.checkRead(root);
512 | if (path.isDirectory()) {
513 | for (File f : path.listFiles()) {
514 | if (f.isDirectory()) {
515 | allDir.add(f.getAbsolutePath());
516 | }
517 | }
518 | }
519 | return allDir;
520 | }
521 |
522 | public static List getChild(String root) {
523 | SecurityManager checker = new SecurityManager();
524 | File path = new File(root);
525 | checker.checkRead(root);
526 | if (path.isDirectory())
527 | return Arrays.asList(path.listFiles());
528 | else
529 | return null;
530 |
531 | }
532 |
533 | /**
534 | * 获取下载文件
535 | *
536 | * @return 文件
537 | * @throws MessageException
538 | * 异常信息
539 | */
540 | public static File getDownloadDir() throws Exception {
541 | File downloadFile = null;
542 | if (Environment.getExternalStorageState().equals(
543 | Environment.MEDIA_MOUNTED)) {
544 | downloadFile = new File(Constants.DOWNLOAD_PATH);
545 | if (!downloadFile.exists()) {
546 | downloadFile.mkdirs();
547 | }
548 | }
549 | if (downloadFile == null) {
550 | throw new Exception("can not make dir");
551 | }
552 | return downloadFile;
553 | }
554 |
555 | public static boolean isFileExist(String filePath) {
556 | File file = new File(filePath);
557 | return file.exists();
558 | }
559 |
560 | public static boolean isDir(String filePath) {
561 | File file = new File(filePath);
562 | return file.exists() && file.isDirectory();
563 | }
564 |
565 | //获取后缀
566 | public static String getExspansion(String fileName){
567 | if(TextUtils.isEmpty(fileName))
568 | return null;
569 | int index = fileName.lastIndexOf(".");
570 | if(-1==index || index==(fileName.length()-1))
571 | return null;
572 | return fileName.substring(index);
573 | }
574 |
575 | public static void prepareFile(String filePath) {
576 | File file = new File(filePath);
577 | if (!file.exists()) {
578 | file.mkdirs();
579 | }
580 | }
581 |
582 | public static void delete(String filePath) {
583 | if (filePath == null) {
584 | return;
585 | }
586 | try {
587 | File file = new File(filePath);
588 | if (file == null || !file.exists()) {
589 | return;
590 | }
591 | if (file.isDirectory()) {
592 | deleteDirRecursive(file);
593 | } else {
594 | file.delete();
595 | }
596 | } catch (Exception e) {
597 | Log.e(tag, e.toString());
598 | }
599 | }
600 |
601 | /*
602 | * 递归删除目录
603 | */
604 | public static void deleteDirRecursive(File dir) {
605 | if (dir == null || !dir.exists() || !dir.isDirectory()) {
606 | return;
607 | }
608 | File[] files = dir.listFiles();
609 | if (files == null) {
610 | return;
611 | }
612 | for (File f : files) {
613 | if (f.isFile()) {
614 | f.delete();
615 | } else {
616 | deleteDirRecursive(f);
617 | }
618 | }
619 | dir.delete();
620 | }
621 |
622 | /**
623 | * 判断SD卡是否已经准备好
624 | *
625 | * @return 是否有SDCARD
626 | */
627 | public static boolean isSDCardReady() {
628 | return Environment.getExternalStorageState().equals(
629 | Environment.MEDIA_MOUNTED);
630 | }
631 |
632 | /**
633 | * 可扩展卡路径
634 | * @return
635 | */
636 | public static String getExtSdCardPath(){
637 | File file = new File("/mnt/external_sd/");
638 | if(file.exists()){
639 | return file.getAbsolutePath();
640 | }else{
641 | file = new File("/mnt/extSdCard/");
642 | if(file.exists())
643 | return file.getAbsolutePath();
644 | }
645 | return null;
646 | }
647 |
648 | }
--------------------------------------------------------------------------------