├── .gitattributes ├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── z7dream │ │ └── filemanager │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── z7dream │ │ │ └── filemanager │ │ │ ├── Application.java │ │ │ └── MainActivity.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── z7dream │ └── filemanager │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradlew ├── gradlew.bat ├── lib ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── z7dream │ │ └── lib │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── z7dream │ │ │ └── lib │ │ │ ├── callback │ │ │ └── Callback.java │ │ │ ├── db │ │ │ ├── FileDaoImpl.java │ │ │ ├── FileDaoManager.java │ │ │ └── bean │ │ │ │ ├── FileInfo.java │ │ │ │ ├── FileStarInfo.java │ │ │ │ └── FileTypeInfo.java │ │ │ ├── listener │ │ │ └── RecursiveFileObserver.java │ │ │ ├── model │ │ │ ├── Extension.java │ │ │ ├── MagicFileEntity.java │ │ │ └── MagicPicEntity1.java │ │ │ ├── service │ │ │ └── FileUpdatingService.java │ │ │ └── tool │ │ │ ├── CacheManager.java │ │ │ ├── EnumFileType.java │ │ │ ├── FileUtils.java │ │ │ ├── MagicExplorer.java │ │ │ ├── Utils.java │ │ │ └── rx │ │ │ ├── RxBus.java │ │ │ └── RxSchedulersHelper.java │ └── res │ │ ├── drawable-xhdpi │ │ ├── ic_file_audio.png │ │ ├── ic_file_excel.png │ │ ├── ic_file_folder.png │ │ ├── ic_file_launcher.png │ │ ├── ic_file_msg_down.png │ │ ├── ic_file_myfiles.png │ │ ├── ic_file_mytypes.png │ │ ├── ic_file_near30day.png │ │ ├── ic_file_other.png │ │ ├── ic_file_pdf.png │ │ ├── ic_file_pic.png │ │ ├── ic_file_ppt.png │ │ ├── ic_file_qq.png │ │ ├── ic_file_txt.png │ │ ├── ic_file_video.png │ │ ├── ic_file_word.png │ │ ├── ic_file_wps.png │ │ └── ic_file_wx.png │ │ ├── drawable-xxhdpi │ │ ├── ic_file_audio.png │ │ ├── ic_file_excel.png │ │ ├── ic_file_folder.png │ │ ├── ic_file_launcher.png │ │ ├── ic_file_msg_down.png │ │ ├── ic_file_myfiles.png │ │ ├── ic_file_mytypes.png │ │ ├── ic_file_near30day.png │ │ ├── ic_file_other.png │ │ ├── ic_file_pdf.png │ │ ├── ic_file_pic.png │ │ ├── ic_file_ppt.png │ │ ├── ic_file_qq.png │ │ ├── ic_file_txt.png │ │ ├── ic_file_video.png │ │ ├── ic_file_word.png │ │ ├── ic_file_wps.png │ │ └── ic_file_wx.png │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── z7dream │ └── lib │ └── ExampleUnitTest.java └── settings.gradle /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle/ 2 | local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | *build/ 7 | /captures 8 | gradle/ 9 | .idea/ 10 | *.iml 11 | 12 | # Compiled source # 13 | ################### 14 | *xcshareddata 15 | *xcuserdatad/ 16 | *.com 17 | *.class 18 | *.dll 19 | *.exe 20 | *.o 21 | 22 | # Packages # 23 | ############ 24 | # it's better to unpack these files and commit the raw source 25 | # git has its own built in compression methods 26 | *.7z 27 | *.dmg 28 | *.gz 29 | *.iso 30 | *.rar 31 | *.tar 32 | 33 | # Logs and databases # 34 | ###################### 35 | *.log 36 | *.sql 37 | *.sqlite 38 | 39 | # OS generated files # 40 | ###################### 41 | .DS_Store 42 | .DS_Store? 43 | ._* 44 | .Spotlight-V100 45 | .Trashes 46 | ehthumbs.db 47 | Thumbs.db 48 | 49 | /*.hprof 50 | 51 | lib/src/main/java/com/eblog/lib/utils/db/dao/* 52 | lib/objectbox-models/default.json 53 | lib/objectbox-models/default.json.bak 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 文件管理器 2 | #### 说明:针对android系统数据库的文件更新不及时的问题,我写了这个文件管理器,可以对系统中文件的增加删除和移动进行及时监听。
3 | #### 局限性: 4 | 当我们的应用不在栈顶的时候,文件将不再监听。
5 | #### 实现原理: 6 | 由于文件改变后会在上一级文件夹上表现出来:即时间的改变。于是我使用了FileObserver进行递归循环对所有文件夹进行监听。 7 | 第一次应用启动时会做入库操作,这个时间可能会很长(和手机中的文件数量有关),当应用被杀死后的第二次启动依旧会对已更新的文件夹进行入库更新操作。
8 | #### 使用了第三方库: 9 | ``` 10 | dependencies { 11 | 'com.jakewharton:butterknife:8.6.0' 12 | 'io.objectbox:objectbox-android:0.9.13' 13 | 'io.reactivex.rxjava2:rxjava:2.x.y' 14 | 'io.reactivex.rxjava2:rxandroid:2.0.1' 15 | 'com.trello.rxlifecycle2:rxlifecycle:2.1.0' 16 | 'com.trello.rxlifecycle2:rxlifecycle-android:2.1.0' 17 | 'com.trello.rxlifecycle2:rxlifecycle-components:2.1.0' 18 | } 19 | ``` 20 | ##### 截图: 21 | ![](https://github.com/zhangxyfs/FileManager/blob/1.0/screenshots/fileManager-1.0.gif) 22 | ##### 调用: 23 | ###### 使用文件监听: 24 | ```java 25 | public class Application extends MultiDexApplication { 26 | @Override 27 | public void onCreate() { 28 | super.onCreate(); 29 | FileUpdatingService.startService(this); 30 | } 31 | } 32 | ``` 33 | ###### 使用文件管理器:(开发中) 34 | 需要extends BaseAppli.class 35 | 36 | ```java 37 | public class Application extends BaseAppli { 38 | private FileConfig fileConfig; 39 | 40 | private FileConfigCallback configCallback = new FileConfigCallback() { 41 | @Override 42 | public FileConfig getConfig() { 43 | fileConfig.userToken = "123"; 44 | fileConfig.fileBaseTitle = getString(R.string.mine_file_str); 45 | return fileConfig; 46 | } 47 | }; 48 | 49 | @Override 50 | public void onCreate() { 51 | super.onCreate(); 52 | fileConfig = new FileConfig(); 53 | } 54 | 55 | @Override 56 | public boolean isStartFileUpdating() { 57 | return true; 58 | } 59 | 60 | @Override 61 | public FileConfigCallback getFileConfigCallback() { 62 | return configCallback; 63 | } 64 | } 65 | ``` 66 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.z7dream.filemanager" 8 | minSdkVersion 19 9 | targetSdkVersion 26 10 | versionCode 1 11 | versionName "1.0" 12 | multiDexEnabled true 13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | configurations.all { 22 | resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9' 23 | } 24 | } 25 | 26 | dependencies { 27 | compile fileTree(dir: 'libs', include: ['*.jar']) 28 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 29 | exclude group: 'com.android.support', module: 'support-annotations' 30 | }) 31 | compile 'com.android.support:appcompat-v7:26.+' 32 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 33 | testCompile 'junit:junit:4.12' 34 | 35 | 36 | compile project(':lib') 37 | } 38 | -------------------------------------------------------------------------------- /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 D:\software\soft\Android\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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/z7dream/filemanager/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.filemanager; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.z7dream.filemanager", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/java/com/z7dream/filemanager/Application.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.filemanager; 2 | 3 | import android.support.multidex.MultiDexApplication; 4 | 5 | import com.z7dream.lib.service.FileUpdatingService; 6 | 7 | /** 8 | * Created by Z7Dream on 2017/7/25 11:59. 9 | * Email:zhangxyfs@126.com 10 | */ 11 | 12 | public class Application extends MultiDexApplication { 13 | 14 | @Override 15 | public void onCreate() { 16 | super.onCreate(); 17 | FileUpdatingService.startService(this); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/com/z7dream/filemanager/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.filemanager; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.os.Bundle; 5 | 6 | public class MainActivity extends AppCompatActivity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | setContentView(R.layout.activity_main); 12 | 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | FileManager 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/z7dream/filemanager/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.filemanager; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | mavenCentral() 7 | maven { url "http://objectbox.net/beta-repo/" } 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:2.3.3' 11 | classpath 'me.tatarka:gradle-retrolambda:3.3.1' 12 | classpath 'io.objectbox:objectbox-gradle-plugin:0.9.13' 13 | classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0' 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | maven { url 'https://jitpack.io' } 20 | jcenter() 21 | maven { url "http://objectbox.net/beta-repo/" } 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | 29 | ext { 30 | ojectbox_need_version = '0.9.13' 31 | butterknife_need_version = '8.6.0' 32 | rxjava_need_version = '2.x.y' 33 | rxandroid_need_version = '2.0.1' 34 | rxlifecycle_need_version = '2.1.0'//1.0 35 | } 36 | 37 | -------------------------------------------------------------------------------- /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 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /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 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /lib/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'io.objectbox' 3 | apply plugin: 'com.jakewharton.butterknife' 4 | apply plugin: 'me.tatarka.retrolambda' 5 | 6 | android { 7 | compileSdkVersion 26 8 | buildToolsVersion "25.0.2" 9 | 10 | defaultConfig { 11 | minSdkVersion 19 12 | targetSdkVersion 26 13 | versionCode 1 14 | versionName "1.0" 15 | multiDexEnabled true 16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 17 | 18 | } 19 | buildTypes { 20 | release { 21 | minifyEnabled false 22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 23 | } 24 | } 25 | 26 | compileOptions { 27 | sourceCompatibility JavaVersion.VERSION_1_8 28 | targetCompatibility JavaVersion.VERSION_1_8 29 | } 30 | } 31 | 32 | repositories { 33 | jcenter() 34 | maven { url "http://objectbox.net/beta-repo/" } 35 | } 36 | 37 | dependencies { 38 | compile fileTree(dir: 'libs', include: ['*.jar']) 39 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 40 | exclude group: 'com.android.support', module: 'support-annotations' 41 | }) 42 | compile 'com.android.support:appcompat-v7:26.+' 43 | testCompile 'junit:junit:4.12' 44 | 45 | //编译时注解,用于减少代码量 46 | annotationProcessor "com.jakewharton:butterknife-compiler:${butterknife_need_version}" 47 | compile "com.jakewharton:butterknife:${butterknife_need_version}" 48 | 49 | compile "io.objectbox:objectbox-android:${ojectbox_need_version}" 50 | 51 | compile "io.reactivex.rxjava2:rxjava:${rxjava_need_version}" 52 | compile "io.reactivex.rxjava2:rxandroid:${rxandroid_need_version}" 53 | 54 | compile "com.trello.rxlifecycle2:rxlifecycle:${rxlifecycle_need_version}" 55 | compile "com.trello.rxlifecycle2:rxlifecycle-android:${rxlifecycle_need_version}" 56 | compile "com.trello.rxlifecycle2:rxlifecycle-components:${rxlifecycle_need_version}" 57 | } 58 | -------------------------------------------------------------------------------- /lib/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 D:\software\soft\Android\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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /lib/src/androidTest/java/com/z7dream/lib/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.z7dream.lib.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/callback/Callback.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.callback; 2 | 3 | /** 4 | * Created by Z7Dream on 2017/7/25 11:33. 5 | * Email:zhangxyfs@126.com 6 | */ 7 | 8 | public interface Callback { 9 | void callListener(T param); 10 | } -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/db/FileDaoImpl.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.db; 2 | 3 | 4 | import com.z7dream.lib.callback.Callback; 5 | import com.z7dream.lib.db.bean.FileInfo; 6 | import com.z7dream.lib.model.MagicPicEntity1; 7 | import com.z7dream.lib.tool.EnumFileType; 8 | 9 | import java.io.File; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by Z7Dream on 2017/7/5 16:22. 15 | * Email:zhangxyfs@126.com 16 | */ 17 | 18 | public interface FileDaoImpl { 19 | /** 20 | * 添加文件类型 21 | * 22 | * @param typeName 文件类型名字 23 | * @param format 格式 24 | */ 25 | void addFileTypeInfo(String typeName, String format); 26 | 27 | /** 28 | * 文件入库操作 29 | * 30 | * @param folderSize 应该的最小文件数 31 | */ 32 | void toPutFileInStorage(int folderSize); 33 | 34 | /** 35 | * 是否入库完成 36 | * 37 | * @return 38 | */ 39 | boolean isPutFileInStorageSucc(); 40 | 41 | /** 42 | * 根据文件路径查询文件信息 43 | * 44 | * @param filePath 文件路径 45 | * @return 文件信息 46 | */ 47 | FileInfo findFileInfoByPath(String filePath); 48 | 49 | /** 50 | * 添加文件信息 51 | * 52 | * @param f 文件 53 | */ 54 | void addFileInfo(File f); 55 | 56 | /** 57 | * 删除文件信息 58 | * 59 | * @param filePath 文件路径 60 | */ 61 | void removeFileInfo(String filePath); 62 | 63 | /** 64 | * 更新文件信息 65 | * 66 | * @param f 文件 67 | */ 68 | void updateFileInfo(File f); 69 | 70 | /** 71 | * 获取文件类型 72 | * 73 | * @param exc 文件扩展名 74 | * @return 75 | */ 76 | String getFileType(String exc); 77 | 78 | /** 79 | * 是否为需要的文件 80 | * 81 | * @param exc 文件扩展名 82 | * @return 83 | */ 84 | boolean isNeedFile(String exc); 85 | 86 | /** 87 | * 根据文件类型查找 88 | * 89 | * @param enumFileType 文件类型枚举 90 | * @return 91 | */ 92 | List getFileInfoList(EnumFileType enumFileType); 93 | 94 | 95 | /** 96 | * 根据文件类型查找 97 | * 98 | * @param enumFileType 文件类型枚举 99 | * @param likeStr 模糊查询 100 | * @return 101 | */ 102 | List getFileInfoList(EnumFileType enumFileType, String likeStr); 103 | 104 | /** 105 | * 获取qq文件列表 106 | * 107 | * @param enumFileType 文件类型枚举 108 | * @return 109 | */ 110 | List getQQFileInfoList(EnumFileType enumFileType); 111 | 112 | /** 113 | * 获取微信文件列表 114 | * 115 | * @param enumFileType 文件类型枚举 116 | * @return 117 | */ 118 | List getWXFileInfoList(EnumFileType enumFileType); 119 | 120 | /** 121 | * 获取最近30天文件列表 122 | * 123 | * @param enumFileType 文件类型枚举 124 | * @return 125 | */ 126 | List get30DaysFileInfoList(EnumFileType enumFileType); 127 | 128 | /** 129 | * 获取图片文件夹列表 130 | * 131 | * @param callback 132 | */ 133 | void getFilePicFolderList(Callback> callback); 134 | 135 | void destory(); 136 | } 137 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/db/FileDaoManager.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.db; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.z7dream.lib.callback.Callback; 6 | import com.z7dream.lib.db.bean.FileInfo; 7 | import com.z7dream.lib.db.bean.FileInfo_; 8 | import com.z7dream.lib.db.bean.FileStarInfo; 9 | import com.z7dream.lib.db.bean.FileTypeInfo; 10 | import com.z7dream.lib.db.bean.FileTypeInfo_; 11 | import com.z7dream.lib.model.Extension; 12 | import com.z7dream.lib.model.MagicFileEntity; 13 | import com.z7dream.lib.model.MagicPicEntity1; 14 | import com.z7dream.lib.tool.CacheManager; 15 | import com.z7dream.lib.tool.EnumFileType; 16 | import com.z7dream.lib.tool.FileUtils; 17 | import com.z7dream.lib.tool.rx.RxSchedulersHelper; 18 | 19 | import java.io.File; 20 | import java.util.ArrayList; 21 | import java.util.HashMap; 22 | import java.util.List; 23 | import java.util.Map; 24 | import java.util.Stack; 25 | 26 | import io.objectbox.Box; 27 | import io.objectbox.BoxStore; 28 | import io.objectbox.query.QueryBuilder; 29 | import io.reactivex.Observable; 30 | import io.reactivex.ObservableOnSubscribe; 31 | 32 | import static com.z7dream.lib.db.bean.FileInfo_.filePath; 33 | import static com.z7dream.lib.tool.MagicExplorer.HW_SCREEN_SAVER_PATH; 34 | import static com.z7dream.lib.tool.MagicExplorer.QQ_FILE_PATH; 35 | import static com.z7dream.lib.tool.MagicExplorer.QQ_PIC_PATH; 36 | import static com.z7dream.lib.tool.MagicExplorer.SCREENSHOTS_PATH; 37 | import static com.z7dream.lib.tool.MagicExplorer.SYS_CAMERA_PATH; 38 | import static com.z7dream.lib.tool.MagicExplorer.WX_FILE_PATH; 39 | import static com.z7dream.lib.tool.MagicExplorer.WX_PIC_PATH; 40 | 41 | 42 | /** 43 | * Created by Z7Dream on 2017/7/4 11:36. 44 | * Email:zhangxyfs@126.com 45 | */ 46 | 47 | public class FileDaoManager implements FileDaoImpl { 48 | private Box fileInfoBox; 49 | private Box fileTypeInfoBox; 50 | private Box fileStarInfoBox; 51 | private BoxStore boxStore; 52 | 53 | private static final String PUT_IN_STORAGE_PATH = CacheManager.getCachePath(null, CacheManager.CONFIG) + "addAllFile.succ"; 54 | private static final String START_PATH = CacheManager.getSaveFilePath() + File.separator; 55 | 56 | public FileDaoManager(BoxStore boxStore) { 57 | fileInfoBox = boxStore.boxFor(FileInfo.class); 58 | fileTypeInfoBox = boxStore.boxFor(FileTypeInfo.class); 59 | fileStarInfoBox = boxStore.boxFor(FileStarInfo.class); 60 | this.boxStore = boxStore; 61 | } 62 | 63 | /** 64 | * 添加文件类型 65 | * 66 | * @param typeName 文件类型名字 67 | * @param format 格式 68 | */ 69 | @Override 70 | public void addFileTypeInfo(String typeName, String format) { 71 | fileTypeInfoBox.put(new FileTypeInfo(typeName, format)); 72 | } 73 | 74 | /** 75 | * 文件入库操作 76 | */ 77 | @Override 78 | public void toPutFileInStorage(int folderSize) { 79 | initFileType(); 80 | File check = new File(PUT_IN_STORAGE_PATH); 81 | long count = fileInfoBox.query().build().count(); 82 | if (check.exists()) { 83 | if (count > folderSize) { 84 | toUpdateFileInfoDB(); 85 | return; 86 | } 87 | check.delete(); 88 | } 89 | fileInfoBox.removeAll(); 90 | Observable.create((ObservableOnSubscribe>) e -> { 91 | File folder = new File(CacheManager.getSaveFilePath()); 92 | Stack stack = new Stack<>(); 93 | stack.push(folder.getPath()); 94 | List tempFileList = new ArrayList<>(); 95 | 96 | while (!stack.isEmpty()) { 97 | String temp = stack.pop(); 98 | File path = new File(temp); 99 | File[] files = path.listFiles(); 100 | if (null == files) 101 | continue; 102 | for (File f : files) { 103 | // 递归监听目录 104 | if (isNeedToListener(f)) { 105 | if (f.isDirectory()) { 106 | stack.push(f.getAbsolutePath()); 107 | } 108 | FileInfo fileInfo = new FileInfo(); 109 | fileInfo.setFileName(f.getName()); 110 | fileInfo.setFilePath(f.getAbsolutePath()); 111 | fileInfo.setParentPath(f.getParent()); 112 | fileInfo.setExtension(FileUtils.getExtensionName(fileInfo.getFileName())); 113 | fileInfo.setLastModifyTime(f.lastModified()); 114 | fileInfo.setFileSize(f.length()); 115 | fileInfo.setIsFile(f.isFile()); 116 | fileInfo.setFileType(getFileType(fileInfo.getExtension())); 117 | tempFileList.add(fileInfo); 118 | } 119 | } 120 | } 121 | e.onNext(tempFileList); 122 | e.onComplete(); 123 | }).compose(RxSchedulersHelper.io()) 124 | .doOnComplete(check::createNewFile) 125 | .subscribe(list -> boxStore.runInTxAsync(() -> fileInfoBox.put(list), (aVoid, throwable) -> list.clear()) 126 | , Throwable::printStackTrace); 127 | } 128 | 129 | /** 130 | * 是否入库完成 131 | * 132 | * @return 133 | */ 134 | @Override 135 | public boolean isPutFileInStorageSucc() { 136 | return new File(PUT_IN_STORAGE_PATH).exists(); 137 | } 138 | 139 | 140 | /** 141 | * 根据文件路径查询文件信息 142 | * 143 | * @param filePath 144 | * @return 145 | */ 146 | @Override 147 | public FileInfo findFileInfoByPath(String filePath) { 148 | return fileInfoBox.query().equal(FileInfo_.filePath, filePath).build().findUnique(); 149 | } 150 | 151 | /** 152 | * 添加文件信息 153 | * 154 | * @param f 文件 155 | */ 156 | @Override 157 | public void addFileInfo(File f) { 158 | FileInfo fi = findFileInfoByPath(f.getAbsolutePath()); 159 | if (fi == null) { 160 | if (f.isFile() && !isNeedFile(FileUtils.getExtensionName(f.getPath()))) { 161 | return; 162 | } 163 | 164 | FileInfo fileInfo = new FileInfo(); 165 | fileInfo.setFileName(f.getName()); 166 | fileInfo.setFilePath(f.getAbsolutePath()); 167 | fileInfo.setParentPath(f.getParent()); 168 | fileInfo.setExtension(FileUtils.getExtensionName(fileInfo.getFileName())); 169 | fileInfo.setLastModifyTime(f.lastModified()); 170 | fileInfo.setFileSize(f.length()); 171 | fileInfo.setIsFile(f.isFile()); 172 | fileInfo.setFileType(getFileType(fileInfo.getExtension())); 173 | fileInfoBox.put(fileInfo); 174 | } 175 | } 176 | 177 | /** 178 | * 删除文件信息 179 | * 180 | * @param filePath 文件路径 181 | */ 182 | @Override 183 | public void removeFileInfo(String filePath) { 184 | FileInfo fi = findFileInfoByPath(filePath); 185 | if (fi != null) { 186 | fileInfoBox.remove(fi); 187 | } 188 | } 189 | 190 | /** 191 | * 更新文件信息 192 | * 193 | * @param f 文件 194 | */ 195 | @Override 196 | public void updateFileInfo(File f) { 197 | FileInfo fi = findFileInfoByPath(f.getAbsolutePath()); 198 | if (fi != null) { 199 | fi.setFileName(f.getName()); 200 | fi.setFilePath(f.getAbsolutePath()); 201 | fi.setParentPath(f.getParent()); 202 | fi.setExtension(FileUtils.getExtensionName(fi.getFileName())); 203 | fi.setLastModifyTime(f.lastModified()); 204 | fi.setFileSize(f.length()); 205 | fi.setIsFile(f.isFile()); 206 | fi.setFileType(getFileType(fi.getExtension())); 207 | fileInfoBox.put(fi); 208 | } 209 | } 210 | 211 | /** 212 | * 获取文件类型 213 | * 214 | * @param exc 文件扩展名 215 | * @return 216 | */ 217 | @Override 218 | public String getFileType(String exc) { 219 | FileTypeInfo info = fileTypeInfoBox.query().equal(FileTypeInfo_.format, exc.toLowerCase()).build().findFirst(); 220 | if (info == null) { 221 | info = fileTypeInfoBox.query().equal(FileTypeInfo_.typeName, EnumFileType.OTHER.name()).build().findFirst(); 222 | } 223 | if (info != null) { 224 | return info.getTypeName(); 225 | } 226 | return EnumFileType.OTHER.name(); 227 | } 228 | 229 | /** 230 | * 是否为需要的文件 231 | * 232 | * @param exc 文件扩展名 233 | * @return 234 | */ 235 | @Override 236 | public boolean isNeedFile(String exc) { 237 | return fileTypeInfoBox.query().equal(FileTypeInfo_.format, exc.toLowerCase()).build().findFirst() != null; 238 | } 239 | 240 | /** 241 | * 根据文件类型查找 242 | * 243 | * @param enumFileType 244 | * @return 245 | */ 246 | @Override 247 | public List getFileInfoList(EnumFileType enumFileType) { 248 | QueryBuilder queryBuilder = fileInfoBox.query() 249 | .equal(FileInfo_.isFile, true); 250 | 251 | if (enumFileType != EnumFileType.ALL) { 252 | queryBuilder.equal(FileInfo_.fileType, enumFileType.name()); 253 | } 254 | return queryBuilder.build().find(); 255 | } 256 | 257 | /** 258 | * 根据文件类型模糊查找 259 | * 260 | * @param enumFileType 261 | * @return 262 | */ 263 | @Override 264 | public List getFileInfoList(EnumFileType enumFileType, String likeStr) { 265 | QueryBuilder queryBuilder = fileInfoBox.query() 266 | .equal(FileInfo_.isFile, true); 267 | 268 | if (enumFileType != EnumFileType.ALL) { 269 | queryBuilder.equal(FileInfo_.fileType, enumFileType.name()); 270 | } 271 | if (!TextUtils.isEmpty(likeStr)) { 272 | queryBuilder.contains(filePath, likeStr); 273 | } 274 | 275 | return queryBuilder.build().find(); 276 | } 277 | 278 | /** 279 | * 获取qq文件列表 280 | * 281 | * @param enumFileType 文件类型枚举 282 | * @return 283 | */ 284 | @Override 285 | public List getQQFileInfoList(EnumFileType enumFileType) { 286 | QueryBuilder queryBuilder = fileInfoBox.query() 287 | .equal(FileInfo_.isFile, true) 288 | .contains(filePath, QQ_PIC_PATH) 289 | .orderDesc(FileInfo_.lastModifyTime); 290 | 291 | if (enumFileType != EnumFileType.ALL) { 292 | queryBuilder.equal(FileInfo_.fileType, enumFileType.name()); 293 | } 294 | 295 | return queryBuilder.build().find(); 296 | } 297 | 298 | /** 299 | * 获取微信文件列表 300 | * 301 | * @param enumFileType 文件类型枚举 302 | * @return 303 | */ 304 | @Override 305 | public List getWXFileInfoList(EnumFileType enumFileType) { 306 | QueryBuilder queryBuilder = fileInfoBox.query() 307 | .equal(FileInfo_.isFile, true) 308 | .contains(filePath, WX_PIC_PATH) 309 | .orderDesc(FileInfo_.lastModifyTime); 310 | 311 | if (enumFileType != EnumFileType.ALL) { 312 | queryBuilder.equal(FileInfo_.fileType, enumFileType.name()); 313 | } 314 | 315 | return queryBuilder.build().find(); 316 | } 317 | 318 | /** 319 | * 获取最近30天文件列表 320 | * 321 | * @param enumFileType 文件类型枚举 322 | * @return 323 | */ 324 | @Override 325 | public List get30DaysFileInfoList(EnumFileType enumFileType) { 326 | long nowTime = System.currentTimeMillis(); 327 | long needTime = nowTime - (30 * 24 * 60 * 60) * 1000L; 328 | 329 | QueryBuilder queryBuilder = fileInfoBox.query() 330 | .equal(FileInfo_.isFile, true) 331 | .greater(FileInfo_.lastModifyTime, needTime) 332 | .notEqual(FileInfo_.extension, "") 333 | .orderDesc(FileInfo_.lastModifyTime); 334 | 335 | if (enumFileType != EnumFileType.ALL) { 336 | queryBuilder.equal(FileInfo_.fileType, enumFileType.name()); 337 | } 338 | return queryBuilder.build().find(); 339 | } 340 | 341 | /** 342 | * 获取图片文件夹列表 343 | * 344 | * @param callback 345 | */ 346 | @Override 347 | public void getFilePicFolderList(Callback> callback) { 348 | ArrayList dataList = new ArrayList<>(); 349 | Map folderItemPosMap = new HashMap<>(); 350 | List allPicList = new ArrayList<>(); 351 | 352 | String notEquals1 = CacheManager.getCachePath(null, CacheManager.ES); 353 | String notEquals2 = CacheManager.getCachePath(null, CacheManager.PIC); 354 | String notEquals3 = CacheManager.getCachePath(null, CacheManager.PIC_TEMP); 355 | 356 | notEquals1 = notEquals1.endsWith(File.separator) ? notEquals1.substring(0, notEquals1.length() - 1) : notEquals1; 357 | notEquals2 = notEquals2.endsWith(File.separator) ? notEquals2.substring(0, notEquals2.length() - 1) : notEquals2; 358 | notEquals3 = notEquals3.endsWith(File.separator) ? notEquals3.substring(0, notEquals3.length() - 1) : notEquals3; 359 | 360 | List list = fileInfoBox.query() 361 | .equal(FileInfo_.fileType, EnumFileType.PIC.name()) 362 | .equal(FileInfo_.isFile, true) 363 | .notEqual(FileInfo_.parentPath, notEquals1) 364 | .notEqual(FileInfo_.parentPath, notEquals2) 365 | .notEqual(FileInfo_.parentPath, notEquals3) 366 | .orderDesc(FileInfo_.lastModifyTime) 367 | .build().find(); 368 | 369 | Observable.fromIterable(list) 370 | .compose(RxSchedulersHelper.io()) 371 | .doOnComplete(() -> { 372 | MagicPicEntity1 itemEntity = new MagicPicEntity1(); 373 | itemEntity.name = "ALL"; 374 | itemEntity.icon = allPicList.size() > 0 ? allPicList.get(0).path : ""; 375 | itemEntity.path = ""; 376 | itemEntity.childNum = allPicList.size(); 377 | itemEntity.childList = new ArrayList<>(); 378 | itemEntity.childList.addAll(allPicList); 379 | dataList.add(0, itemEntity); 380 | 381 | callback.callListener(dataList); 382 | }) 383 | .subscribe(info -> { 384 | String parentName = FileUtils.getFolderName(info.getParentPath()); 385 | 386 | //生成所有图片 387 | MagicFileEntity allPicChild = new MagicFileEntity(); 388 | allPicChild.name = info.getFileName(); 389 | allPicChild.size = info.getFileSize(); 390 | allPicChild.path = info.getFilePath(); 391 | allPicChild.time = info.getLastModifyTime(); 392 | allPicChild.isFile = true; 393 | allPicList.add(allPicChild); 394 | 395 | if (folderItemPosMap.get(parentName) == null) { 396 | folderItemPosMap.put(parentName, dataList.size()); 397 | } 398 | 399 | if (dataList.size() < folderItemPosMap.get(parentName) + 1) { 400 | MagicPicEntity1 itemEntity = new MagicPicEntity1(); 401 | itemEntity.name = parentName; 402 | itemEntity.icon = info.getFilePath(); 403 | itemEntity.path = info.getParentPath(); 404 | if (TextUtils.equals(parentName, "EB_photo")) { 405 | File file1 = new File(info.getParentPath()); 406 | itemEntity.childNum = file1.list().length; 407 | 408 | itemEntity.childList = new ArrayList<>(); 409 | for (int childPos = 0; childPos < file1.list().length; childPos++) { 410 | File childFile = file1.listFiles()[childPos]; 411 | 412 | MagicFileEntity child = new MagicFileEntity(); 413 | child.name = childFile.getName(); 414 | child.size = childFile.length(); 415 | child.path = childFile.getPath(); 416 | child.time = childFile.lastModified(); 417 | child.isFile = true; 418 | itemEntity.childList.add(child); 419 | } 420 | 421 | itemEntity.icon = itemEntity.childList.get(0).path; 422 | 423 | } else { 424 | itemEntity.childNum = 1; 425 | 426 | itemEntity.childList = new ArrayList<>(); 427 | MagicFileEntity firstChild = new MagicFileEntity(); 428 | firstChild.name = info.getFileName(); 429 | firstChild.size = info.getFileSize(); 430 | firstChild.path = info.getFilePath(); 431 | firstChild.time = info.getLastModifyTime(); 432 | firstChild.isFile = true; 433 | itemEntity.childList.add(firstChild); 434 | } 435 | dataList.add(itemEntity); 436 | } else { 437 | if (!TextUtils.equals(parentName, "EB_photo")) { 438 | dataList.get(folderItemPosMap.get(parentName)).childNum += 1; 439 | 440 | MagicFileEntity child = new MagicFileEntity(); 441 | child.name = info.getFileName(); 442 | child.size = info.getFileSize(); 443 | child.path = info.getFilePath(); 444 | child.time = info.getLastModifyTime(); 445 | child.isFile = true; 446 | dataList.get(folderItemPosMap.get(parentName)).childList.add(child); 447 | } 448 | } 449 | 450 | }, error -> { 451 | }); 452 | } 453 | 454 | @Override 455 | public void destory() { 456 | fileInfoBox = null; 457 | fileTypeInfoBox = null; 458 | fileStarInfoBox = null; 459 | boxStore = null; 460 | } 461 | 462 | 463 | /** 464 | * 初始化 文件类型数据 465 | */ 466 | private void initFileType() { 467 | FileTypeInfo first = fileTypeInfoBox.query().build().findFirst(); 468 | if (first == null) { 469 | List list = new ArrayList<>(); 470 | for (int i = 0; i < Extension.PIC.length; i++) { 471 | FileTypeInfo info = new FileTypeInfo(); 472 | info.setTypeName(EnumFileType.PIC.name()); 473 | info.setFormat(Extension.PIC[i]); 474 | list.add(info); 475 | } 476 | for (int i = 0; i < Extension.TXT.length; i++) { 477 | FileTypeInfo info = new FileTypeInfo(); 478 | info.setTypeName(EnumFileType.TXT.name()); 479 | info.setFormat(Extension.TXT[i]); 480 | list.add(info); 481 | } 482 | for (int i = 0; i < Extension.EXCEL.length; i++) { 483 | FileTypeInfo info = new FileTypeInfo(); 484 | info.setTypeName(EnumFileType.EXCEL.name()); 485 | info.setFormat(Extension.EXCEL[i]); 486 | list.add(info); 487 | } 488 | for (int i = 0; i < Extension.PPT.length; i++) { 489 | FileTypeInfo info = new FileTypeInfo(); 490 | info.setTypeName(EnumFileType.PPT.name()); 491 | info.setFormat(Extension.PPT[i]); 492 | list.add(info); 493 | } 494 | for (int i = 0; i < Extension.WORD.length; i++) { 495 | FileTypeInfo info = new FileTypeInfo(); 496 | info.setTypeName(EnumFileType.WORD.name()); 497 | info.setFormat(Extension.WORD[i]); 498 | list.add(info); 499 | } 500 | for (int i = 0; i < Extension.PDF.length; i++) { 501 | FileTypeInfo info = new FileTypeInfo(); 502 | info.setTypeName(EnumFileType.PDF.name()); 503 | info.setFormat(Extension.PDF[i]); 504 | list.add(info); 505 | } 506 | for (int i = 0; i < Extension.AUDIO.length; i++) { 507 | FileTypeInfo info = new FileTypeInfo(); 508 | info.setTypeName(EnumFileType.AUDIO.name()); 509 | info.setFormat(Extension.AUDIO[i]); 510 | list.add(info); 511 | } 512 | for (int i = 0; i < Extension.VIDEO.length; i++) { 513 | FileTypeInfo info = new FileTypeInfo(); 514 | info.setTypeName(EnumFileType.VIDEO.name()); 515 | info.setFormat(Extension.VIDEO[i]); 516 | list.add(info); 517 | } 518 | for (int i = 0; i < Extension.ZIP.length; i++) { 519 | FileTypeInfo info = new FileTypeInfo(); 520 | info.setTypeName(EnumFileType.ZIP.name()); 521 | info.setFormat(Extension.ZIP[i]); 522 | list.add(info); 523 | } 524 | FileTypeInfo info = new FileTypeInfo(); 525 | info.setTypeName(EnumFileType.OTHER.name()); 526 | info.setFormat(""); 527 | list.add(info); 528 | 529 | fileTypeInfoBox.put(list); 530 | } 531 | } 532 | 533 | /** 534 | * 手动更新数据库数据,仅仅当应用启动时候去做 535 | */ 536 | private void toUpdateFileInfoDB() { 537 | Observable.create((ObservableOnSubscribe>) e -> { 538 | List list = fileInfoBox.query().equal(FileInfo_.isFile, false).orderDesc(FileInfo_.lastModifyTime).build().find(); 539 | List deleteFileInfoIdList = new ArrayList<>(); 540 | List needUpdateFileidList = new ArrayList<>(); 541 | for (FileInfo folderInfo : list) { 542 | File file = new File(folderInfo.getFilePath()); 543 | if (!file.exists()) { 544 | deleteFileInfoIdList.add(folderInfo.getId()); 545 | } else { 546 | if (folderInfo.getLastModifyTime() != file.lastModified()) {//当前文件夹,时间不同,需要更新 547 | needUpdateFileidList.add(folderInfo); 548 | traverseChild(folderInfo.getFilePath(), deleteFileInfoIdList, needUpdateFileidList); 549 | } 550 | } 551 | } 552 | fileInfoBox.removeByKeys(deleteFileInfoIdList); 553 | e.onNext(needUpdateFileidList); 554 | e.onComplete(); 555 | }).compose(RxSchedulersHelper.io()).subscribe(list -> { 556 | boxStore.runInTx(() -> { 557 | for (FileInfo fileInfo : list) { 558 | File f = new File(fileInfo.getFilePath()); 559 | fileInfo.setFileName(f.getName()); 560 | fileInfo.setFilePath(f.getAbsolutePath()); 561 | fileInfo.setParentPath(f.getParent()); 562 | fileInfo.setExtension(FileUtils.getExtensionName(fileInfo.getFileName())); 563 | fileInfo.setLastModifyTime(f.lastModified()); 564 | fileInfo.setFileSize(f.length()); 565 | fileInfo.setIsFile(f.isFile()); 566 | fileInfo.setFileType(getFileType(fileInfo.getExtension())); 567 | } 568 | fileInfoBox.put(list); 569 | }); 570 | }, error -> { 571 | }); 572 | } 573 | 574 | private void traverseChild(String parentPath, List delList, List updateList) { 575 | List childList = fileInfoBox.query().equal(FileInfo_.parentPath, parentPath).build().find(); 576 | for (FileInfo childInfo : childList) { 577 | File file = new File(childInfo.getFilePath()); 578 | if (!file.exists()) { 579 | delList.add(childInfo.getId()); 580 | } else { 581 | if (childInfo.getLastModifyTime() != file.lastModified()) {//当前文件夹,时间不同,需要更新 582 | updateList.add(childInfo); 583 | 584 | if (!childInfo.getIsFile()) { 585 | traverseChild(childInfo.getFilePath(), delList, updateList); 586 | } 587 | } 588 | } 589 | } 590 | } 591 | 592 | private boolean isNeedToListener(File f) { 593 | if (f == null) return false; 594 | String path = f.getAbsolutePath(); 595 | //以下返回必须为false 596 | String fileName = FileUtils.getFolderName(path); 597 | boolean isHidden = fileName.startsWith("_") || fileName.startsWith("."); 598 | boolean isSystem = path.startsWith(START_PATH + "Android") || path.startsWith(START_PATH + "backup") || path.startsWith(START_PATH + "backups") || path.startsWith(START_PATH + "CloudDrive") 599 | || path.startsWith(START_PATH + "huawei") || path.startsWith(START_PATH + "HuaweiBackup") || path.startsWith(START_PATH + "HWThemes") || path.startsWith(START_PATH + "msc") || path.startsWith(START_PATH + "Musiclrc"); 600 | // boolean isRxCache = path.startsWith(START_PATH + "com.eblog" + File.separator + "cache" + File.separator + "rxCache"); 601 | // boolean isSmiley = path.startsWith(START_PATH + "com.eblog" + File.separator + "cache" + File.separator + "smiley"); 602 | // boolean isGlide = path.startsWith(START_PATH + "com.eblog" + File.separator + "cache" + File.separator + "glide"); 603 | // boolean isOSS = path.startsWith(START_PATH + "com.eblog" + File.separator + "cache" + File.separator + "oss_record"); 604 | 605 | //以下返回必须为true 606 | boolean isQQ = path.startsWith(QQ_PIC_PATH) || path.startsWith(QQ_FILE_PATH); 607 | boolean isWX = path.startsWith(WX_PIC_PATH) || path.startsWith(WX_FILE_PATH); 608 | boolean isSysPic = path.startsWith(SYS_CAMERA_PATH) || path.startsWith(SCREENSHOTS_PATH) || path.startsWith(HW_SCREEN_SAVER_PATH); 609 | 610 | //以下部分返回为true 611 | boolean isTencentPath = path.startsWith(START_PATH + "tencent" + File.separator); 612 | 613 | boolean isNeedFile; 614 | if (isHidden || isSystem)//|| isRxCache || isSmiley || isGlide || isOSS) 615 | isNeedFile = false; 616 | else if (isTencentPath) 617 | isNeedFile = isQQ || isWX; 618 | else if (isSysPic) 619 | isNeedFile = true; 620 | else 621 | isNeedFile = true; 622 | 623 | if (isNeedFile && f.isFile()) { 624 | String exc = FileUtils.getExtensionName(f.getName()); 625 | isNeedFile = isNeedFile(exc); 626 | } 627 | 628 | return isNeedFile; 629 | } 630 | } 631 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/db/bean/FileInfo.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.db.bean; 2 | 3 | import io.objectbox.annotation.Entity; 4 | import io.objectbox.annotation.Id; 5 | import io.objectbox.annotation.Index; 6 | import io.objectbox.annotation.Generated; 7 | import io.objectbox.annotation.apihint.Internal; 8 | 9 | /** 10 | * 文件元数据 11 | *

12 | * Created by Z7Dream on 2017/7/4 11:34. 13 | * Email:zhangxyfs@126.com 14 | */ 15 | 16 | @Entity 17 | public class FileInfo { 18 | @Id 19 | private long id; 20 | 21 | private String fileName;//文件名 22 | 23 | @Index 24 | private String filePath;//文件路径 25 | 26 | @Index 27 | private String parentPath;//父文件夹路径 28 | 29 | private String extension;//扩展名 30 | 31 | private long createTime;//创建时间 32 | 33 | @Index 34 | private long lastModifyTime;//最后修改时间 35 | 36 | private long fileSize;//文件大小 37 | 38 | private boolean isFile;//是否文件 39 | 40 | @Index 41 | private String fileType;//文件类型 42 | 43 | @Generated(1546775479) 44 | @Internal 45 | /** This constructor was generated by ObjectBox and may change any time. */ 46 | public FileInfo(long id, String fileName, String filePath, String parentPath, 47 | String extension, long createTime, long lastModifyTime, long fileSize, 48 | boolean isFile, String fileType) { 49 | this.id = id; 50 | this.fileName = fileName; 51 | this.filePath = filePath; 52 | this.parentPath = parentPath; 53 | this.extension = extension; 54 | this.createTime = createTime; 55 | this.lastModifyTime = lastModifyTime; 56 | this.fileSize = fileSize; 57 | this.isFile = isFile; 58 | this.fileType = fileType; 59 | } 60 | 61 | @Generated(1367591352) 62 | public FileInfo() { 63 | } 64 | 65 | public long getId() { 66 | return id; 67 | } 68 | 69 | public void setId(long id) { 70 | this.id = id; 71 | } 72 | 73 | public String getFileName() { 74 | return fileName; 75 | } 76 | 77 | public void setFileName(String fileName) { 78 | this.fileName = fileName; 79 | } 80 | 81 | public String getFilePath() { 82 | return filePath; 83 | } 84 | 85 | public void setFilePath(String filePath) { 86 | this.filePath = filePath; 87 | } 88 | 89 | public String getParentPath() { 90 | return parentPath; 91 | } 92 | 93 | public void setParentPath(String parentPath) { 94 | this.parentPath = parentPath; 95 | } 96 | 97 | public String getExtension() { 98 | return extension; 99 | } 100 | 101 | public void setExtension(String extension) { 102 | this.extension = extension; 103 | } 104 | 105 | public long getCreateTime() { 106 | return createTime; 107 | } 108 | 109 | public void setCreateTime(long createTime) { 110 | this.createTime = createTime; 111 | } 112 | 113 | public long getLastModifyTime() { 114 | return lastModifyTime; 115 | } 116 | 117 | public void setLastModifyTime(long lastModifyTime) { 118 | this.lastModifyTime = lastModifyTime; 119 | } 120 | 121 | public long getFileSize() { 122 | return fileSize; 123 | } 124 | 125 | public void setFileSize(long fileSize) { 126 | this.fileSize = fileSize; 127 | } 128 | 129 | public boolean getIsFile() { 130 | return isFile; 131 | } 132 | 133 | public void setIsFile(boolean isFile) { 134 | this.isFile = isFile; 135 | } 136 | 137 | public String getFileType() { 138 | return fileType; 139 | } 140 | 141 | public void setFileType(String fileType) { 142 | this.fileType = fileType; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/db/bean/FileStarInfo.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.db.bean; 2 | 3 | import io.objectbox.annotation.Entity; 4 | import io.objectbox.annotation.Id; 5 | import io.objectbox.annotation.Generated; 6 | import io.objectbox.annotation.apihint.Internal; 7 | 8 | /** 9 | * 文件星标 10 | *

11 | * Created by Z7Dream on 2017/7/4 13:38. 12 | * Email:zhangxyfs@126.com 13 | */ 14 | @Entity 15 | public class FileStarInfo { 16 | @Id 17 | private long id; 18 | 19 | private long userId;//用户id 20 | 21 | private long fileInfoId;//文件id 22 | 23 | @Generated(52653744) 24 | @Internal 25 | /** This constructor was generated by ObjectBox and may change any time. */ 26 | public FileStarInfo(long id, long userId, long fileInfoId) { 27 | this.id = id; 28 | this.userId = userId; 29 | this.fileInfoId = fileInfoId; 30 | } 31 | 32 | @Generated(298402998) 33 | public FileStarInfo() { 34 | } 35 | 36 | public long getId() { 37 | return id; 38 | } 39 | 40 | public void setId(long id) { 41 | this.id = id; 42 | } 43 | 44 | public long getUserId() { 45 | return userId; 46 | } 47 | 48 | public void setUserId(long userId) { 49 | this.userId = userId; 50 | } 51 | 52 | public long getFileInfoId() { 53 | return fileInfoId; 54 | } 55 | 56 | public void setFileInfoId(long fileInfoId) { 57 | this.fileInfoId = fileInfoId; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/db/bean/FileTypeInfo.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.db.bean; 2 | 3 | import io.objectbox.annotation.Entity; 4 | import io.objectbox.annotation.Id; 5 | import io.objectbox.annotation.Generated; 6 | import io.objectbox.annotation.apihint.Internal; 7 | 8 | /** 9 | * 文件类型:数据固定 10 | *

11 | * Created by Z7Dream on 2017/7/4 11:44. 12 | * Email:zhangxyfs@126.com 13 | */ 14 | @Entity 15 | public class FileTypeInfo { 16 | @Id(assignable = true) 17 | private long id; 18 | 19 | private String typeName;//文件类型名称 20 | 21 | private String format;//格式(扩展名) 22 | 23 | public FileTypeInfo(String typeName, String format) { 24 | this.typeName = typeName; 25 | this.format = format; 26 | } 27 | 28 | @Generated(642009613) 29 | @Internal 30 | /** This constructor was generated by ObjectBox and may change any time. */ 31 | public FileTypeInfo(long id, String typeName, String format) { 32 | this.id = id; 33 | this.typeName = typeName; 34 | this.format = format; 35 | } 36 | 37 | @Generated(1312591050) 38 | public FileTypeInfo() { 39 | } 40 | 41 | public long getId() { 42 | return id; 43 | } 44 | 45 | public void setId(long id) { 46 | this.id = id; 47 | } 48 | 49 | public String getTypeName() { 50 | return typeName; 51 | } 52 | 53 | public void setTypeName(String typeName) { 54 | this.typeName = typeName; 55 | } 56 | 57 | public String getFormat() { 58 | return format; 59 | } 60 | 61 | public void setFormat(String format) { 62 | this.format = format; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/listener/RecursiveFileObserver.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.listener; 2 | 3 | import android.os.FileObserver; 4 | import android.support.v4.util.ArrayMap; 5 | import android.text.TextUtils; 6 | import android.util.Log; 7 | 8 | import com.z7dream.lib.callback.Callback; 9 | import com.z7dream.lib.db.FileDaoImpl; 10 | import com.z7dream.lib.tool.CacheManager; 11 | import com.z7dream.lib.tool.FileUtils; 12 | import com.z7dream.lib.tool.rx.RxSchedulersHelper; 13 | 14 | import java.io.File; 15 | import java.util.Map; 16 | import java.util.Stack; 17 | 18 | import io.reactivex.Observable; 19 | import io.reactivex.ObservableOnSubscribe; 20 | import io.reactivex.disposables.Disposable; 21 | 22 | import static com.z7dream.lib.tool.MagicExplorer.HW_SCREEN_SAVER_PATH; 23 | import static com.z7dream.lib.tool.MagicExplorer.QQ_FILE_PATH; 24 | import static com.z7dream.lib.tool.MagicExplorer.QQ_PIC_PATH; 25 | import static com.z7dream.lib.tool.MagicExplorer.SCREENSHOTS_PATH; 26 | import static com.z7dream.lib.tool.MagicExplorer.SYS_CAMERA_PATH; 27 | import static com.z7dream.lib.tool.MagicExplorer.WX_FILE_PATH; 28 | import static com.z7dream.lib.tool.MagicExplorer.WX_PIC_PATH; 29 | 30 | 31 | /** 32 | * 文件增删改查监听 33 | *

34 | * Created by Z7Dream on 2017/7/3 16:39. 35 | * Email:zhangxyfs@126.com 36 | */ 37 | 38 | public class RecursiveFileObserver extends FileObserver { 39 | private Map mObservers; 40 | private String mPath; 41 | private int mMask; 42 | private static final String START_PATH = CacheManager.getSaveFilePath() + File.separator; 43 | private Callback callback; 44 | private FileDaoImpl fileDaoUtils; 45 | 46 | private Disposable startDisposable, stopDisposable, createDisposable, deleteDisposable; 47 | 48 | public RecursiveFileObserver(String path, Callback callback, FileDaoImpl fileDaoUtils) { 49 | this(path, ALL_EVENTS, callback, fileDaoUtils); 50 | } 51 | 52 | public RecursiveFileObserver(String path, int mask, Callback callback, FileDaoImpl fileDaoUtils) { 53 | super(path, mask); 54 | mPath = path; 55 | mMask = mask; 56 | this.callback = callback; 57 | this.fileDaoUtils = fileDaoUtils; 58 | } 59 | 60 | @Override 61 | public void startWatching() { 62 | if (mObservers == null) { 63 | startDisposable = Observable.create((ObservableOnSubscribe) e -> { 64 | mObservers = new ArrayMap<>(); 65 | Stack stack = new Stack<>(); 66 | stack.push(mPath); 67 | while (!stack.isEmpty()) { 68 | String temp = stack.pop(); 69 | mObservers.put(temp, new SingleFileObserver(temp, mMask)); 70 | File path = new File(temp); 71 | File[] files = path.listFiles(); 72 | if (null == files) 73 | continue; 74 | for (File f : files) { 75 | // 递归监听目录 76 | if (f.isDirectory() && isNeedToListener(f.getPath())) { 77 | stack.push(f.getAbsolutePath()); 78 | } 79 | } 80 | } 81 | for (String key : mObservers.keySet()) { 82 | e.onNext(key); 83 | } 84 | e.onComplete(); 85 | 86 | }).compose(RxSchedulersHelper.io()).doOnComplete(() -> { 87 | startDisposable.dispose(); 88 | startDisposable = null; 89 | callback.callListener(mObservers.size()); 90 | }).subscribe(key -> { 91 | mObservers.get(key).startWatching(); 92 | }, error -> { 93 | }); 94 | } 95 | } 96 | 97 | @Override 98 | public void stopWatching() { 99 | if (mObservers != null) { 100 | stopDisposable = Observable.create((ObservableOnSubscribe) e -> { 101 | for (String key : mObservers.keySet()) { 102 | e.onNext(key); 103 | } 104 | e.onComplete(); 105 | }).compose(RxSchedulersHelper.io()) 106 | .doOnComplete(() -> { 107 | mObservers.clear(); 108 | mObservers = null; 109 | stopDisposable.dispose(); 110 | stopDisposable = null; 111 | 112 | fileDaoUtils = null; 113 | }) 114 | .subscribe(key -> { 115 | mObservers.get(key).stopWatching(); 116 | }, error -> { 117 | }); 118 | } 119 | } 120 | 121 | @Override 122 | public void onEvent(int event, String path) { 123 | File file = new File(path); 124 | int el = event & FileObserver.ALL_EVENTS; 125 | switch (el) { 126 | case FileObserver.ATTRIB: 127 | Log.i("RecursiveFileObserver", "ATTRIB: " + path); 128 | break; 129 | case FileObserver.CREATE: 130 | createDisposable = Observable.create((ObservableOnSubscribe) e -> { 131 | if (file.isDirectory()) { 132 | Stack stack = new Stack<>(); 133 | stack.push(path); 134 | while (!stack.isEmpty()) { 135 | String temp = stack.pop(); 136 | if (mObservers.containsKey(temp)) { 137 | continue; 138 | } else { 139 | SingleFileObserver sfo = new SingleFileObserver(temp, mMask); 140 | e.onNext(sfo); 141 | mObservers.put(temp, sfo); 142 | } 143 | File tempPath = new File(temp); 144 | File[] files = tempPath.listFiles(); 145 | if (null == files) 146 | continue; 147 | for (File f : files) { 148 | // 递归监听目录 149 | if (f.isDirectory() && isNeedToListener(f.getPath())) { 150 | stack.push(f.getAbsolutePath()); 151 | } 152 | } 153 | } 154 | } 155 | e.onComplete(); 156 | }).compose(RxSchedulersHelper.io()) 157 | .doOnComplete(() -> { 158 | createDisposable.dispose(); 159 | createDisposable = null; 160 | }).subscribe(FileObserver::startWatching, error -> { 161 | }); 162 | 163 | fileDaoUtils.addFileInfo(file); 164 | Log.i("RecursiveFileObserver", "CREATE: " + path); 165 | break; 166 | case FileObserver.DELETE: 167 | if (file.isDirectory()) { 168 | mObservers.get(path).stopWatching(); 169 | mObservers.remove(path); 170 | } 171 | fileDaoUtils.removeFileInfo(file.getAbsolutePath()); 172 | 173 | Log.i("RecursiveFileObserver", "DELETE: " + path); 174 | break; 175 | case FileObserver.DELETE_SELF: 176 | if (file.isDirectory()) { 177 | mObservers.get(path).stopWatching(); 178 | mObservers.remove(path); 179 | } 180 | fileDaoUtils.removeFileInfo(file.getAbsolutePath()); 181 | 182 | Log.i("RecursiveFileObserver", "DELETE_SELF: " + path); 183 | break; 184 | case FileObserver.MODIFY: 185 | fileDaoUtils.updateFileInfo(file); 186 | Log.i("RecursiveFileObserver", "MODIFY: " + path); 187 | break; 188 | case FileObserver.MOVE_SELF: 189 | Log.i("RecursiveFileObserver", "MOVE_SELF: " + path); 190 | break; 191 | case FileObserver.MOVED_FROM: 192 | Log.i("RecursiveFileObserver", "MOVED_FROM: " + path); 193 | break; 194 | case FileObserver.MOVED_TO: 195 | Log.i("RecursiveFileObserver", "MOVED_TO: " + path); 196 | break; 197 | } 198 | } 199 | 200 | private class SingleFileObserver extends FileObserver { 201 | String mPath; 202 | 203 | public SingleFileObserver(String path) { 204 | this(path, ALL_EVENTS); 205 | mPath = path; 206 | } 207 | 208 | SingleFileObserver(String path, int mask) { 209 | super(path, mask); 210 | mPath = path; 211 | } 212 | 213 | @Override 214 | public void onEvent(int event, String path) { 215 | if (path != null) { 216 | String newPath = mPath + "/" + path; 217 | RecursiveFileObserver.this.onEvent(event, newPath); 218 | } 219 | } 220 | } 221 | 222 | private boolean isNeedToListener(String path) { 223 | if (TextUtils.isEmpty(path)) return false; 224 | //以下返回必须为false 225 | String fileName = FileUtils.getFolderName(path); 226 | boolean isHidden = fileName.startsWith("_") || fileName.startsWith("."); 227 | boolean isSystem = path.equals(START_PATH + "Android") || path.equals(START_PATH + "backup") || path.equals(START_PATH + "backups") || path.equals(START_PATH + "CloudDrive") 228 | || path.equals(START_PATH + "huawei") || path.equals(START_PATH + "HuaweiBackup") || path.equals(START_PATH + "HWThemes") || path.equals(START_PATH + "msc") || path.endsWith(START_PATH + "Musiclrc"); 229 | boolean isRxCache = path.equals(START_PATH + "com.eblog" + File.separator + "cache" + File.separator + "rxCache"); 230 | boolean isSmiley = path.equals(START_PATH + "com.eblog" + File.separator + "cache" + File.separator + "smiley"); 231 | boolean isGlide = path.equals(START_PATH + "com.eblog" + File.separator + "cache" + File.separator + "glide"); 232 | boolean isOSS = path.equals(START_PATH + "com.eblog" + File.separator + "cache" + File.separator + "oss_record"); 233 | 234 | //以下返回必须为true 235 | boolean isQQ = path.startsWith(QQ_PIC_PATH) || path.startsWith(QQ_FILE_PATH); 236 | boolean isWX = path.startsWith(WX_PIC_PATH) || path.startsWith(WX_FILE_PATH); 237 | boolean isSysPic = path.equals(SYS_CAMERA_PATH) || path.equals(SCREENSHOTS_PATH) || path.equals(HW_SCREEN_SAVER_PATH); 238 | 239 | //以下部分返回为true 240 | boolean isTencentPath = path.startsWith(START_PATH + "tencent" + File.separator); 241 | 242 | if (isHidden || isSystem || isRxCache || isSmiley || isGlide || isOSS) 243 | return false; 244 | else if (isTencentPath) 245 | if (isQQ || isWX) 246 | return true; 247 | else 248 | return false; 249 | 250 | else if (isSysPic) 251 | return true; 252 | else 253 | return true; 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/model/Extension.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.model; 2 | 3 | /** 4 | * Created by Z7Dream on 2017/2/13 17:23. 5 | * Email:zhangxyfs@126.com 6 | */ 7 | 8 | public class Extension { 9 | public static final String[] PIC = {"jpg", "jpeg", "jpe", "bmp", "png"}; 10 | public static final String[] TXT = {"txt"}; 11 | public static final String[] EXCEL = {"xls", "xlt", "xlm", "xlsx"}; 12 | public static final String[] PPT = {"dps", "dpt", "ppt", "pot", "pps", "pptx"}; 13 | public static final String[] WORD = {"wps", "wpt", "doc", "dot", "rtf", "docx", "dotx"}; 14 | public static final String[] PDF = {"pdf"}; 15 | 16 | public static final String[] AUDIO = {"aac", "mp3", "mid", "wav", "flac", "amr", "m4a", "xmf", "ogg"}; 17 | public static final String[] VIDEO = {"3gp", "mp4", "mkv", "ts", "rmvb"}; 18 | 19 | public static final String[] ZIP = {"rar", "zip", "7z", "z", "iso", "gz", "tar", "cab", "ace", "apk"}; 20 | 21 | 22 | public static void addLike(String which, StringBuilder sb, String... strs) { 23 | for (int i = 0; i < strs.length; i++) { 24 | sb.append(which); 25 | sb.append(" LIKE "); 26 | sb.append("'%.").append(strs[i]).append("'"); 27 | sb.append(" OR "); 28 | } 29 | sb.delete(sb.length() - 4, sb.length()); 30 | } 31 | 32 | public static void addNotLike(String which, StringBuilder sb, String... strs) { 33 | for (int i = 0; i < strs.length; i++) { 34 | sb.append(which); 35 | sb.append(" NOT LIKE "); 36 | sb.append("'%.").append(strs[i]).append("'"); 37 | sb.append(" AND "); 38 | } 39 | sb.delete(sb.length() - 4, sb.length()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/model/MagicFileEntity.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.model; 2 | 3 | /** 4 | * Created by Z7Dream on 2017/2/3 17:45. 5 | * Email:zhangxyfs@126.com 6 | */ 7 | 8 | public class MagicFileEntity { 9 | public String name; 10 | public String mimieType; 11 | public long size; 12 | public long time; 13 | public String path; 14 | public String icon; 15 | 16 | public String company; 17 | public Long companyId; 18 | public String userName; 19 | public Long userId; 20 | 21 | public String chatId; 22 | public String chatName; 23 | 24 | public boolean isFile;//是否文件 25 | } 26 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/model/MagicPicEntity1.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.model; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * Created by Z7Dream on 2017/5/22 11:19. 7 | * Email:zhangxyfs@126.com 8 | */ 9 | 10 | public class MagicPicEntity1 { 11 | public String name; 12 | public String path; 13 | 14 | public String icon; 15 | public int childNum; 16 | 17 | public boolean isNull(){ 18 | return name == null || path == null; 19 | } 20 | 21 | public ArrayList childList; 22 | } 23 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/service/FileUpdatingService.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.service; 2 | 3 | import android.app.Service; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.os.IBinder; 7 | 8 | import com.z7dream.lib.db.FileDaoImpl; 9 | import com.z7dream.lib.db.FileDaoManager; 10 | import com.z7dream.lib.db.bean.MyObjectBox; 11 | import com.z7dream.lib.listener.RecursiveFileObserver; 12 | import com.z7dream.lib.tool.CacheManager; 13 | import com.z7dream.lib.tool.Utils; 14 | 15 | import io.objectbox.BoxStore; 16 | 17 | public class FileUpdatingService extends Service { 18 | private RecursiveFileObserver recursiveFileObserver; 19 | private FileDaoImpl fileDaoImpl; 20 | private static BoxStore mBoxStore; 21 | 22 | public FileUpdatingService() { 23 | 24 | } 25 | 26 | @Override 27 | public IBinder onBind(Intent intent) { 28 | return null; 29 | } 30 | 31 | @Override 32 | public void onCreate() { 33 | super.onCreate(); 34 | if (mBoxStore != null) 35 | fileDaoImpl = new FileDaoManager(mBoxStore); 36 | else 37 | fileDaoImpl = new FileDaoManager(MyObjectBox.builder().androidContext(getApplicationContext()).build()); 38 | //全盘文件夹监听 39 | recursiveFileObserver = new RecursiveFileObserver(CacheManager.getSaveFilePath(), param -> { 40 | fileDaoImpl.toPutFileInStorage(param); 41 | }, fileDaoImpl); 42 | recursiveFileObserver.startWatching(); 43 | } 44 | 45 | @Override 46 | public void onDestroy() { 47 | super.onDestroy(); 48 | if (recursiveFileObserver != null) 49 | recursiveFileObserver.stopWatching(); 50 | if (fileDaoImpl != null) 51 | fileDaoImpl.destory(); 52 | } 53 | 54 | public void toUpdateFileInfos() { 55 | if (fileDaoImpl == null) return; 56 | if (fileDaoImpl.isPutFileInStorageSucc()) { 57 | 58 | } 59 | } 60 | 61 | public static void startService(BoxStore boxStore, Context context) { 62 | if (mBoxStore == null && boxStore != null) { 63 | mBoxStore = boxStore; 64 | } 65 | 66 | if (!Utils.isServiceRunning(context, FileUpdatingService.class.getName())) { 67 | context.startService(new Intent(context, FileUpdatingService.class)); 68 | } 69 | } 70 | 71 | public static void startService(Context context) { 72 | startService(null, context); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/tool/CacheManager.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.tool; 2 | 3 | import android.content.Context; 4 | import android.os.Environment; 5 | import android.support.annotation.NonNull; 6 | 7 | import java.io.File; 8 | 9 | /** 10 | * 缓存目录控制 11 | * Created by xiaoyu.zhang on 2016/11/10 14:57 12 | *   13 | */ 14 | public class CacheManager { 15 | public static final int DEFAULT = 0x0000; 16 | public static final int APK = 0x00100; 17 | public static final int VOICE = 0x00200; 18 | public static final int VIDEO = 0x00300; 19 | public static final int PIC = 0x00400; 20 | public static final int DB = 0x00500; 21 | public static final int CONFIG = 0x00600; 22 | public static final int CACHE = 0x00700; 23 | public static final int USED = 0x00800; 24 | public static final int GIFT = 0x00900; 25 | public static final int GLIDE = 0x01000; 26 | public static final int CRASH = 0x01100; 27 | public static final int SMILEY = 0x01200; 28 | public static final int FILE = 0x01300; 29 | public static final int RES = 0x01400; 30 | public static final int OSS = 0x01500; 31 | public static final int IM = 0x01600; 32 | public static final int ES = 0x01700;//下属文件夹命名-公司id-文件类型- 33 | public static final int EB_PHOTO = 0x01800; 34 | public static final int COLLECT = 0x01900; 35 | public static final int PIC_TEMP = 0x02000; 36 | public static final int OFF_LINE_CACHE = 0x02001; 37 | 38 | public static final int TXT = 0x01710; 39 | public static final int EXCEL = 0x01720; 40 | public static final int PPT = 0x01730; 41 | public static final int WORD = 0x01740; 42 | public static final int PDF = 0x01750; 43 | public static final int OTHER = 0x01760; 44 | public static final int ES_ALL = 0x01799; 45 | 46 | 47 | private static final String STR_APK = "apk"; 48 | private static final String STR_VOICE = "voice"; 49 | private static final String STR_VIDEO = "video"; 50 | private static final String STR_PIC = "picture"; 51 | private static final String STR_DB = "database"; 52 | private static final String STR_CFG = "config"; 53 | private static final String STR_RX = "rxCache"; 54 | private static final String STR_USED = "used"; 55 | private static final String STR_GIFT = "gift"; 56 | private static final String STR_GLIDE = "glide"; 57 | private static final String STR_CRASH = "crash"; 58 | private static final String STR_SMILEY = "smiley"; 59 | private static final String STR_FILE = "file"; 60 | private static final String STR_RES = "res"; 61 | private static final String STR_OSS = "oss_record"; 62 | private static final String STR_IM = "im"; 63 | private static final String STR_ES = "es"; 64 | private static final String STR_TXT = "txt"; 65 | private static final String STR_EXCEL = "excel"; 66 | private static final String STR_PPT = "ppt"; 67 | private static final String STR_WORD = "word"; 68 | private static final String STR_PDF = "pdf"; 69 | private static final String STR_OTHER = "other"; 70 | private static final String STR_EB_PHOTO = "EB_photo"; 71 | private static final String STR_COLLECT = "collect"; 72 | private static final String STR_PIC_TEMP = "picTemp"; 73 | private static final String STR_OFF_LINE_CACHE = "offlinecache"; 74 | 75 | private static final String NOMEDIA = ".nomedia"; 76 | 77 | 78 | /** 79 | * 获取缓存路径 80 | */ 81 | public static String getCachePath(Context context) { 82 | String savePath = getSaveFilePath() + File.separator + context.getPackageName() + File.separator + "cache"; 83 | File fDir = new File(savePath); 84 | if (!fDir.exists()) { 85 | fDir.mkdirs(); 86 | } 87 | return savePath; 88 | } 89 | 90 | public static String getRelativePath(Context context) { 91 | String savePath = getSaveFilePath() + File.separator + context.getPackageName() + File.separator + "cache"; 92 | String relatviePath = File.separator + context.getPackageName() + File.separator + "cache"; 93 | File fDir = new File(savePath); 94 | if (!fDir.exists()) { 95 | fDir.mkdirs(); 96 | } 97 | 98 | return relatviePath; 99 | } 100 | 101 | public static String getCachePath(int which) { 102 | return getCachePath(null, which); 103 | } 104 | 105 | public static String getCachePathNoSepa(int which) { 106 | String path = getCachePath(null, which); 107 | if (path.endsWith(File.separator)) { 108 | return path.substring(0, path.length() - 1); 109 | } 110 | return path; 111 | } 112 | 113 | public static String getCachePath(@NonNull Context context, int which) { 114 | String savePath = ""; 115 | savePath = getCachePath(context); 116 | savePath = getSavePath(savePath, which); 117 | String nomediaPath = savePath + NOMEDIA; 118 | 119 | File fDir = new File(savePath); 120 | if (!fDir.exists()) { 121 | fDir.mkdirs(); 122 | } 123 | File npDir = new File(nomediaPath); 124 | if (!savePath.contains(STR_EB_PHOTO)) { 125 | if (!npDir.exists()) { 126 | npDir.mkdir(); 127 | } 128 | } else { 129 | if (npDir.exists()) 130 | npDir.delete(); 131 | } 132 | return savePath; 133 | } 134 | 135 | public static String getRelativePath(@NonNull Context context, int which) { 136 | String savePath = ""; 137 | savePath = getRelativePath(context); 138 | savePath = getSavePath(savePath, which); 139 | File fDir = new File(savePath); 140 | if (!fDir.exists()) { 141 | fDir.mkdirs(); 142 | } 143 | return savePath; 144 | } 145 | 146 | private static String getSavePath(String savePath, int which) { 147 | savePath += File.separator; 148 | if (which == APK) { 149 | savePath += STR_APK; 150 | } else if (which == VOICE) { 151 | savePath += STR_VOICE; 152 | } else if (which == VIDEO) { 153 | savePath += STR_VIDEO; 154 | } else if (which == PIC) { 155 | savePath += STR_PIC; 156 | } else if (which == DB) { 157 | savePath += STR_DB; 158 | } else if (which == CONFIG) { 159 | savePath += STR_CFG; 160 | } else if (which == CACHE) { 161 | savePath += STR_RX; 162 | } else if (which == USED) { 163 | savePath += STR_USED; 164 | } else if (which == GIFT) { 165 | savePath += STR_GIFT; 166 | } else if (which == GLIDE) { 167 | savePath += STR_GLIDE; 168 | } else if (which == CRASH) { 169 | savePath += STR_CRASH; 170 | } else if (which == SMILEY) { 171 | savePath += STR_SMILEY; 172 | } else if (which == FILE) { 173 | savePath += STR_FILE; 174 | } else if (which == RES) { 175 | savePath += STR_RES; 176 | } else if (which == OSS) { 177 | savePath += STR_OSS; 178 | } else if (which == IM) { 179 | savePath += STR_IM; 180 | } else if (which == ES) { 181 | savePath += STR_ES; 182 | } else if (which == TXT) { 183 | savePath += STR_TXT; 184 | } else if (which == EXCEL) { 185 | savePath += STR_EXCEL; 186 | } else if (which == PPT) { 187 | savePath += STR_PPT; 188 | } else if (which == WORD) { 189 | savePath += STR_WORD; 190 | } else if (which == PDF) { 191 | savePath += STR_PDF; 192 | } else if (which == OTHER) { 193 | savePath += STR_OTHER; 194 | } else if (which == ES_ALL) { 195 | savePath = savePath.substring(0, savePath.length() - 1); 196 | } else if (which == EB_PHOTO) { 197 | savePath += STR_EB_PHOTO; 198 | } else if (which == COLLECT) { 199 | savePath += STR_COLLECT; 200 | } else if (which == PIC_TEMP) { 201 | savePath += STR_PIC_TEMP; 202 | } else if (which == OFF_LINE_CACHE) { 203 | savePath += STR_OFF_LINE_CACHE; 204 | } 205 | savePath += File.separator; 206 | return savePath; 207 | } 208 | 209 | /** 210 | * 生成下载文件保存路径 211 | * 212 | * @return 213 | */ 214 | public static String getSaveFilePath() { 215 | File file = null; 216 | String rootPath = ""; 217 | String status = Environment.getExternalStorageState(); 218 | if (status.equals(Environment.MEDIA_MOUNTED)) { 219 | file = Environment.getExternalStorageDirectory();//获取跟目录 220 | rootPath = file.getPath(); 221 | } 222 | return rootPath; 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/tool/EnumFileType.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.tool; 2 | 3 | import android.text.TextUtils; 4 | 5 | import com.z7dream.lib.R; 6 | 7 | 8 | /** 9 | * Created by Z7Dream on 2017/7/5 13:15. 10 | * Email:zhangxyfs@126.com 11 | */ 12 | 13 | public enum EnumFileType { 14 | PIC, 15 | TXT, 16 | EXCEL, 17 | PPT, 18 | WORD, 19 | PDF, 20 | AUDIO, 21 | VIDEO, 22 | ZIP, 23 | OTHER, 24 | ALL; 25 | 26 | // public static EnumFileType getType(int oldFileType) { 27 | // EnumFileType enumFileType; 28 | // switch (oldFileType) { 29 | // case com.eblog.lib.utils.explorer.FileType.PIC: 30 | // enumFileType = PIC; 31 | // break; 32 | // case com.eblog.lib.utils.explorer.FileType.AUDIO: 33 | // enumFileType = AUDIO; 34 | // break; 35 | // case com.eblog.lib.utils.explorer.FileType.VIDEO: 36 | // enumFileType = VIDEO; 37 | // break; 38 | // case com.eblog.lib.utils.explorer.FileType.TXT: 39 | // enumFileType = TXT; 40 | // break; 41 | // case com.eblog.lib.utils.explorer.FileType.EXCEL: 42 | // enumFileType = EXCEL; 43 | // break; 44 | // case com.eblog.lib.utils.explorer.FileType.PPT: 45 | // enumFileType = PPT; 46 | // break; 47 | // case com.eblog.lib.utils.explorer.FileType.WORD: 48 | // enumFileType = WORD; 49 | // break; 50 | // case com.eblog.lib.utils.explorer.FileType.PDF: 51 | // enumFileType = PDF; 52 | // break; 53 | // default: 54 | // enumFileType = OTHER; 55 | // break; 56 | // } 57 | // return enumFileType; 58 | // } 59 | 60 | public static int getCacheWhich(EnumFileType type) { 61 | int fileType = CacheManager.OTHER; 62 | if (type == EnumFileType.PIC) { 63 | fileType = CacheManager.PIC; 64 | } else if (type == EnumFileType.AUDIO) { 65 | fileType = CacheManager.VOICE; 66 | } else if (type == EnumFileType.VIDEO) { 67 | fileType = CacheManager.VIDEO; 68 | } else if (type == EnumFileType.TXT) { 69 | fileType = CacheManager.TXT; 70 | } else if (type == EnumFileType.EXCEL) { 71 | fileType = CacheManager.EXCEL; 72 | } else if (type == EnumFileType.PPT) { 73 | fileType = CacheManager.PPT; 74 | } else if (type == EnumFileType.WORD) { 75 | fileType = CacheManager.WORD; 76 | } else if (type == EnumFileType.PDF) { 77 | fileType = CacheManager.PDF; 78 | } 79 | return fileType; 80 | } 81 | 82 | public static EnumFileType getEnum(String string) { 83 | if (string != null) { 84 | try { 85 | return Enum.valueOf(EnumFileType.class, string.trim()); 86 | } catch (IllegalArgumentException ex) { 87 | } 88 | } 89 | return EnumFileType.OTHER; 90 | } 91 | 92 | 93 | public static int createIconResId(String type, boolean isFile) { 94 | int resId = R.drawable.ic_file_other; 95 | if (isFile) { 96 | if (TextUtils.equals(type, EnumFileType.PIC.name())) { 97 | resId = R.drawable.ic_file_pic; 98 | } else if (TextUtils.equals(type, EnumFileType.AUDIO.name())) { 99 | resId = R.drawable.ic_file_audio; 100 | } else if (TextUtils.equals(type, EnumFileType.VIDEO.name())) { 101 | resId = R.drawable.ic_file_video; 102 | } else if (TextUtils.equals(type, EnumFileType.TXT.name())) { 103 | resId = R.drawable.ic_file_txt; 104 | } else if (TextUtils.equals(type, EnumFileType.EXCEL.name())) { 105 | resId = R.drawable.ic_file_excel; 106 | } else if (TextUtils.equals(type, EnumFileType.PPT.name())) { 107 | resId = R.drawable.ic_file_ppt; 108 | } else if (TextUtils.equals(type, EnumFileType.WORD.name())) { 109 | resId = R.drawable.ic_file_word; 110 | } else if (TextUtils.equals(type, EnumFileType.PDF.name())) { 111 | resId = R.drawable.ic_file_pdf; 112 | } 113 | } else { 114 | resId = R.drawable.ic_file_folder; 115 | } 116 | return resId; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/tool/FileUtils.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.tool; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.content.ContentUris; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.database.Cursor; 8 | import android.graphics.Bitmap; 9 | import android.graphics.BitmapFactory; 10 | import android.media.MediaScannerConnection; 11 | import android.net.Uri; 12 | import android.os.Build; 13 | import android.os.Environment; 14 | import android.provider.DocumentsContract; 15 | import android.provider.MediaStore; 16 | import android.text.TextUtils; 17 | import android.util.Log; 18 | 19 | import java.io.BufferedOutputStream; 20 | import java.io.BufferedReader; 21 | import java.io.File; 22 | import java.io.FileOutputStream; 23 | import java.io.FileReader; 24 | import java.io.FileWriter; 25 | import java.io.IOException; 26 | import java.io.PrintWriter; 27 | import java.util.Map; 28 | 29 | /** 30 | * Created by Z7Dream on 2017/3/7 9:57. 31 | * Email:zhangxyfs@126.com 32 | */ 33 | 34 | public class FileUtils { 35 | /** 36 | * Java文件操作 获取文件扩展名 37 | */ 38 | public static String getExtensionName(String filename) { 39 | if ((filename != null) && (filename.length() > 0)) { 40 | int dot = filename.lastIndexOf('.'); 41 | if ((dot > -1) && (dot < (filename.length() - 1))) { 42 | return filename.substring(dot + 1).trim(); 43 | } 44 | } 45 | return ""; 46 | } 47 | 48 | /** 49 | * 获取文件夹名 50 | * 51 | * @param path 52 | * @return 53 | */ 54 | public static String getFolderName(String path) { 55 | if (!TextUtils.isEmpty(path)) { 56 | String[] paths = path.split("\\/"); 57 | if (paths.length > 0) 58 | return paths[paths.length - 1]; 59 | } 60 | return path; 61 | } 62 | 63 | /** 64 | * Java文件操作 获取不带扩展名的文件名 65 | */ 66 | public static String getFileNameNoEx(String filename) { 67 | if ((filename != null) && (filename.length() > 0)) { 68 | int dot = filename.lastIndexOf('.'); 69 | if ((dot > -1) && (dot < (filename.length()))) { 70 | return filename.substring(0, dot); 71 | } 72 | } 73 | return filename; 74 | } 75 | 76 | //删除指定文件夹下所有文件 77 | //param path 文件夹完整绝对路径 78 | public static boolean delAllFile(String path, Map notDeleteMap) { 79 | boolean flag = false; 80 | File file = new File(path); 81 | if (!file.exists()) { 82 | return flag; 83 | } 84 | if (!file.isDirectory()) { 85 | return flag; 86 | } 87 | String[] tempList = file.list(); 88 | File temp; 89 | for (int i = 0; i < tempList.length; i++) { 90 | if (path.endsWith(File.separator)) { 91 | temp = new File(path + tempList[i]); 92 | } else { 93 | temp = new File(path + File.separator + tempList[i]); 94 | } 95 | if (temp.isFile()) { 96 | temp.delete(); 97 | } 98 | if (temp.isDirectory() && !temp.getPath().contains(".nomedia") && notDeleteMap.get(temp.getPath()) == null) { 99 | delAllFile(path + "/" + tempList[i], notDeleteMap);//先删除文件夹里面的文件 100 | flag = true; 101 | } 102 | } 103 | return flag; 104 | } 105 | 106 | public static int[] getImageSize(String imagePath) { 107 | int[] res = new int[2]; 108 | 109 | BitmapFactory.Options options = new BitmapFactory.Options(); 110 | options.inJustDecodeBounds = true; 111 | options.inSampleSize = 1; 112 | BitmapFactory.decodeFile(imagePath, options); 113 | 114 | res[0] = options.outWidth; 115 | res[1] = options.outHeight; 116 | return res; 117 | } 118 | 119 | public static String getPathByUri(Context context, Uri data) { 120 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { 121 | return getPathByUri4BeforeKitkat(context, data); 122 | } else { 123 | return getPathByUri4AfterKitkat(context, data); 124 | } 125 | } 126 | 127 | //4.4以前通过Uri获取路径:data是Uri,filename是一个String的字符串,用来保存路径 128 | public static String getPathByUri4BeforeKitkat(Context context, Uri data) { 129 | String filename = null; 130 | if (data.getScheme().toString().compareTo("content") == 0) { 131 | Cursor cursor = context.getContentResolver().query(data, new String[]{"_data"}, null, null, null); 132 | if (cursor.moveToFirst()) { 133 | filename = cursor.getString(0); 134 | } 135 | } else if (data.getScheme().toString().compareTo("file") == 0) {// file:///开头的uri 136 | filename = data.toString().replace("file://", "");// 替换file:// 137 | if (!filename.startsWith("/mnt")) {// 加上"/mnt"头 138 | filename += "/mnt"; 139 | } 140 | } 141 | return filename; 142 | } 143 | 144 | //4.4以后根据Uri获取路径: 145 | @SuppressLint("NewApi") 146 | public static String getPathByUri4AfterKitkat(final Context context, final Uri uri) { 147 | final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; 148 | // DocumentProvider 149 | if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { 150 | if (isExternalStorageDocument(uri)) {// ExternalStorageProvider 151 | final String docId = DocumentsContract.getDocumentId(uri); 152 | final String[] split = docId.split(":"); 153 | final String type = split[0]; 154 | if ("primary".equalsIgnoreCase(type)) { 155 | return Environment.getExternalStorageDirectory() + "/" + split[1]; 156 | } 157 | } else if (isDownloadsDocument(uri)) {// DownloadsProvider 158 | final String id = DocumentsContract.getDocumentId(uri); 159 | final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), 160 | Long.valueOf(id)); 161 | return getDataColumn(context, contentUri, null, null); 162 | } else if (isMediaDocument(uri)) {// MediaProvider 163 | final String docId = DocumentsContract.getDocumentId(uri); 164 | final String[] split = docId.split(":"); 165 | final String type = split[0]; 166 | Uri contentUri = null; 167 | if ("image".equals(type)) { 168 | contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 169 | } else if ("video".equals(type)) { 170 | contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 171 | } else if ("audio".equals(type)) { 172 | contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 173 | } 174 | final String selection = "_id=?"; 175 | final String[] selectionArgs = new String[]{split[1]}; 176 | return getDataColumn(context, contentUri, selection, selectionArgs); 177 | } 178 | } else if ("content".equalsIgnoreCase(uri.getScheme())) {// MediaStore 179 | // (and 180 | // general) 181 | return getDataColumn(context, uri, null, null); 182 | } else if ("file".equalsIgnoreCase(uri.getScheme())) {// File 183 | return uri.getPath(); 184 | } 185 | return null; 186 | } 187 | 188 | /** 189 | * Get the value of the data column for this Uri. This is useful for 190 | * MediaStore Uris, and other file-based ContentProviders. 191 | * 192 | * @param context The context. 193 | * @param uri The Uri to query. 194 | * @param selection (Optional) Filter used in the query. 195 | * @param selectionArgs (Optional) Selection arguments used in the query. 196 | * @return The value of the _data column, which is typically a file path. 197 | */ 198 | public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { 199 | Cursor cursor = null; 200 | final String column = "_data"; 201 | final String[] projection = {column}; 202 | try { 203 | cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); 204 | if (cursor != null && cursor.moveToFirst()) { 205 | final int column_index = cursor.getColumnIndexOrThrow(column); 206 | return cursor.getString(column_index); 207 | } 208 | } finally { 209 | if (cursor != null) 210 | cursor.close(); 211 | } 212 | return null; 213 | } 214 | 215 | /** 216 | * @param uri The Uri to check. 217 | * @return Whether the Uri authority is ExternalStorageProvider. 218 | */ 219 | public static boolean isExternalStorageDocument(Uri uri) { 220 | return "com.android.externalstorage.documents".equals(uri.getAuthority()); 221 | } 222 | 223 | /** 224 | * @param uri The Uri to check. 225 | * @return Whether the Uri authority is DownloadsProvider. 226 | */ 227 | public static boolean isDownloadsDocument(Uri uri) { 228 | return "com.android.providers.downloads.documents".equals(uri.getAuthority()); 229 | } 230 | 231 | /** 232 | * @param uri The Uri to check. 233 | * @return Whether the Uri authority is MediaProvider. 234 | */ 235 | public static boolean isMediaDocument(Uri uri) { 236 | return "com.android.providers.media.documents".equals(uri.getAuthority()); 237 | } 238 | 239 | public static void saveBitmap(Bitmap bitmap, String savePath) { 240 | File file = new File(savePath); 241 | try { 242 | BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); 243 | bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos); 244 | bos.flush(); 245 | bos.close(); 246 | } catch (IOException e) { 247 | e.printStackTrace(); 248 | } 249 | } 250 | 251 | /** 252 | * 扫描指定文件 253 | * 254 | * @param filePath 255 | */ 256 | public static void scanFileAsync(Context context, String filePath) { 257 | MediaScannerConnection.scanFile(context, new String[]{filePath}, null, new MediaScannerConnection.MediaScannerConnectionClient() { 258 | @Override 259 | public void onMediaScannerConnected() { 260 | Log.e("tag", "onMediaScannerConnected"); 261 | } 262 | 263 | @Override 264 | public void onScanCompleted(String path, Uri uri) { 265 | Log.e("tag", path); 266 | } 267 | }); 268 | } 269 | 270 | 271 | /** 272 | * 扫描指定目录 273 | * 274 | * @param dir 275 | */ 276 | public static void scanDirAsync(Context context, String dir) { 277 | Intent scanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_DIR"); 278 | scanIntent.setData(Uri.fromFile(new File(dir))); 279 | context.sendBroadcast(scanIntent); 280 | } 281 | 282 | /** 283 | * 重命名文件 284 | */ 285 | public static boolean renameFile(String filePath, String newPath) { 286 | if (TextUtils.isEmpty(filePath) || TextUtils.isEmpty(newPath)) 287 | return false; 288 | 289 | File file = new File(filePath); 290 | if (file != null) { 291 | return file.renameTo(new File(newPath)); 292 | } 293 | 294 | return false; 295 | } 296 | 297 | /** 298 | * 写文件 299 | * 300 | * @param filePath 301 | * @param str 302 | */ 303 | public static void writeFile(String filePath, String str) { 304 | FileWriter fileWriter = null; 305 | PrintWriter printWriter = null; 306 | 307 | try { 308 | fileWriter = new FileWriter(filePath); 309 | printWriter = new PrintWriter(fileWriter); 310 | printWriter.write(str); 311 | printWriter.println(); 312 | } catch (IOException e) { 313 | e.printStackTrace(); 314 | } finally { 315 | try { 316 | if (fileWriter != null) 317 | fileWriter.close(); 318 | if (printWriter != null) 319 | printWriter.close(); 320 | } catch (IOException e) { 321 | e.printStackTrace(); 322 | } 323 | } 324 | } 325 | 326 | public static String readFile(File file) { 327 | BufferedReader reader = null; 328 | StringBuffer stringBuffer = new StringBuffer(); 329 | try { 330 | reader = new BufferedReader(new FileReader(file)); 331 | String tempString; 332 | while ((tempString = reader.readLine()) != null) { 333 | stringBuffer.append(tempString); 334 | } 335 | reader.close(); 336 | } catch (IOException e1) { 337 | e1.printStackTrace(); 338 | } finally { 339 | if (reader != null) { 340 | try { 341 | reader.close(); 342 | } catch (IOException e1) { 343 | } 344 | } 345 | } 346 | return stringBuffer.toString(); 347 | } 348 | } 349 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/tool/MagicExplorer.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.tool; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * Created by Z7Dream on 2017/7/21 16:59. 7 | * Email:zhangxyfs@126.com 8 | */ 9 | 10 | public class MagicExplorer { 11 | public static final String WPS_PATH = CacheManager.getSaveFilePath() + File.separator + "/Android/Data/cn.wps.moffice_eng/.cache/KingsoftOffice/.history/attach_mapping_v1.json"; 12 | public static final String QQ_PIC_PATH = CacheManager.getSaveFilePath() + File.separator + "tencent" + File.separator + "QQ_Images"; 13 | public static final String QQ_FILE_PATH = CacheManager.getSaveFilePath() + File.separator + "tencent" + File.separator + "QQfile_recv"; 14 | public static final String WX_PIC_PATH = CacheManager.getSaveFilePath() + File.separator + "tencent" + File.separator + "MicroMsg" + File.separator + "WeiXin"; 15 | public static final String WX_FILE_PATH = CacheManager.getSaveFilePath() + File.separator + "tencent" + File.separator + "MicroMsg" + File.separator + "Download"; 16 | public static final String SYS_CAMERA_PATH = CacheManager.getSaveFilePath() + File.separator + "DCIM" + File.separator + "Camera"; 17 | public static final String SCREENSHOTS_PATH = CacheManager.getSaveFilePath() + File.separator + "Pictures"; 18 | public static final String HW_SCREEN_SAVER_PATH = CacheManager.getSaveFilePath() + File.separator + "MagazineUnlock"; 19 | // public static final String ES_PATH = CacheManager.getCachePath(Appli.getContext(), CacheManager.ES); 20 | // public static final String PIC_EBPHOTO_PATH = CacheManager.getCachePath(Appli.getContext(), CacheManager.EB_PHOTO); 21 | } 22 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/tool/Utils.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.tool; 2 | 3 | import android.app.ActivityManager; 4 | import android.content.Context; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by Z7Dream on 2017/7/25 11:43. 10 | * Email:zhangxyfs@126.com 11 | */ 12 | 13 | public class Utils { 14 | public static boolean isServiceRunning(Context context, String serviceName) { 15 | boolean isRunning = false; 16 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 17 | List serviceList = activityManager.getRunningServices(Integer.MAX_VALUE); 18 | if (serviceList == null || serviceList.size() == 0) return false; 19 | for (int i = 0; i < serviceList.size(); i++) { 20 | if (serviceList.get(i).service.getClassName().equals(serviceName)) { 21 | isRunning = true; 22 | break; 23 | } 24 | } 25 | return isRunning; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/tool/rx/RxBus.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.tool.rx; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.util.Log; 5 | 6 | import java.util.ArrayList; 7 | import java.util.Collection; 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.Map; 11 | import java.util.concurrent.ConcurrentHashMap; 12 | 13 | import io.reactivex.Observable; 14 | import io.reactivex.subjects.PublishSubject; 15 | import io.reactivex.subjects.Subject; 16 | 17 | /** 18 | * 无法跨进程 19 | * Created by xiaoyu.zhang on 2015/8/13. 20 | */ 21 | public class RxBus { 22 | private static final String TAG = RxBus.class.getSimpleName(); 23 | private static volatile RxBus instance; 24 | public static boolean DEBUG = false; 25 | 26 | 27 | public static synchronized RxBus get() { 28 | if (null == instance) { 29 | synchronized (RxBus.class) { 30 | if (null == instance) { 31 | instance = new RxBus(); 32 | } 33 | } 34 | } 35 | return instance; 36 | } 37 | 38 | private RxBus() { 39 | } 40 | 41 | private ConcurrentHashMap> subjectMapper = new ConcurrentHashMap<>(); 42 | 43 | public void clear() { 44 | for (Object obj : subjectMapper.keySet()) { 45 | List subjects = subjectMapper.get(obj); 46 | if (null != subjects) { 47 | subjects.clear(); 48 | } 49 | } 50 | subjectMapper.clear(); 51 | } 52 | 53 | public boolean isHasObservable(Object tag) { 54 | if (subjectMapper.size() > 0) { 55 | return subjectMapper.get(tag) != null; 56 | } 57 | return false; 58 | } 59 | 60 | 61 | @SuppressWarnings("unchecked") 62 | public Observable register(@NonNull Object tag, @NonNull Class clazz) { 63 | List subjectList = subjectMapper.get(tag); 64 | if (null == subjectList) { 65 | subjectList = Collections.synchronizedList(new ArrayList<>()); 66 | subjectMapper.put(tag, subjectList); 67 | } 68 | 69 | final Subject subject; 70 | subjectList.add(subject = PublishSubject.create()); 71 | if (DEBUG) Log.d(TAG, "[register]subjectMapper: " + subjectMapper); 72 | return subject; 73 | } 74 | 75 | public void unregister(@NonNull Object tag, @NonNull Observable observable) { 76 | List subjects = subjectMapper.get(tag); 77 | if (null != subjects) { 78 | subjects.remove(observable); 79 | // if (isEmpty(subjects)) { 80 | // subjectMapper.remove(tag); 81 | // } 82 | if (!observable.subscribe().isDisposed()) { 83 | observable.subscribe().dispose(); 84 | } 85 | } 86 | 87 | if (DEBUG) Log.d(TAG, "[unregister]subjectMapper: " + subjectMapper); 88 | } 89 | 90 | public void destory() { 91 | for (Object key : subjectMapper.keySet()) { 92 | List subjectList = subjectMapper.get(key); 93 | if (null != subjectList) { 94 | for (int i = 0; i < subjectList.size(); i++) { 95 | Observable observable = subjectList.get(i); 96 | if (null != observable) { 97 | if (!observable.subscribe().isDisposed()) { 98 | observable.subscribe().dispose(); 99 | } 100 | } 101 | } 102 | subjectList.clear(); 103 | } 104 | } 105 | subjectMapper.clear(); 106 | } 107 | 108 | public void post(@NonNull Object content) { 109 | post(content.getClass().getName(), content); 110 | } 111 | 112 | @SuppressWarnings("unchecked") 113 | public void post(@NonNull Object tag, @NonNull Object content) { 114 | if (subjectMapper == null) { 115 | return; 116 | } 117 | List subjectList = subjectMapper.get(tag); 118 | 119 | if (!isEmpty(subjectList)) { 120 | for (Subject subject : subjectList) { 121 | if (subject != null) { 122 | subject.onNext(content); 123 | } 124 | } 125 | } 126 | if (DEBUG) Log.d(TAG, "[send]subjectMapper: " + subjectMapper); 127 | } 128 | 129 | 130 | public static boolean isEmpty(Collection collection) { 131 | return null == collection || collection.isEmpty(); 132 | } 133 | 134 | public static boolean isEmpty(Map map) { 135 | return null == map || map.isEmpty(); 136 | } 137 | 138 | public static boolean isEmpty(Object[] objs) { 139 | return null == objs || objs.length <= 0; 140 | } 141 | 142 | public static boolean isEmpty(int[] objs) { 143 | return null == objs || objs.length <= 0; 144 | } 145 | 146 | public static boolean isEmpty(CharSequence charSequence) { 147 | return null == charSequence || charSequence.length() <= 0; 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /lib/src/main/java/com/z7dream/lib/tool/rx/RxSchedulersHelper.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib.tool.rx; 2 | 3 | 4 | import io.reactivex.FlowableTransformer; 5 | import io.reactivex.ObservableTransformer; 6 | import io.reactivex.android.schedulers.AndroidSchedulers; 7 | import io.reactivex.schedulers.Schedulers; 8 | 9 | /** 10 | * User: Axl_Jacobs(Axl.Jacobs@gmail.com) 11 | * Date: 2016-09-03 12 | * Time: 11:16 13 | * FIXME 14 | * 处理Rx线程 15 | */ 16 | public class RxSchedulersHelper { 17 | 18 | //处理Rx线程 19 | public static ObservableTransformer io_main() { 20 | return tObservable -> tObservable.subscribeOn(Schedulers.io()) 21 | .observeOn(AndroidSchedulers.mainThread()); 22 | } 23 | 24 | public static ObservableTransformer main() { 25 | return tObservable -> tObservable.subscribeOn(AndroidSchedulers.mainThread()) 26 | .observeOn(AndroidSchedulers.mainThread()); 27 | } 28 | 29 | 30 | public static ObservableTransformer io() { 31 | return tObservable -> tObservable.subscribeOn(Schedulers.io()) 32 | .observeOn(Schedulers.io()); 33 | } 34 | 35 | public static FlowableTransformer fio_main() { 36 | return upstream -> upstream.subscribeOn(Schedulers.io()) 37 | .observeOn(AndroidSchedulers.mainThread()); 38 | } 39 | 40 | public static FlowableTransformer fmain() { 41 | return upstream -> upstream.subscribeOn(AndroidSchedulers.mainThread()) 42 | .observeOn(AndroidSchedulers.mainThread()); 43 | } 44 | 45 | public static FlowableTransformer fio() { 46 | return upstream -> upstream.subscribeOn(Schedulers.io()) 47 | .observeOn(Schedulers.io()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_audio.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_excel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_excel.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_folder.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_launcher.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_msg_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_msg_down.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_myfiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_myfiles.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_mytypes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_mytypes.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_near30day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_near30day.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_other.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_other.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_pdf.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_pic.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_ppt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_ppt.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_qq.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_txt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_txt.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_video.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_word.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_word.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_wps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_wps.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xhdpi/ic_file_wx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xhdpi/ic_file_wx.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_audio.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_excel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_excel.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_folder.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_launcher.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_msg_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_msg_down.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_myfiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_myfiles.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_mytypes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_mytypes.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_near30day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_near30day.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_other.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_other.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_pdf.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_pic.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_ppt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_ppt.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_qq.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_txt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_txt.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_video.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_word.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_word.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_wps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_wps.png -------------------------------------------------------------------------------- /lib/src/main/res/drawable-xxhdpi/ic_file_wx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhangxyfs/FileManager/7acdf9d594c7c31a27fe2053ef89fcfae3919431/lib/src/main/res/drawable-xxhdpi/ic_file_wx.png -------------------------------------------------------------------------------- /lib/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | lib 3 | 4 | -------------------------------------------------------------------------------- /lib/src/test/java/com/z7dream/lib/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.z7dream.lib; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':lib' 2 | --------------------------------------------------------------------------------