diff --git a/.gitignore b/.gitignore
index 910e696..59c21df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,3 +61,4 @@ library/src/main/res/drawable/
samples/libs/
samples/src/main/res/drawable/
.idea/misc.xml
+/repo/
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
new file mode 100644
index 0000000..f5ac0f0
Binary files /dev/null and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml
new file mode 100644
index 0000000..b6e4700
--- /dev/null
+++ b/.idea/checkstyle-idea.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
new file mode 100644
index 0000000..30aa626
--- /dev/null
+++ b/.idea/codeStyles/Project.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 9a8b7e5..fb7f4a8 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,22 +1,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index e7bedf3..0000000
--- a/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml
new file mode 100644
index 0000000..67ce0f0
--- /dev/null
+++ b/.idea/dbnavigator.xml
@@ -0,0 +1,453 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..97626ba
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 1765860..310c65f 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -1,10 +1,13 @@
+
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..3c5b05a
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..548df33
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml
new file mode 100644
index 0000000..a3f7734
--- /dev/null
+++ b/.idea/markdown-navigator.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/markdown-navigator/profiles_settings.xml b/.idea/markdown-navigator/profiles_settings.xml
new file mode 100644
index 0000000..57927c5
--- /dev/null
+++ b/.idea/markdown-navigator/profiles_settings.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 1caa136..169093e 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,43 +1,45 @@
-
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/.idea/modules.xml b/.idea/modules.xml
index e2d513a..a0c2092 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,9 +2,18 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
deleted file mode 100644
index 7f68460..0000000
--- a/.idea/runConfigurations.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index b78a0b8..b35237c 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,21 +3,30 @@
buildscript {
repositories {
jcenter()
+ google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.3.1'
-
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
+ classpath 'com.android.tools.build:gradle:4.2.2'
}
}
allprojects {
repositories {
jcenter()
+ google()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
+
+ext {
+ userOrg = 'davy'
+ repoName = "maven"
+ groupId = 'org.greenleaf.utils'
+ version = '1.0.0'
+ desc = 'useful tool for android'
+ website = 'https://github.com/davyjoneswang/AndroidCommonUtils'
+ licences = ['Apache-2.0']
+}
\ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 0f1949a..4d9ca16 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Thu Jun 08 13:10:58 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/injectplugin/.gitignore b/injectplugin/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/injectplugin/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/injectplugin/build.gradle b/injectplugin/build.gradle
new file mode 100644
index 0000000..be7b691
--- /dev/null
+++ b/injectplugin/build.gradle
@@ -0,0 +1,35 @@
+apply plugin: 'groovy'
+apply plugin: 'maven-publish'
+
+dependencies {
+ compile gradleApi()//gradle sdk
+ compile localGroovy()
+ compile 'com.android.tools.build:gradle:3.2.0'
+ compile 'org.apache.commons:commons-io:1.3.2'
+ compile 'org.javassist:javassist:3.20.0-GA'
+}
+
+task generateSourcesJar(type: Jar) {
+ from sourceSets.main.java.srcDirs
+ classifier 'sources'
+}
+
+//发布maven库
+publishing {
+ //配置maven-publishing插件的输出物
+ publications {
+ maven(MavenPublication) {
+ from components.java
+ //发布仓库的文件路径
+ groupId = rootProject.ext.groupId
+ //库名
+ artifactId = 'injectplugin'
+ //版本号
+ version = rootProject.ext.version
+ //指定打包路径
+ // artifact "$buildDir/outputs/aar/${project.name}-release.aar"
+ // 上传source,这样使用方可以看到方法注释
+ artifact generateSourcesJar
+ }
+ }
+}
\ No newline at end of file
diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectExtension.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectExtension.groovy
new file mode 100644
index 0000000..147b121
--- /dev/null
+++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectExtension.groovy
@@ -0,0 +1,18 @@
+package org.greenleaf.utils.plugin
+
+/**
+ * Created by davy on 2017/6/8.
+ */
+public class InjectExtension {
+
+ List injectPackages
+ String message
+
+ @Override
+ public String toString() {
+ return "InjectExtension{" +
+ "injectPackages=" + injectPackages +
+ ", message='" + message + '\'' +
+ '}'
+ }
+}
\ No newline at end of file
diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy
new file mode 100644
index 0000000..711c529
--- /dev/null
+++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectPlugin.groovy
@@ -0,0 +1,31 @@
+package org.greenleaf.utils.plugin
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+public class InjectPlugin implements Plugin {
+
+ Logger mLogger = LoggerFactory.getLogger(Injecter.class)
+
+ @Override
+ void apply(Project project) {
+
+ mLogger.info("========================")
+ mLogger.info("InjectPlugin")
+ mLogger.info("========================")
+
+ def injectExtension = project.extensions.create('injectplugin', InjectExtension)
+ println(injectExtension) //这里返回空,afterEvaluate才能获得值
+ mLogger.info("========================")
+
+ project.afterEvaluate {
+ println(injectExtension)
+ }
+
+// project.android.registerTransform(new OnlyCopyTransform(project))
+ project.android.registerTransform(new InjectTransform(project, injectExtension))
+
+ }
+}
\ No newline at end of file
diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy
new file mode 100644
index 0000000..cf2042d
--- /dev/null
+++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/InjectTransform.groovy
@@ -0,0 +1,99 @@
+package org.greenleaf.utils.plugin
+
+import com.android.build.api.transform.*
+import com.android.build.gradle.internal.pipeline.TransformManager
+import org.apache.commons.codec.digest.DigestUtils
+import org.apache.commons.io.FileUtils
+import org.gradle.api.Project
+import org.slf4j.Logger
+import org.slf4j.LoggerFactory
+
+/**
+ * Created by davy on 2017/6/8.
+ */
+
+public class InjectTransform extends Transform {
+
+ Logger mLogger = LoggerFactory.getLogger(Injecter.class)
+
+ Project project
+ InjectExtension injectExtension
+
+ InjectTransform(Project project, InjectExtension injectExtension) {
+ this.project = project
+ this.injectExtension = injectExtension
+ }
+
+ @Override
+ String getName() {
+ return this.class.simpleName
+ }
+
+ @Override
+ Set getInputTypes() {
+ return TransformManager.CONTENT_CLASS
+ }
+
+ @Override
+ Set getOutputTypes() {
+ return TransformManager.CONTENT_CLASS
+ }
+
+ @Override
+ Set super QualifiedContent.Scope> getScopes() {
+ return TransformManager.SCOPE_FULL_PROJECT
+ }
+
+ @Override
+ boolean isIncremental() {
+ return false
+ }
+
+ @Override
+ void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
+ super.transform(transformInvocation)
+
+ println this.class.simpleName + " transform start."
+ mLogger.info("{} transform start. ", this.class.simpleName)
+
+ // Transform的inputs有两种类型,一种是目录,一种是jar包,要分开遍历
+ transformInvocation.inputs.each { TransformInput input ->
+ //对类型为“文件夹”的input进行遍历
+ input.directoryInputs.each { DirectoryInput directoryInput ->
+
+ //文件夹里面包含的是我们手写的类以及R.class、BuildConfig.class以及R$XXX.class等
+ List stringList = new ArrayList<>()
+ stringList.addAll(injectExtension.injectPackages)
+ println "inject path: " + stringList.toString()
+
+ Injecter.injectDir(project, directoryInput.file.absolutePath, stringList)
+
+ // 获取output目录
+ def dest = transformInvocation.outputProvider.getContentLocation(directoryInput.name,
+ directoryInput.contentTypes, directoryInput.scopes,
+ Format.DIRECTORY)
+ // 将input的目录复制到output指定目录
+ FileUtils.copyDirectory(directoryInput.file, dest)
+ }
+ //对类型为jar文件的input进行遍历
+ input.jarInputs.each { JarInput jarInput ->
+
+ //jar文件一般是第三方依赖库jar文件 重命名输出文件(同目录copyFile会冲突)
+ def jarName = jarInput.name
+ def md5Name = DigestUtils.md5Hex(jarInput.file.getAbsolutePath())
+
+ if (jarName.endsWith(".jar")) {
+ jarName = jarName.substring(0, jarName.length() - 4)
+ }
+ //生成输出路径
+ def dest = transformInvocation.outputProvider.getContentLocation(jarName + md5Name,
+ jarInput.contentTypes, jarInput.scopes, Format.JAR)
+ //将输入内容复制到输出
+ FileUtils.copyFile(jarInput.file, dest)
+ }
+ }
+
+ println this.class.simpleName + " transform end"
+ mLogger.info("{} transform end. ", this.class.simpleName)
+ }
+}
diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy
new file mode 100644
index 0000000..2cadfc6
--- /dev/null
+++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/Injecter.groovy
@@ -0,0 +1,138 @@
+package org.greenleaf.utils.plugin
+
+import groovy.io.FileType
+import javassist.ClassPool
+import javassist.CtClass
+import javassist.CtConstructor
+import org.apache.commons.io.FileUtils
+import org.gradle.api.Project
+
+/**
+ * Created by davy on 2017/6/8.
+ */
+public class Injecter {
+
+ private static final ClassPool mPool = ClassPool.getDefault()
+ private static
+ final String injectStr = "System.out.println(\"Injecter Helper\");"
+
+ public static void injectDir(final Project project, final String rootPath, final List injectPackages) {
+
+ println "injectDir path:" + rootPath + " injectPackages:" + injectPackages
+ println project.android.bootClasspath[0].toString()
+
+ mPool.appendClassPath(project.android.bootClasspath[0].toString())
+ mPool.appendClassPath(rootPath)
+
+ File dir = new File(rootPath)
+ if (!dir.isDirectory()) {
+ return
+ }
+
+ final Set injectPackagesPathSet = new HashSet<>()
+ for (String packageNameItem : injectPackages) {
+ injectPackagesPathSet.add(packageNameItem.replace(".", File.separator))
+ }
+ println injectPackagesPathSet
+
+ dir.eachFileRecurse(FileType.FILES, { File file ->
+
+ println()
+ println("each file")
+ String classFilePath = file.absolutePath
+ String subClassFilePath = classFilePath.substring(rootPath.length() + 1)
+ println subClassFilePath
+
+ //确保当前文件是class文件,并且不是系统自动生成的class文件
+ if (classFilePath.endsWith(".class")
+ && !classFilePath.contains('R$')
+ && !classFilePath.contains('R.class')
+ && !classFilePath.contains("BuildConfig.class")) {
+
+ boolean needInject = false
+
+ int index = -1
+
+ for (String packageNameItem : injectPackagesPathSet) {
+ index = subClassFilePath.lastIndexOf(packageNameItem)
+ println packageNameItem
+ println subClassFilePath
+ println index
+ needInject = index != -1
+ if (needInject) {
+ break
+ }
+ }
+
+ println "injectDir process File fileName:" + file.getName() + " inject:" + needInject
+
+ if (needInject) {
+
+ //subClassFilePath .aa.bb.cc.class
+ int end = subClassFilePath.length() - 6 // .class = 6
+ String className = subClassFilePath.substring(index, end)
+ .replace('\\', '.').replace('/', '.')
+
+ println "injectDir do inject className:" + className
+
+ //开始修改class文件
+ CtClass c = mPool.getCtClass(className)
+
+ if (c.isFrozen()) {
+ c.defrost()
+ }
+
+ CtConstructor[] cts = c.getDeclaredConstructors()
+ if (cts == null || cts.length == 0) {
+ //手动创建一个构造函数
+ CtConstructor constructor = new CtConstructor(new CtClass[0], c)
+ constructor.insertBeforeBody(injectStr)
+ c.addConstructor(constructor)
+ } else {
+ cts[0].insertBeforeBody(injectStr)
+ }
+ c.writeFile(rootPath)
+ c.detach()
+ }
+ }
+ }
+ )
+ }
+
+ /**
+ * 这里需要将jar包先解压,注入代码后再重新生成jar包
+ * @path jar包的绝对路径
+ */
+ public static void injectJar(String path) {
+ if (path.endsWith(".jar")) {
+ File jarFile = new File(path)
+
+ // jar包解压后的保存路径
+ String jarZipDir = jarFile.getParent() + "/" + jarFile.getName().replace('.jar', '')
+
+ // 解压jar包, 返回jar包中所有class的完整类名的集合(带.class后缀)
+ List classNameList = JarZipUtil.unzipJar(path, jarZipDir)
+
+ // 删除原来的jar包
+ jarFile.delete()
+
+ // 注入代码
+ mPool.appendClassPath(jarZipDir)
+ for (String className : classNameList) {
+ if (className.endsWith(".class")
+ && !className.contains('R$')
+ && !className.contains('R.class')
+ && !className.contains("BuildConfig.class")) {
+ className = className.substring(0, className.length() - 6)
+ injectClass(className, jarZipDir)
+ }
+ }
+
+ // 从新打包jar
+ JarZipUtil.zipJar(jarZipDir, path)
+
+ // 删除目录
+ FileUtils.deleteDirectory(new File(jarZipDir))
+ }
+ }
+}
\ No newline at end of file
diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/JarZipUtil.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/JarZipUtil.groovy
new file mode 100644
index 0000000..f51f6e1
--- /dev/null
+++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/JarZipUtil.groovy
@@ -0,0 +1,70 @@
+package org.greenleaf.utils.plugin
+
+import java.util.jar.JarEntry
+import java.util.jar.JarFile
+import java.util.jar.JarOutputStream
+import java.util.zip.ZipEntry
+
+public class JarZipUtil {
+
+ /**
+ * 将该jar包解压到指定目录
+ *
+ * @param jarPath jar包的绝对路径
+ * @param destDirPath jar包解压后的保存路径
+ * @return 返回该jar包中包含的所有class的完整类名类名集合,其中一条数据如:com.aitski.hotpatch.Xxxx.class
+ */
+ public static List unzipJar(String jarPath, String destDirPath) {
+
+ List list = new ArrayList()
+ if (jarPath.endsWith('.jar')) {
+
+ JarFile jarFile = new JarFile(jarPath)
+ Enumeration jarEntrys = jarFile.entries()
+ while (jarEntrys.hasMoreElements()) {
+ JarEntry jarEntry = jarEntrys.nextElement()
+ if (jarEntry.directory) {
+ continue
+ }
+ String entryName = jarEntry.getName()
+ if (entryName.endsWith('.class')) {
+ String className = entryName.replace('\\', '.').replace('/', '.')
+ list.add(className)
+ }
+ String outFileName = destDirPath + "/" + entryName
+ File outFile = new File(outFileName)
+ outFile.getParentFile().mkdirs()
+ InputStream inputStream = jarFile.getInputStream(jarEntry)
+ FileOutputStream fileOutputStream = new FileOutputStream(outFile)
+ fileOutputStream << inputStream
+ fileOutputStream.close()
+ inputStream.close()
+ }
+ jarFile.close()
+ }
+ return list
+ }
+
+ /**
+ * 重新打包jar
+ *
+ * @param packagePath 将这个目录下的所有文件打包成jar
+ * @param destPath 打包好的jar包的绝对路径
+ */
+ public static void zipJar(String packagePath, String destPath) {
+
+ File file = new File(packagePath)
+ JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(destPath))
+ file.eachFileRecurse {
+ File f ->
+ String entryName = f.getAbsolutePath().substring(packagePath.length() + 1)
+ outputStream.putNextEntry(new ZipEntry(entryName))
+ if (!f.directory) {
+ InputStream inputStream = new FileInputStream(f)
+ outputStream << inputStream
+ inputStream.close()
+ }
+ }
+ outputStream.close()
+ }
+}
\ No newline at end of file
diff --git a/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy
new file mode 100644
index 0000000..4999e88
--- /dev/null
+++ b/injectplugin/src/main/groovy/org/greenleaf/utils/plugin/OnlyCopyTransform.groovy
@@ -0,0 +1,89 @@
+package org.greenleaf.utils.plugin
+
+import com.android.build.api.transform.*
+import com.android.build.gradle.internal.pipeline.TransformManager
+import org.apache.commons.codec.digest.DigestUtils
+import org.apache.commons.io.FileUtils
+import org.gradle.api.Project
+/**
+ * Created by davy on 2017/6/8.
+ */
+
+public class OnlyCopyTransform extends Transform {
+
+ Project project
+
+ OnlyCopyTransform(Project project) {
+ this.project = project
+ }
+
+ @Override
+ String getName() {
+ return this.class.simpleName
+ }
+
+ @Override
+ Set getInputTypes() {
+ return TransformManager.CONTENT_CLASS
+ }
+
+ @Override
+ Set getOutputTypes() {
+ return TransformManager.CONTENT_CLASS
+ }
+
+ @Override
+ Set super QualifiedContent.Scope> getScopes() {
+ return TransformManager.SCOPE_FULL_PROJECT
+ }
+
+ @Override
+ boolean isIncremental() {
+ return false
+ }
+
+ @Override
+ void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
+ super.transform(transformInvocation)
+ println this.class.simpleName + " transform start"
+
+ // Transform的inputs有两种类型,一种是目录,一种是jar包,要分开遍历
+ transformInvocation.inputs.each { TransformInput input ->
+ //对类型为“文件夹”的input进行遍历
+ input.directoryInputs.each { DirectoryInput directoryInput ->
+ //文件夹里面包含的是我们手写的类以及R.class、BuildConfig.class以及R$XXX.class等
+ // 获取output目录
+ def dest = transformInvocation.outputProvider.getContentLocation(directoryInput.name,
+ directoryInput.contentTypes, directoryInput.scopes,
+ Format.DIRECTORY)
+
+ println "Directory:" + directoryInput.name + " " + directoryInput.contentTypes + " " + directoryInput.file.getAbsolutePath()
+ println " Output:" + dest.getAbsolutePath()
+ // 将input的目录复制到output指定目录
+ FileUtils.copyDirectory(directoryInput.file, dest)
+ }
+ //对类型为jar文件的input进行遍历
+ input.jarInputs.each { JarInput jarInput ->
+
+ //jar文件一般是第三方依赖库jar文件
+ // 重命名输出文件(同目录copyFile会冲突)
+ def jarName = jarInput.name
+ def md5Name = DigestUtils.md5Hex(jarInput.file.getAbsolutePath())
+
+ if (jarName.endsWith(".jar")) {
+ jarName = jarName.substring(0, jarName.length() - 4)
+ }
+ //生成输出路径
+ def dest = transformInvocation.outputProvider.getContentLocation(jarName + md5Name,
+ jarInput.contentTypes, jarInput.scopes, Format.JAR)
+ //将输入内容复制到输出
+
+ println "JAR:" + jarName + " " + jarInput.contentTypes + " " + jarInput.file.getAbsolutePath() + " " + md5Name
+ println " Output:" + dest.getAbsolutePath()
+ FileUtils.copyFile(jarInput.file, dest)
+ }
+ }
+
+ println this.class.simpleName + " transform end"
+ }
+}
diff --git a/injectplugin/src/main/resources/META-INF/gradle-plugins/org.greenleaf.utils.injectplugin.properties b/injectplugin/src/main/resources/META-INF/gradle-plugins/org.greenleaf.utils.injectplugin.properties
new file mode 100644
index 0000000..38bdb2e
--- /dev/null
+++ b/injectplugin/src/main/resources/META-INF/gradle-plugins/org.greenleaf.utils.injectplugin.properties
@@ -0,0 +1 @@
+implementation-class = org.greenleaf.utils.plugin.InjectPlugin
\ No newline at end of file
diff --git a/library/build.gradle b/library/build.gradle
index 6e8d203..8bc5293 100644
--- a/library/build.gradle
+++ b/library/build.gradle
@@ -1,17 +1,25 @@
apply plugin: 'com.android.library'
+apply plugin: 'maven-publish'
+
+//publish {
+// artifactId = 'utils'
+// uploadName = 'AndroidCommonUtils'
+// publishVersion = '1.0.0'
+//
+// userOrg = rootProject.ext.userOrg
+// repoName = rootProject.ext.repoName
+// groupId = rootProject.ext.groupId
+// desc = rootProject.ext.desc
+// website = rootProject.ext.website
+// licences = rootProject.ext.licences
+//}
android {
compileSdkVersion 25
- buildToolsVersion "25.0.3"
-
+ buildToolsVersion '25.0.3'
defaultConfig {
- minSdkVersion 19
+ minSdkVersion 17
targetSdkVersion 25
- versionCode 1
- versionName "1.0"
-
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-
}
buildTypes {
release {
@@ -19,13 +27,67 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
+ lintOptions {
+ abortOnError false
+ checkDependencies true
+ checkReleaseBuilds false
+ // Or, if you prefer, you can continue to check for errors in release builds,
+ // but continue the build even when errors are found:
+ abortOnError false
+ // The demo app does not have translations.
+ disable 'MissingTranslation'
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+tasks.withType(Javadoc) {
+ options {
+ options.addStringOption('Xdoclint:none', '-quiet')
+ options.addStringOption('encoding', 'UTF-8')
+ options.addStringOption('charSet', 'UTF-8')
+ }
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
- exclude group: 'com.android.support', module: 'support-annotations'
- })
- compile 'com.android.support:appcompat-v7:25.3.1'
- testCompile 'junit:junit:4.12'
+ api fileTree(include: ['*.jar'], dir: 'libs')
+ api 'com.android.support:appcompat-v7:25.4.0'
}
+
+task generateSourcesJar(type: Jar) {
+ from android.sourceSets.main.java.srcDirs
+ classifier 'sources'
+}
+
+afterEvaluate {
+ publishing {
+ publications {
+ // Creates a Maven publication called "release".
+ release(MavenPublication) {
+ // Applies the component for the release build variant.
+ from components.release
+
+ // You can then customize attributes of the publication as shown below.
+ groupId = rootProject.ext.groupId
+ artifactId = 'utils'
+ version = rootProject.ext.version
+
+ // 上传source,这样使用方可以看到方法注释
+ artifact generateSourcesJar
+ }
+ // Creates a Maven publication called “debug”.
+ debug(MavenPublication) {
+ // Applies the component for the debug build variant.
+ from components.debug
+
+ groupId = rootProject.ext.groupId
+ artifactId = 'utils'
+ version = rootProject.ext.version + "-SNAPSHOT"
+ // 上传source,这样使用方可以看到方法注释
+ artifact generateSourcesJar
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/library/src/androidTest/java/org/davy/commons/ExampleInstrumentedTest.java b/library/src/androidTest/java/org/davy/commons/ExampleInstrumentedTest.java
deleted file mode 100644
index f1a4785..0000000
--- a/library/src/androidTest/java/org/davy/commons/ExampleInstrumentedTest.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.davy.commons;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumentation test, which will execute on an Android device.
- *
- * @see Testing documentation
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
- @Test
- public void useAppContext() throws Exception {
- // Context of the app under test.
- Context appContext = InstrumentationRegistry.getTargetContext();
-
- assertEquals("org.davy.commons.test", appContext.getPackageName());
- }
-}
diff --git a/library/src/main/AndroidManifest.xml b/library/src/main/AndroidManifest.xml
index ef3fc20..016c7c9 100644
--- a/library/src/main/AndroidManifest.xml
+++ b/library/src/main/AndroidManifest.xml
@@ -1,12 +1,7 @@
- package="org.davy.commons">
-
-
-
-
-
-
-
+
+
+
diff --git a/library/src/main/java/org/davy/commons/FileExistsException.java b/library/src/main/java/org/davy/commons/FileExistsException.java
deleted file mode 100644
index e02c1e5..0000000
--- a/library/src/main/java/org/davy/commons/FileExistsException.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.davy.commons;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Indicates that a file already exists.
- */
-public class FileExistsException extends IOException {
-
- private static final long serialVersionUID = 1L;
-
- public FileExistsException() {
- super();
- }
-
- public FileExistsException(final String message) {
- super(message);
- }
-
- public FileExistsException(final File file) {
- super("File " + file + " exists");
- }
-
-}
diff --git a/library/src/main/java/org/davy/commons/NetworkUtil.java b/library/src/main/java/org/davy/commons/NetworkUtil.java
deleted file mode 100644
index 28a287d..0000000
--- a/library/src/main/java/org/davy/commons/NetworkUtil.java
+++ /dev/null
@@ -1,132 +0,0 @@
-package org.davy.commons;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.net.ConnectivityManager;
-import android.net.DhcpInfo;
-import android.net.NetworkInfo;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.provider.Settings;
-import android.support.annotation.NonNull;
-import android.support.annotation.WorkerThread;
-import android.text.TextUtils;
-import android.text.format.Formatter;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Created by davy on 2017/5/23.
- */
-
-public class NetworkUtil {
-
- private static final String TAG = "NetworkUtil";
-
- private static final String ETHERNET_USE_STATIC_IP = "ethernet_use_static_ip";
- private static final String ETHERNET_STATIC_IP = "ethernet_static_ip";
- private static final String ETHERNET_STATIC_GATEWAY = "ethernet_static_gateway";
- private static final String ETHERNET_STATIC_NETMASK = "ethernet_static_netmask";
- private static final String ETHERNET_STATIC_DNS1 = "ethernet_static_dns1";
- private static final String ETHERNET_STATIC_DNS2 = "ethernet_static_dns2";
- private static final String ETH0 = "eth0";
-
- public static boolean isConnected(Context context) {
- ConnectivityManager connManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo networkInfo = connManager.getActiveNetworkInfo();
- if (networkInfo != null) {
- return networkInfo.isAvailable();
- }
- return false;
- }
-
- public static boolean isEthernetConnected(Context context) {
- ConnectivityManager connManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET);
- if (networkInfo != null) {
- return networkInfo.isAvailable();
- }
- return false;
- }
-
- @WorkerThread
- public static boolean pingToken(@NonNull String urlNoHttpOrIp) {
- Runtime runtime = Runtime.getRuntime();
-
- try {
- Process e = runtime.exec("/system/bin/ping -c 1 " + urlNoHttpOrIp);
- int exitValue = e.waitFor();
- return exitValue == 0;
- } catch (InterruptedException | IOException var4) {
- //ignore
- return false;
- }
- }
-
- public static String getCurrentIp(Context context) {
- String ip = "";
- StringBuilder stringBuilder = new StringBuilder();
- ConnectivityManager connectivityManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
-
- if (networkInfo != null) {
- if (networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET) {
- if (Settings.System.getInt(context.getContentResolver(), ETHERNET_USE_STATIC_IP, 0) == 1) {
- return getStaticEthInfo(context);
- } else {
- return getEthInfoFromDhcp(context);
- }
- } else if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
- WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
- DhcpInfo dhcpInfo = wifiManager.getDhcpInfo();
- if (dhcpInfo != null) {
- stringBuilder.append(dhcpInfo.ipAddress).append(" ").append(Formatter.formatIpAddress(dhcpInfo.ipAddress)).append(" \n");
- stringBuilder.append(dhcpInfo.netmask).append(" ").append(Formatter.formatIpAddress(dhcpInfo.netmask)).append(" \n");
- stringBuilder.append(dhcpInfo.gateway).append(" ").append(Formatter.formatIpAddress(dhcpInfo.gateway)).append(" \n");
- stringBuilder.append(dhcpInfo.ipAddress & dhcpInfo.netmask).append(" ").append(Formatter.formatIpAddress(dhcpInfo.ipAddress & dhcpInfo.netmask)).append(" \n");
- stringBuilder.append(dhcpInfo.dns1).append(" ").append(Formatter.formatIpAddress(dhcpInfo.dns1)).append(" \n");
- stringBuilder.append(dhcpInfo.dns2).append(" ").append(Formatter.formatIpAddress(dhcpInfo.dns2)).append(" \n");
- ip = Formatter.formatIpAddress(dhcpInfo.ipAddress);
- } else {
- WifiInfo wifiInfo = wifiManager.getConnectionInfo();
- if (wifiInfo != null) {
- ip = Formatter.formatIpAddress(wifiInfo.getIpAddress());
- }
- }
- } else {
- stringBuilder.append("未知连接类型" + networkInfo.getTypeName() + "\n\n");
- }
- } else {
- stringBuilder.append("无网络连接" + "\n\n");
- }
- Log.d("TAG", stringBuilder.toString());
- return ip;
- }
-
- public static String getStaticEthInfo(Context context) {
- StringBuilder stringBuilder = new StringBuilder();
- ContentResolver contentResolver = context.getContentResolver();
- stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_USE_STATIC_IP)).append(" \n");
- stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_STATIC_IP)).append(" \n");
- stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_STATIC_GATEWAY)).append(" \n");
- stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_STATIC_NETMASK)).append(" \n");
- stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_STATIC_DNS1)).append(" \n");
- stringBuilder.append(Settings.System.getString(contentResolver, ETHERNET_STATIC_DNS2)).append(" \n");
- Log.d("TAG", stringBuilder.toString());
- return Settings.System.getString(contentResolver, ETHERNET_STATIC_IP);
- }
-
- public static String getEthInfoFromDhcp(Context context) {
- String dhcpIp = "";
- StringBuilder stringBuilder = new StringBuilder();
- dhcpIp = SystemPropertiesHelper.get("dhcp." + ETH0 + ".ipaddress");
- stringBuilder.append("ipaddr:").append(dhcpIp).append(" \n");
- stringBuilder.append("gateway:").append(SystemPropertiesHelper.get("dhcp." + ETH0 + ".gateway")).append(" \n");
- stringBuilder.append("mask:").append(SystemPropertiesHelper.get("dhcp." + ETH0 + ".mask")).append(" \n");
- stringBuilder.append("dns1:").append(SystemPropertiesHelper.get("dhcp." + ETH0 + ".dns1")).append(" \n");
- stringBuilder.append("dns2:").append(SystemPropertiesHelper.get("dhcp." + ETH0 + ".dns2")).append(" \n");
- Log.d("TAG", stringBuilder.toString());
- return dhcpIp;
- }
-}
diff --git a/library/src/main/java/org/davy/commons/SystemPropertiesHelper.java b/library/src/main/java/org/davy/commons/SystemPropertiesHelper.java
deleted file mode 100644
index bdc4738..0000000
--- a/library/src/main/java/org/davy/commons/SystemPropertiesHelper.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.davy.commons;
-
-import java.lang.reflect.Method;
-
-/**
- * 反射调用SystemProperties
- * Created by davy on 2017/6/7.
- */
-
-public class SystemPropertiesHelper {
- private static Class> mClassType = null;
- private static Method mGetMethod = null;
- private static Method mGetIntMethod = null;
-
- private static void init() {
- try {
- if (mClassType == null) {
- mClassType = Class.forName("android.os.SystemProperties");
- mGetMethod = mClassType.getDeclaredMethod("get", String.class);
- mGetIntMethod = mClassType.getDeclaredMethod("getInt", String.class, int.class);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public static String get(String key) {
- init();
- String value = null;
- try {
- value = (String) mGetMethod.invoke(mClassType, key);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return value;
- }
-}
diff --git a/library/src/main/java/org/greenleaf/utils/AppUtils.java b/library/src/main/java/org/greenleaf/utils/AppUtils.java
new file mode 100644
index 0000000..af054b6
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/AppUtils.java
@@ -0,0 +1,148 @@
+package org.greenleaf.utils;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+
+import java.util.List;
+
+public class AppUtils {
+
+ public static String getVersionName(Context context) {
+ PackageInfo info;
+ try {
+ info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ return info.versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ public static int getVersionCode(Context context) {
+ PackageInfo info;
+ try {
+ info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
+ return info.versionCode;
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return 0;
+ }
+
+ public static String getPackageName(Context context) {
+ return context.getPackageName();
+ }
+
+ public static Drawable getIcon(Context context) {
+ return getAppIcon(context, getPackageName(context));
+ }
+
+ public static Drawable getAppIcon(Context context, String packageName) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
+ return info.loadIcon(pm);
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String getAppVersionName(Context context, String packageName) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
+ return packageInfo.versionName;
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static int getAppVersionCode(Context context, String packageName) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ PackageInfo packageInfo = pm.getPackageInfo(packageName, 0);
+ return packageInfo.versionCode;
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return -1;
+ }
+
+ public static String getAppName(Context context, String packageName) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
+ return info.loadLabel(pm).toString();
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String[] getAppPermission(Context context, String packageName) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
+ return packageInfo.requestedPermissions;
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String getAppSignature(Context context, String packageName) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+ return packageInfo.signatures[0].toCharsString();
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static boolean isApkDebuggable(Context context) {
+ try {
+ ApplicationInfo info = context.getApplicationInfo();
+ return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+ } catch (Exception e) {
+
+ }
+ return false;
+ }
+
+ public static boolean isApkDebugable(Context context, String packageName) {
+ try {
+ PackageInfo pkginfo = context.getPackageManager().getPackageInfo(
+ packageName, PackageManager.GET_ACTIVITIES);
+ if (pkginfo != null) {
+ ApplicationInfo info = pkginfo.applicationInfo;
+ return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+ }
+ } catch (Exception e) {
+ }
+ return false;
+ }
+
+ public static boolean isAppInBackground(Context context) {
+ ActivityManager am = (ActivityManager) context
+ .getSystemService(Context.ACTIVITY_SERVICE);
+ List taskList = am.getRunningTasks(1);
+ if (taskList != null && !taskList.isEmpty()) {
+ ComponentName topActivity = taskList.get(0).topActivity;
+ if (topActivity != null
+ && !topActivity.getPackageName().equals(
+ context.getPackageName())) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/library/src/main/java/org/greenleaf/utils/AssetsUtils.java b/library/src/main/java/org/greenleaf/utils/AssetsUtils.java
new file mode 100644
index 0000000..b02141b
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/AssetsUtils.java
@@ -0,0 +1,77 @@
+package org.greenleaf.utils;
+
+import android.content.Context;
+import android.content.res.AssetManager;
+import android.support.annotation.NonNull;
+import android.support.annotation.WorkerThread;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+/**
+ * Assets操作
+ */
+public class AssetsUtils {
+ private static final String ENCODING = "UTF-8";
+
+ public static InputStream getFileFromAssets(@NonNull Context context, String fileName) throws IOException {
+ AssetManager am = context.getAssets();
+ return am.open(fileName);
+ }
+
+ @WorkerThread
+ public static String asset2String(@NonNull Context context, String fileName) {
+
+ StringBuilder stringBuilder = new StringBuilder();
+
+ InputStream inputStream = null;
+ BufferedInputStream bufferedInputStream = null;
+ InputStreamReader inputStreamReader = null;
+ BufferedReader bufReader = null;
+
+ try {
+ inputStream = getFileFromAssets(context, fileName);
+ bufferedInputStream = new BufferedInputStream(inputStream);
+ inputStreamReader = new InputStreamReader(bufferedInputStream);
+ bufReader = new BufferedReader(inputStreamReader);
+
+ String line;
+ StringBuilder result = new StringBuilder();
+ while ((line = bufReader.readLine()) != null) {
+ result.append(line);
+ }
+ } catch (IOException e) {
+ // ignore
+ } finally {
+ IOUtils.closeQuietly(inputStream, bufferedInputStream, inputStreamReader, bufReader);
+ }
+ return stringBuilder.toString();
+ }
+
+ @WorkerThread
+ public static void copyAssetsFile(@NonNull Context context, @NonNull final String assetsFileName, @NonNull final String destFilePath) throws IOException {
+
+ InputStream inputStream = null;
+ FileOutputStream fileOutputStream = null;
+ try {
+
+ File desFile = new File(destFilePath);
+ if (desFile.exists()) {
+ return;
+ }
+
+ fileOutputStream = new FileOutputStream(desFile);
+ inputStream = getFileFromAssets(context, assetsFileName);
+ IOUtils.copy(inputStream, fileOutputStream);
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ IOUtils.closeQuietly(inputStream, fileOutputStream);
+ }
+ }
+}
diff --git a/library/src/main/java/org/greenleaf/utils/Base64Utils.java b/library/src/main/java/org/greenleaf/utils/Base64Utils.java
new file mode 100644
index 0000000..b3e8d02
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/Base64Utils.java
@@ -0,0 +1,26 @@
+package org.greenleaf.utils;
+
+import android.util.Base64;
+
+/**
+ * bese64的转换
+ */
+
+public class Base64Utils {
+
+ public static byte[] encode(byte[] input) {
+ return Base64.encode(input, Base64.DEFAULT);
+ }
+
+ public static String encode(String s) {
+ return Base64.encodeToString(s.getBytes(), Base64.DEFAULT);
+ }
+
+ public static byte[] decode(byte[] input) {
+ return Base64.decode(input, Base64.DEFAULT);
+ }
+
+ public static String decode(String s) {
+ return new String(Base64.decode(s, Base64.DEFAULT));
+ }
+}
diff --git a/library/src/main/java/org/greenleaf/utils/BitmapUtils.java b/library/src/main/java/org/greenleaf/utils/BitmapUtils.java
new file mode 100644
index 0000000..a3bc6ef
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/BitmapUtils.java
@@ -0,0 +1,67 @@
+package org.greenleaf.utils;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.view.View;
+
+public class BitmapUtils {
+
+ public static final int UNSPECIFIED = 0;
+
+ public static Bitmap convertViewToBitmap(View view, int width, int height) {
+ view.measure(View.MeasureSpec.makeMeasureSpec(width, (width == UNSPECIFIED) ? View.MeasureSpec.UNSPECIFIED :
+ View.MeasureSpec.EXACTLY),
+ View.MeasureSpec.makeMeasureSpec(height, (height == UNSPECIFIED) ? View.MeasureSpec.UNSPECIFIED :
+ View.MeasureSpec.EXACTLY));
+ view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
+ Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
+ view.draw(new Canvas(bitmap));
+ return bitmap;
+ }
+
+ public static Bitmap convertViewToBitmap(View view) {
+ return convertViewToBitmap(view, UNSPECIFIED, UNSPECIFIED);
+ }
+
+ public static Bitmap convertGreyImg(Bitmap img) {
+ int width = img.getWidth(); // 获取位图的宽
+ int height = img.getHeight(); // 获取位图的高
+
+ int[] pixels = new int[width * height]; // 通过位图的大小创建像素点数组
+
+ img.getPixels(pixels, 0, width, 0, 0, width, height);
+ int alpha = 0xFF << 24;
+ for (int i = 0; i < height; i++) {
+ for (int j = 0; j < width; j++) {
+ int grey = pixels[width * i + j];
+
+ int red = ((grey & 0x00FF0000) >> 16);
+ int green = ((grey & 0x0000FF00) >> 8);
+ int blue = (grey & 0x000000FF);
+
+ grey = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);
+ grey = alpha | (grey << 16) | (grey << 8) | grey;
+ pixels[width * i + j] = grey;
+ }
+ }
+ Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
+ result.setPixels(pixels, 0, width, 0, 0, width, height);
+ return result;
+ }
+
+ public static Bitmap reverseHorizontal(Bitmap bitmap) {
+ Matrix matrix = new Matrix();
+ matrix.preScale(-1, 1);
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
+ bitmap.getHeight(), matrix, false);
+ }
+
+ public static Bitmap reverseVertical(Bitmap bitmap) {
+ Matrix matrix = new Matrix();
+ matrix.preScale(1, -1);
+ return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
+ bitmap.getHeight(), matrix, false);
+ }
+
+}
diff --git a/library/src/main/java/org/davy/commons/ByteUtil.java b/library/src/main/java/org/greenleaf/utils/ByteUtil.java
similarity index 81%
rename from library/src/main/java/org/davy/commons/ByteUtil.java
rename to library/src/main/java/org/greenleaf/utils/ByteUtil.java
index 66a8251..a9ecdd1 100644
--- a/library/src/main/java/org/davy/commons/ByteUtil.java
+++ b/library/src/main/java/org/greenleaf/utils/ByteUtil.java
@@ -1,16 +1,18 @@
-package org.davy.commons;
+package org.greenleaf.utils;
import java.util.Locale;
public class ByteUtil {
+
private final static byte[] EMPTY_BYTES = new byte[]{};
private final static char[] mChars = "0123456789ABCDEF".toCharArray();
public static String bytes2HexStr(byte[] bytes, int start, int length) {
+
if (bytes == null || bytes.length == 0 || start > bytes.length || start + length > bytes.length) {
return "";
}
- int position = 1;
+
StringBuilder builder = new StringBuilder();
for (int i = start; i < start + length; i++) {
builder.append(mChars[(bytes[i] & 0xFF) >> 4]);
@@ -21,23 +23,19 @@ public static String bytes2HexStr(byte[] bytes, int start, int length) {
}
public static String bytes2HexStr(byte[] bytes) {
+
if (bytes == null || bytes.length == 0) {
return "";
}
- StringBuilder builder = new StringBuilder();
- for (byte b : bytes) {
- builder.append(mChars[(b & 0xFF) >> 4]);
- builder.append(mChars[b & 0x0F]);
- builder.append(" ");
- }
- return builder.toString();
+
+ return bytes2HexStr(bytes, 0, bytes.length);
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
- public static byte[] hexString2Bytes(String hexString) {
+ public static byte[] str2Bytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return EMPTY_BYTES;
}
diff --git a/library/src/main/java/org/greenleaf/utils/CollectionUtils.java b/library/src/main/java/org/greenleaf/utils/CollectionUtils.java
new file mode 100644
index 0000000..a08ad51
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/CollectionUtils.java
@@ -0,0 +1,43 @@
+package org.greenleaf.utils;
+
+import android.text.TextUtils;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 集合工具类
+ */
+public class CollectionUtils {
+ private static final String DELIMITER = ",";
+
+ public static boolean isEmpty(Collection c) {
+ return (c == null || c.isEmpty());
+ }
+
+ public static boolean isNotEmpty(Collection c) {
+ return !isEmpty(c);
+ }
+
+ public static String join(Iterable tokens) {
+ return tokens == null ? "" : TextUtils.join(DELIMITER, tokens);
+ }
+
+ public static List asList(T... array) {
+ return Arrays.asList(array);
+ }
+
+ public static Set asSet(T... array) {
+ return new HashSet(asList(array));
+ }
+
+ public static Object[] asArray(Collection> c) {
+ if (!isEmpty(c)) {
+ return c.toArray();
+ }
+ return null;
+ }
+}
diff --git a/library/src/main/java/org/greenleaf/utils/DisplayUtils.java b/library/src/main/java/org/greenleaf/utils/DisplayUtils.java
new file mode 100644
index 0000000..f0524e2
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/DisplayUtils.java
@@ -0,0 +1,69 @@
+package org.greenleaf.utils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Rect;
+import android.support.annotation.NonNull;
+import android.util.DisplayMetrics;
+
+public class DisplayUtils {
+
+ public static int getScreenWidth(Context context) {
+ DisplayMetrics dm = context.getResources().getDisplayMetrics();
+ return dm.widthPixels;
+ }
+
+ public static int getScreenHeight(Context context) {
+ DisplayMetrics dm = context.getResources().getDisplayMetrics();
+ return dm.heightPixels;
+ }
+
+ public static float getScreenDensity(Context context) {
+ DisplayMetrics dm = context.getResources().getDisplayMetrics();
+ return dm.density;
+ }
+
+ public static int getScreenDensityDPI(Context context) {
+ DisplayMetrics dm = context.getResources().getDisplayMetrics();
+ return dm.densityDpi;
+ }
+
+ public static int getStatusBarHeight(@NonNull Activity activity) {
+ Rect rect = new Rect();
+ activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
+ int statusBarHeight = rect.top;
+ if (0 == statusBarHeight) {
+ Class> localClass;
+ try {
+ localClass = Class.forName("com.android.internal.R$dimen");
+ Object localObject = localClass.newInstance();
+ int id = Integer.parseInt(localClass.getField("status_bar_height").get(localObject).toString());
+ statusBarHeight = activity.getResources().getDimensionPixelSize(id);
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InstantiationException e) {
+ e.printStackTrace();
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ }
+ }
+ return statusBarHeight;
+ }
+
+ public static int dip2px(Context context, float dipValue){
+ final float scale = context.getResources().getDisplayMetrics().density;
+ return (int)(dipValue * scale + 0.5f);
+ }
+ public static int px2dip(Context context, float pxValue){
+ final float scale = context.getResources().getDisplayMetrics().density;
+ return (int)(pxValue / scale + 0.5f);
+ }
+}
diff --git a/library/src/main/java/org/greenleaf/utils/DumpUtils.java b/library/src/main/java/org/greenleaf/utils/DumpUtils.java
new file mode 100644
index 0000000..3123407
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/DumpUtils.java
@@ -0,0 +1,27 @@
+package org.greenleaf.utils;
+
+public class DumpUtils {
+
+ private DumpUtils() {
+ }
+
+ public static int getLineNumber( ){
+ StackTraceElement[] stackTrace = new Throwable().getStackTrace();
+ return stackTrace[1].getLineNumber( );
+ }
+
+ public static String getMethodName( ){
+ StackTraceElement[] stackTrace = new Throwable().getStackTrace();
+ return stackTrace[1].getMethodName( );
+ }
+
+ public static String getFileName( ){
+ StackTraceElement[] stackTrace = new Throwable().getStackTrace();
+ return stackTrace[1].getFileName( );
+ }
+
+ public static String getClassName( ){
+ StackTraceElement[] stackTrace = new Throwable().getStackTrace();
+ return stackTrace[1].getClassName();
+ }
+}
\ No newline at end of file
diff --git a/library/src/main/java/org/davy/commons/FileUtils.java b/library/src/main/java/org/greenleaf/utils/FileUtils.java
similarity index 94%
rename from library/src/main/java/org/davy/commons/FileUtils.java
rename to library/src/main/java/org/greenleaf/utils/FileUtils.java
index 8e15281..abb6cf3 100644
--- a/library/src/main/java/org/davy/commons/FileUtils.java
+++ b/library/src/main/java/org/greenleaf/utils/FileUtils.java
@@ -1,20 +1,4 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.davy.commons;
+package org.greenleaf.utils;
import java.io.File;
import java.io.FileFilter;
diff --git a/library/src/main/java/org/davy/commons/IOUtils.java b/library/src/main/java/org/greenleaf/utils/IOUtils.java
similarity index 63%
rename from library/src/main/java/org/davy/commons/IOUtils.java
rename to library/src/main/java/org/greenleaf/utils/IOUtils.java
index ee80f4e..f27cd74 100644
--- a/library/src/main/java/org/davy/commons/IOUtils.java
+++ b/library/src/main/java/org/greenleaf/utils/IOUtils.java
@@ -1,20 +1,4 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.davy.commons;
+package org.greenleaf.utils;
import java.io.Closeable;
import java.io.IOException;
@@ -37,7 +21,13 @@ public static void closeQuietly(final Closeable... closeables) {
return;
}
for (final Closeable closeable : closeables) {
- closeQuietly(closeable);
+ try {
+ if (closeable != null) {
+ closeable.close();
+ }
+ } catch (final IOException ioe) {
+ // ignore
+ }
}
}
diff --git a/library/src/main/java/org/greenleaf/utils/MD5Utils.java b/library/src/main/java/org/greenleaf/utils/MD5Utils.java
new file mode 100644
index 0000000..3f47a95
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/MD5Utils.java
@@ -0,0 +1,40 @@
+package org.greenleaf.utils;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ *
+ * MD5工具类
+ */
+
+public class MD5Utils {
+
+ private MD5Utils() {
+ }
+
+ public static String encode(String s) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("MD5");
+ digest.update(s.getBytes());
+ byte messageDigest[] = digest.digest();
+ return ByteUtil.bytes2HexStr(messageDigest);
+ } catch (NoSuchAlgorithmException e) {
+ //ignore
+ }
+ return "";
+ }
+
+ public static String encode(byte[] bytes) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("MD5");
+ digest.update(bytes);
+ byte messageDigest[] = digest.digest();
+ return ByteUtil.bytes2HexStr(messageDigest);
+ } catch (NoSuchAlgorithmException e) {
+ //ignore
+ }
+ return "";
+ }
+
+}
diff --git a/library/src/main/java/org/greenleaf/utils/NetworkUtil.java b/library/src/main/java/org/greenleaf/utils/NetworkUtil.java
new file mode 100644
index 0000000..02f015d
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/NetworkUtil.java
@@ -0,0 +1,58 @@
+package org.greenleaf.utils;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.support.annotation.NonNull;
+import android.support.annotation.WorkerThread;
+
+import java.io.IOException;
+
+/**
+ * Created by davy on 2017/5/23.
+ */
+
+public class NetworkUtil {
+
+ private static final String TAG = "NetworkUtil";
+
+ private static final String ETHERNET_USE_STATIC_IP = "ethernet_use_static_ip";
+ private static final String ETHERNET_STATIC_IP = "ethernet_static_ip";
+ private static final String ETHERNET_STATIC_GATEWAY = "ethernet_static_gateway";
+ private static final String ETHERNET_STATIC_NETMASK = "ethernet_static_netmask";
+ private static final String ETHERNET_STATIC_DNS1 = "ethernet_static_dns1";
+ private static final String ETHERNET_STATIC_DNS2 = "ethernet_static_dns2";
+ private static final String ETH0 = "eth0";
+
+ public static boolean isConnected(Context context) {
+ ConnectivityManager connManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = connManager.getActiveNetworkInfo();
+ if (networkInfo != null) {
+ return networkInfo.isAvailable();
+ }
+ return false;
+ }
+
+ public static boolean isEthernetConnected(Context context) {
+ ConnectivityManager connManager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo networkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_ETHERNET);
+ if (networkInfo != null) {
+ return networkInfo.isAvailable();
+ }
+ return false;
+ }
+
+ @WorkerThread
+ public static boolean pingToken(@NonNull String urlNoHttpOrIp) {
+ Runtime runtime = Runtime.getRuntime();
+
+ try {
+ Process e = runtime.exec("/system/bin/ping -c 1 " + urlNoHttpOrIp);
+ int exitValue = e.waitFor();
+ return exitValue == 0;
+ } catch (InterruptedException | IOException var4) {
+ //ignore
+ return false;
+ }
+ }
+}
diff --git a/library/src/main/java/org/greenleaf/utils/NumberUtils.java b/library/src/main/java/org/greenleaf/utils/NumberUtils.java
new file mode 100644
index 0000000..b6eac4f
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/NumberUtils.java
@@ -0,0 +1,18 @@
+package org.greenleaf.utils;
+
+import java.text.DecimalFormat;
+
+public class NumberUtils {
+
+ private static final DecimalFormat oneDec = new DecimalFormat("##0.0");
+ private static final DecimalFormat twoDec = new DecimalFormat("##0.00");
+
+ public static String formatOneDecimal(float number) {
+ return oneDec.format(number);
+ }
+
+ public static String formatTwoDecimal(float number) {
+ DecimalFormat twoDec = new DecimalFormat("##0.00");
+ return twoDec.format(number);
+ }
+}
diff --git a/library/src/main/java/org/greenleaf/utils/ObjectUtils.java b/library/src/main/java/org/greenleaf/utils/ObjectUtils.java
new file mode 100644
index 0000000..be9447e
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/ObjectUtils.java
@@ -0,0 +1,8 @@
+package org.greenleaf.utils;
+
+public class ObjectUtils {
+
+ public static boolean equals(Object a, Object b) {
+ return a != null && a.equals(b);
+ }
+}
diff --git a/library/src/main/java/org/greenleaf/utils/PackageUtils.java b/library/src/main/java/org/greenleaf/utils/PackageUtils.java
new file mode 100644
index 0000000..78ff4d5
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/PackageUtils.java
@@ -0,0 +1,133 @@
+package org.greenleaf.utils;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.support.annotation.NonNull;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class PackageUtils {
+
+ public static boolean checkPermission(@NonNull Context context, String permName, String pkgName) {
+ PackageManager pm = context.getPackageManager();
+ return (PackageManager.PERMISSION_GRANTED == pm.checkPermission(permName, pkgName));
+ }
+
+ public static boolean checkPermission(@NonNull Context context, String permName) {
+ int perm = context.checkCallingOrSelfPermission(permName);
+ return perm == PackageManager.PERMISSION_GRANTED;
+ }
+
+ public static boolean install(@NonNull Context context, String filePath) {
+ File file = new File(filePath);
+ if (!file.exists() || !file.isFile() || file.length() <= 0) {
+ return false;
+ }
+
+ Intent i = new Intent(Intent.ACTION_VIEW);
+ i.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(i);
+ return true;
+ }
+
+ public static boolean uninstall(Context context, String packageName) {
+ if (packageName == null || packageName.length() == 0) {
+ return false;
+ }
+
+ Intent i = new Intent(Intent.ACTION_DELETE, Uri.parse(new StringBuilder(32).append("package:")
+ .append(packageName).toString()));
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ context.startActivity(i);
+ return true;
+ }
+
+ public static boolean isSystemApplication(Context context) {
+ if (context == null) {
+ return false;
+ }
+ return isSystemApplication(context, context.getPackageName());
+ }
+
+ public static boolean isSystemApplication(Context context, String packageName) {
+ if (context == null) {
+ return false;
+ }
+ return isSystemApplication(context.getPackageManager(), packageName);
+ }
+
+ public static boolean isSystemApplication(PackageManager packageManager, String packageName) {
+ if (packageManager == null || packageName == null || packageName.length() == 0) {
+ return false;
+ }
+ try {
+ ApplicationInfo app = packageManager.getApplicationInfo(packageName, 0);
+ return (app != null && (app.flags & ApplicationInfo.FLAG_SYSTEM) > 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+ /**
+ * 获取所有安装包信息
+ */
+ public static List getInstalledPackageInfos(Context context) {
+ return context.getPackageManager().getInstalledPackages(0);
+ }
+
+ public static List getThirdPartyAllApps(Context context) {
+ List apps = new ArrayList();
+ PackageManager packageManager = context.getPackageManager();
+ List packageInfos = packageManager.getInstalledPackages(0);
+ for (int i = 0; i < packageInfos.size(); i++) {
+ PackageInfo pak = packageInfos.get(i);
+ if ((pak.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != ApplicationInfo.FLAG_SYSTEM) {
+ apps.add(pak);
+ }
+ }
+ return apps;
+ }
+
+ public static void startApp(Context context, String packageName) {
+ PackageInfo packageinfo = null;
+ try {
+ packageinfo = context.getPackageManager().getPackageInfo(packageName, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+ if (packageinfo == null) {
+ return;
+ }
+
+ Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
+ resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ resolveIntent.setPackage(packageinfo.packageName);
+
+ List resolveinfoList = context.getPackageManager()
+ .queryIntentActivities(resolveIntent, 0);
+
+ ResolveInfo resolveinfo = resolveinfoList.iterator().next();
+ if (resolveinfo != null) {
+ String pkgName = resolveinfo.activityInfo.packageName;
+ String className = resolveinfo.activityInfo.name;
+
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+ ComponentName cn = new ComponentName(pkgName, className);
+ intent.setComponent(cn);
+ context.startActivity(intent);
+ }
+ }
+}
diff --git a/library/src/main/java/org/greenleaf/utils/RandomUtils.java b/library/src/main/java/org/greenleaf/utils/RandomUtils.java
new file mode 100644
index 0000000..92c2120
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/RandomUtils.java
@@ -0,0 +1,59 @@
+package org.greenleaf.utils;
+
+import java.util.Random;
+
+/**
+ * 随机数操作类
+ */
+
+public class RandomUtils {
+
+ public static int randomInt() {
+ Random random = new Random();
+ return random.nextInt();
+ }
+
+ public static int randomInt(int n) {
+ Random random = new Random();
+ return random.nextInt(n);
+ }
+
+ public static int randomInt(int min, int max) {
+ Random random = new Random();
+ return random.nextInt(max) % (max - min + 1) + min;
+ }
+
+
+ public static float randomFloat() {
+ Random random = new Random();
+ return random.nextFloat();
+ }
+
+ public static double randomDouble() {
+ Random random = new Random();
+ return random.nextDouble();
+ }
+
+
+ public static long randomLong() {
+ Random random = new Random();
+ return random.nextLong();
+ }
+
+
+ public static boolean randomBoolean() {
+ Random random = new Random();
+ return random.nextBoolean();
+ }
+
+
+ public static double randomGaussian() {
+ Random random = new Random();
+ return random.nextGaussian();
+ }
+
+ public static void randomBytes(byte[] buf) {
+ Random random = new Random();
+ random.nextBytes(buf);
+ }
+}
diff --git a/library/src/main/java/org/davy/commons/RegUtil.java b/library/src/main/java/org/greenleaf/utils/RegexUtils.java
similarity index 50%
rename from library/src/main/java/org/davy/commons/RegUtil.java
rename to library/src/main/java/org/greenleaf/utils/RegexUtils.java
index ac01fac..5d4fa52 100644
--- a/library/src/main/java/org/davy/commons/RegUtil.java
+++ b/library/src/main/java/org/greenleaf/utils/RegexUtils.java
@@ -1,6 +1,4 @@
-package org.davy.commons;
-
-import android.text.TextUtils;
+package org.greenleaf.utils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -9,7 +7,28 @@
* Created by davy on 2017/5/18.
*/
-public class RegUtil {
+public class RegexUtils {
+
+ public static boolean isEmail(String email) {
+ Pattern pattern = Pattern
+ .compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)" +
+ "+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
+ Matcher matcher = pattern.matcher(email);
+ return matcher.matches();
+ }
+
+ public static boolean isMobileNumber(String number) {
+ String expr = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
+ return number.matches(expr);
+ }
+
+ public static boolean isUrl(String url) {
+ String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
+ Pattern patt = Pattern.compile(regex);
+ Matcher matcher = patt.matcher(url);
+ return matcher.matches();
+ }
+
public static boolean isIp(String str) {
if (str == null || str.trim().equals("")) {
return false;
diff --git a/library/src/main/java/org/greenleaf/utils/SHA1Utils.java b/library/src/main/java/org/greenleaf/utils/SHA1Utils.java
new file mode 100644
index 0000000..510a354
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/SHA1Utils.java
@@ -0,0 +1,36 @@
+package org.greenleaf.utils;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * SHA1 操作类
+ */
+
+public class SHA1Utils {
+
+ public static String encode(String s) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA-1");
+ digest.update(s.getBytes());
+ byte messageDigest[] = digest.digest();
+ return ByteUtil.bytes2HexStr(messageDigest);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+ public static String encode(byte[] bytes) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA-1");
+ digest.update(bytes);
+ byte messageDigest[] = digest.digest();
+ return ByteUtil.bytes2HexStr(messageDigest);
+ } catch (NoSuchAlgorithmException e) {
+ e.printStackTrace();
+ }
+ return "";
+ }
+
+}
diff --git a/library/src/main/java/org/greenleaf/utils/SPUtil.java b/library/src/main/java/org/greenleaf/utils/SPUtil.java
new file mode 100644
index 0000000..bc31a3c
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/SPUtil.java
@@ -0,0 +1,87 @@
+package org.greenleaf.utils;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.support.annotation.NonNull;
+
+import java.util.Map;
+
+public class SPUtil {
+
+ public static final String FILE_NAME = "share_data";
+
+ public static void put(@NonNull Context context, String key, Object object) {
+
+ SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sp.edit();
+
+ if (object instanceof String) {
+ editor.putString(key, (String) object);
+ } else if (object instanceof Integer) {
+ editor.putInt(key, (Integer) object);
+ } else if (object instanceof Boolean) {
+ editor.putBoolean(key, (Boolean) object);
+ } else if (object instanceof Float) {
+ editor.putFloat(key, (Float) object);
+ } else if (object instanceof Long) {
+ editor.putLong(key, (Long) object);
+ } else {
+ editor.putString(key, object.toString());
+ }
+ editor.apply();
+ }
+
+ public static Object get(Context context, String key, Object defaultObject) {
+ SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
+ Context.MODE_PRIVATE);
+
+ if (defaultObject instanceof String) {
+ return sp.getString(key, (String) defaultObject);
+ } else if (defaultObject instanceof Integer) {
+ return sp.getInt(key, (Integer) defaultObject);
+ } else if (defaultObject instanceof Boolean) {
+ return sp.getBoolean(key, (Boolean) defaultObject);
+ } else if (defaultObject instanceof Float) {
+ return sp.getFloat(key, (Float) defaultObject);
+ } else if (defaultObject instanceof Long) {
+ return sp.getLong(key, (Long) defaultObject);
+ }
+ return null;
+ }
+
+ public static void remove(Context context, String key) {
+ SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.remove(key);
+ }
+
+ /**
+ * 清除所有数据
+ */
+ public static void clear(Context context) {
+ SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
+ Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = sp.edit();
+ editor.clear();
+ }
+
+ /**
+ * 查询某个key是否已经存在
+ */
+ public static boolean contains(Context context, String key) {
+ SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
+ Context.MODE_PRIVATE);
+ return sp.contains(key);
+ }
+
+ /**
+ * 返回所有的键值对
+ */
+ public static Map getAll(Context context) {
+ SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
+ Context.MODE_PRIVATE);
+ return sp.getAll();
+ }
+}
diff --git a/library/src/main/java/org/davy/commons/StringUtil.java b/library/src/main/java/org/greenleaf/utils/StringUtil.java
similarity index 56%
rename from library/src/main/java/org/davy/commons/StringUtil.java
rename to library/src/main/java/org/greenleaf/utils/StringUtil.java
index d2ba284..9acc1d0 100644
--- a/library/src/main/java/org/davy/commons/StringUtil.java
+++ b/library/src/main/java/org/greenleaf/utils/StringUtil.java
@@ -1,6 +1,7 @@
-package org.davy.commons;
+package org.greenleaf.utils;
public class StringUtil {
+
/**
* 获取字符串的字节数目
* @param str JAVA字符串的值
@@ -50,4 +51,42 @@ public static boolean isChinese(char c) {
}
return false;
}
+
+ public static boolean isEmpty(final CharSequence s) {
+ return s == null || s.length() == 0;
+ }
+
+ public static boolean isTrimEmpty(final String s) {
+ return (s == null || s.trim().length() == 0);
+ }
+
+ public static boolean isSpace(final String s) {
+ if (s == null) return true;
+ for (int i = 0, len = s.length(); i < len; ++i) {
+ if (!Character.isWhitespace(s.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static boolean equals(final CharSequence s1, final CharSequence s2) {
+ if (s1 == s2) return true;
+ int length;
+ if (s1 != null && s2 != null && (length = s1.length()) == s2.length()) {
+ if (s1 instanceof String && s2 instanceof String) {
+ return s1.equals(s2);
+ } else {
+ for (int i = 0; i < length; i++) {
+ if (s1.charAt(i) != s2.charAt(i)) return false;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean equalsIgnoreCase(final String s1, final String s2) {
+ return s1 == null ? s2 == null : s1.equalsIgnoreCase(s2);
+ }
}
diff --git a/library/src/main/java/org/greenleaf/utils/SystemUtils.java b/library/src/main/java/org/greenleaf/utils/SystemUtils.java
new file mode 100644
index 0000000..1da31dc
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/SystemUtils.java
@@ -0,0 +1,116 @@
+package org.greenleaf.utils;
+
+import android.os.Build;
+
+/**
+ * 获取系统信息工具类
+ */
+public class SystemUtils {
+
+ /**
+ * ART
+ */
+ public static boolean isART() {
+ final String vmVersion = System.getProperty("java.vm.version");
+ return vmVersion != null && vmVersion.startsWith("2");
+ }
+
+ /**
+ * DALVIK
+ */
+ public static boolean isDalvik() {
+ final String vmVersion = System.getProperty("java.vm.version");
+ return vmVersion != null && vmVersion.startsWith("1");
+ }
+
+ /**
+ * The brand
+ */
+ public static String getBrand() {
+ return Build.BRAND;
+ }
+
+ /**
+ * The board
+ */
+ public static String getBoard() {
+ return Build.BOARD;
+ }
+
+ /**
+ * The end-user-visible name for the end product, like "MI-ONE Plus".
+ */
+ public static String getModel() {
+ return Build.MODEL;
+ }
+
+ /**
+ * Either a changelist number, or a label like "JZO54K".
+ */
+ public static String getID() {
+ return Build.ID;
+ }
+
+ /**
+ * The user-visible version string, like "4.1.2".
+ */
+ public static String getVersionRelease() {
+ return Build.VERSION.RELEASE;
+ }
+
+ /**
+ * The user-visible SDK version of the framework.
+ */
+ public static int getVersionSDK() {
+ return Build.VERSION.SDK_INT;
+ }
+
+ /**
+ * A string that uniquely identifies this build. Do not attempt to parse this value.
+ */
+ public static String getFingerPrint() {
+ return Build.FINGERPRINT;
+ }
+
+ /**
+ * The name of the overall product, like "mione_plus".
+ */
+ public static String getProduct() {
+ return Build.PRODUCT;
+ }
+
+ /**
+ * The manufacturer of the product/hardware, like "Xiaomi".
+ */
+ public static String getManufacturer() {
+ return Build.MANUFACTURER;
+ }
+
+ /**
+ * The name of the industrial design, like "mione_plus".
+ */
+ public static String getDevice() {
+ return Build.DEVICE;
+ }
+
+ /**
+ * The name of the instruction set (CPU type + ABI convention) of native code, like "armeabi-v7a".
+ */
+ public static String getCpuAbi() {
+ return Build.CPU_ABI;
+ }
+
+ /**
+ * The name of the second instruction set (CPU type + ABI convention) of native code, like "armeabi".
+ */
+ public static String getCpuAbi2() {
+ return Build.CPU_ABI2;
+ }
+
+ /**
+ * A build ID string meant for displaying to the user, like "JZO54K".
+ */
+ public static String getDisplay() {
+ return Build.DISPLAY;
+ }
+}
diff --git a/library/src/main/java/org/greenleaf/utils/ToastUtil.java b/library/src/main/java/org/greenleaf/utils/ToastUtil.java
new file mode 100644
index 0000000..db06b64
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/ToastUtil.java
@@ -0,0 +1,32 @@
+package org.greenleaf.utils;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.StringRes;
+import android.widget.Toast;
+
+/**
+ * Toast封装类
+ */
+public class ToastUtil {
+
+ private static Toast toast;
+
+ public static void showToast(@NonNull Context context, String text) {
+ if (toast == null) {
+ toast = Toast.makeText(context, text, Toast.LENGTH_SHORT);
+ } else {
+ toast.setText(text);
+ }
+ toast.show();
+ }
+
+ public static void showToast(@NonNull Context context, @StringRes int resId) {
+ if (toast == null) {
+ toast = Toast.makeText(context, context.getString(resId), Toast.LENGTH_SHORT);
+ } else {
+ toast.setText(context.getString(resId));
+ }
+ toast.show();
+ }
+}
diff --git a/library/src/main/java/org/davy/commons/XmlUtil.java b/library/src/main/java/org/greenleaf/utils/XmlUtil.java
similarity index 92%
rename from library/src/main/java/org/davy/commons/XmlUtil.java
rename to library/src/main/java/org/greenleaf/utils/XmlUtil.java
index e6a8741..b0ccbc6 100644
--- a/library/src/main/java/org/davy/commons/XmlUtil.java
+++ b/library/src/main/java/org/greenleaf/utils/XmlUtil.java
@@ -1,4 +1,4 @@
-package org.davy.commons;
+package org.greenleaf.utils;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
@@ -9,6 +9,10 @@
import javax.xml.parsers.DocumentBuilderFactory;
public class XmlUtil {
+
+ private XmlUtil() {
+ }
+
public static Document parserXml(String xmlString) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
diff --git a/library/src/main/java/org/greenleaf/utils/ZipUtils.java b/library/src/main/java/org/greenleaf/utils/ZipUtils.java
new file mode 100644
index 0000000..5adf418
--- /dev/null
+++ b/library/src/main/java/org/greenleaf/utils/ZipUtils.java
@@ -0,0 +1,409 @@
+package org.greenleaf.utils;
+
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+public final class ZipUtils {
+
+ private static final int BUFFER_LEN = 8192;
+
+ private ZipUtils() {
+ }
+
+ /**
+ * Zip the files.
+ */
+ public static boolean zipFiles(final Collection srcFiles,
+ final String zipFilePath)
+ throws IOException {
+ return zipFiles(srcFiles, zipFilePath, null);
+ }
+
+ /**
+ * Zip the files.
+ *
+ * @param srcFilePaths The paths of source files.
+ * @param zipFilePath The path of ZIP file.
+ * @param comment The comment.
+ */
+ public static boolean zipFiles(final Collection srcFilePaths,
+ final String zipFilePath,
+ final String comment)
+ throws IOException {
+ if (srcFilePaths == null || zipFilePath == null) return false;
+ ZipOutputStream zos = null;
+ try {
+ zos = new ZipOutputStream(new FileOutputStream(zipFilePath));
+ for (String srcFile : srcFilePaths) {
+ if (!zipFile(getFileByPath(srcFile), "", zos, comment)) return false;
+ }
+ return true;
+ } finally {
+ if (zos != null) {
+ zos.finish();
+ zos.close();
+ }
+ }
+ }
+
+ /**
+ * Zip the files.
+ */
+ public static boolean zipFiles(final Collection srcFiles, final File zipFile)
+ throws IOException {
+ return zipFiles(srcFiles, zipFile, null);
+ }
+
+ /**
+ * Zip the files.
+ *
+ * @param srcFiles The source of files.
+ * @param zipFile The ZIP file.
+ * @param comment The comment.
+ */
+ public static boolean zipFiles(final Collection srcFiles,
+ final File zipFile,
+ final String comment)
+ throws IOException {
+ if (srcFiles == null || zipFile == null) return false;
+ ZipOutputStream zos = null;
+ try {
+ zos = new ZipOutputStream(new FileOutputStream(zipFile));
+ for (File srcFile : srcFiles) {
+ if (!zipFile(srcFile, "", zos, comment)) return false;
+ }
+ return true;
+ } finally {
+ if (zos != null) {
+ zos.finish();
+ zos.close();
+ }
+ }
+ }
+
+ /**
+ * Zip the file.
+ *
+ * @param srcFilePath The path of source file.
+ * @param zipFilePath The path of ZIP file.
+ */
+ public static boolean zipFile(final String srcFilePath,
+ final String zipFilePath)
+ throws IOException {
+ return zipFile(getFileByPath(srcFilePath), getFileByPath(zipFilePath), null);
+ }
+
+ /**
+ * Zip the file.
+ *
+ * @param srcFilePath The path of source file.
+ * @param zipFilePath The path of ZIP file.
+ * @param comment The comment.
+ */
+ public static boolean zipFile(final String srcFilePath,
+ final String zipFilePath,
+ final String comment)
+ throws IOException {
+ return zipFile(getFileByPath(srcFilePath), getFileByPath(zipFilePath), comment);
+ }
+
+ /**
+ * Zip the file.
+ *
+ * @param srcFile The source of file.
+ * @param zipFile The ZIP file.
+ */
+ public static boolean zipFile(final File srcFile,
+ final File zipFile)
+ throws IOException {
+ return zipFile(srcFile, zipFile, null);
+ }
+
+ /**
+ * Zip the file.
+ *
+ * @param srcFile The source of file.
+ * @param zipFile The ZIP file.
+ * @param comment The comment.
+ */
+ public static boolean zipFile(final File srcFile,
+ final File zipFile,
+ final String comment)
+ throws IOException {
+ if (srcFile == null || zipFile == null) return false;
+ ZipOutputStream zos = null;
+ try {
+ zos = new ZipOutputStream(new FileOutputStream(zipFile));
+ return zipFile(srcFile, "", zos, comment);
+ } finally {
+ if (zos != null) {
+ zos.close();
+ }
+ }
+ }
+
+ private static boolean zipFile(final File srcFile,
+ String rootPath,
+ final ZipOutputStream zos,
+ final String comment)
+ throws IOException {
+ rootPath = rootPath + (isSpace(rootPath) ? "" : File.separator) + srcFile.getName();
+ if (srcFile.isDirectory()) {
+ File[] fileList = srcFile.listFiles();
+ if (fileList == null || fileList.length <= 0) {
+ ZipEntry entry = new ZipEntry(rootPath + '/');
+ entry.setComment(comment);
+ zos.putNextEntry(entry);
+ zos.closeEntry();
+ } else {
+ for (File file : fileList) {
+ if (!zipFile(file, rootPath, zos, comment)) return false;
+ }
+ }
+ } else {
+ InputStream is = null;
+ try {
+ is = new BufferedInputStream(new FileInputStream(srcFile));
+ ZipEntry entry = new ZipEntry(rootPath);
+ entry.setComment(comment);
+ zos.putNextEntry(entry);
+ byte buffer[] = new byte[BUFFER_LEN];
+ int len;
+ while ((len = is.read(buffer, 0, BUFFER_LEN)) != -1) {
+ zos.write(buffer, 0, len);
+ }
+ zos.closeEntry();
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Unzip the file.
+ *
+ * @param zipFilePath The path of ZIP file.
+ * @param destDirPath The path of destination directory.
+ */
+ public static List unzipFile(final String zipFilePath,
+ final String destDirPath)
+ throws IOException {
+ return unzipFileByKeyword(zipFilePath, destDirPath, null);
+ }
+
+ /**
+ * Unzip the file.
+ *
+ * @param zipFile The ZIP file.
+ * @param destDir The destination directory.
+ * @return the unzipped files
+ * @throws IOException if unzip unsuccessfully
+ */
+ public static List unzipFile(final File zipFile,
+ final File destDir)
+ throws IOException {
+ return unzipFileByKeyword(zipFile, destDir, null);
+ }
+
+ /**
+ * Unzip the file by keyword.
+ *
+ * @param zipFilePath The path of ZIP file.
+ * @param destDirPath The path of destination directory.
+ * @param keyword The keyboard.
+ * @return the unzipped files
+ * @throws IOException if unzip unsuccessfully
+ */
+ public static List unzipFileByKeyword(final String zipFilePath,
+ final String destDirPath,
+ final String keyword)
+ throws IOException {
+ return unzipFileByKeyword(getFileByPath(zipFilePath), getFileByPath(destDirPath), keyword);
+ }
+
+ /**
+ * Unzip the file by keyword.
+ *
+ * @param zipFile The ZIP file.
+ * @param destDir The destination directory.
+ * @param keyword The keyboard.
+ * @return the unzipped files
+ * @throws IOException if unzip unsuccessfully
+ */
+ public static List unzipFileByKeyword(final File zipFile,
+ final File destDir,
+ final String keyword)
+ throws IOException {
+ if (zipFile == null || destDir == null) return null;
+ List files = new ArrayList<>();
+ ZipFile zf = new ZipFile(zipFile);
+ Enumeration> entries = zf.entries();
+ if (isSpace(keyword)) {
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = ((ZipEntry) entries.nextElement());
+ String entryName = entry.getName();
+ if (entryName.contains("../")) {
+ Log.e("ZipUtils", "it's dangerous!");
+ return files;
+ }
+ if (!unzipChildFile(destDir, files, zf, entry, entryName)) return files;
+ }
+ } else {
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = ((ZipEntry) entries.nextElement());
+ String entryName = entry.getName();
+ if (entryName.contains("../")) {
+ Log.e("ZipUtils", "it's dangerous!");
+ return files;
+ }
+ if (entryName.contains(keyword)) {
+ if (!unzipChildFile(destDir, files, zf, entry, entryName)) return files;
+ }
+ }
+ }
+ return files;
+ }
+
+ private static boolean unzipChildFile(final File destDir,
+ final List files,
+ final ZipFile zf,
+ final ZipEntry entry,
+ final String entryName) throws IOException {
+ String filePath = destDir + File.separator + entryName;
+ File file = new File(filePath);
+ files.add(file);
+ if (entry.isDirectory()) {
+ if (!createOrExistsDir(file)) return false;
+ } else {
+ if (!createOrExistsFile(file)) return false;
+ InputStream in = null;
+ OutputStream out = null;
+ try {
+ in = new BufferedInputStream(zf.getInputStream(entry));
+ out = new BufferedOutputStream(new FileOutputStream(file));
+ byte buffer[] = new byte[BUFFER_LEN];
+ int len;
+ while ((len = in.read(buffer)) != -1) {
+ out.write(buffer, 0, len);
+ }
+ } finally {
+ if (in != null) {
+ in.close();
+ }
+ if (out != null) {
+ out.close();
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Return the files' path in ZIP file.
+ *
+ * @param zipFilePath The path of ZIP file.
+ * @return the files' path in ZIP file
+ * @throws IOException if an I/O error has occurred
+ */
+ public static List getFilesPath(final String zipFilePath)
+ throws IOException {
+ return getFilesPath(getFileByPath(zipFilePath));
+ }
+
+ /**
+ * Return the files' path in ZIP file.
+ *
+ * @param zipFile The ZIP file.
+ * @return the files' path in ZIP file
+ * @throws IOException if an I/O error has occurred
+ */
+ public static List getFilesPath(final File zipFile)
+ throws IOException {
+ if (zipFile == null) return null;
+ List paths = new ArrayList<>();
+ Enumeration> entries = new ZipFile(zipFile).entries();
+ while (entries.hasMoreElements()) {
+ paths.add(((ZipEntry) entries.nextElement()).getName());
+ }
+ return paths;
+ }
+
+ /**
+ * Return the files' comment in ZIP file.
+ *
+ * @param zipFilePath The path of ZIP file.
+ * @return the files' comment in ZIP file
+ * @throws IOException if an I/O error has occurred
+ */
+ public static List getComments(final String zipFilePath)
+ throws IOException {
+ return getComments(getFileByPath(zipFilePath));
+ }
+
+ /**
+ * Return the files' comment in ZIP file.
+ *
+ * @param zipFile The ZIP file.
+ * @return the files' comment in ZIP file
+ * @throws IOException if an I/O error has occurred
+ */
+ public static List getComments(final File zipFile)
+ throws IOException {
+ if (zipFile == null) return null;
+ List comments = new ArrayList<>();
+ Enumeration> entries = new ZipFile(zipFile).entries();
+ while (entries.hasMoreElements()) {
+ ZipEntry entry = ((ZipEntry) entries.nextElement());
+ comments.add(entry.getComment());
+ }
+ return comments;
+ }
+
+ private static boolean createOrExistsDir(final File file) {
+ return file != null && (file.exists() ? file.isDirectory() : file.mkdirs());
+ }
+
+ private static boolean createOrExistsFile(final File file) {
+ if (file == null) return false;
+ if (file.exists()) return file.isFile();
+ if (!createOrExistsDir(file.getParentFile())) return false;
+ try {
+ return file.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ private static File getFileByPath(final String filePath) {
+ return isSpace(filePath) ? null : new File(filePath);
+ }
+
+ private static boolean isSpace(final String s) {
+ if (s == null) return true;
+ for (int i = 0, len = s.length(); i < len; ++i) {
+ if (!Character.isWhitespace(s.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/library/src/test/java/org/davy/commons/ExampleUnitTest.java b/library/src/test/java/org/davy/commons/ExampleUnitTest.java
deleted file mode 100644
index 89a0b08..0000000
--- a/library/src/test/java/org/davy/commons/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.davy.commons;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/samples/build.gradle b/samples/build.gradle
index 9799e35..f81717a 100644
--- a/samples/build.gradle
+++ b/samples/build.gradle
@@ -1,11 +1,16 @@
apply plugin: 'com.android.application'
+//apply plugin: 'org.greenleaf.utils.injectplugin'
+
+//injectplugin {
+// message = "this is test Message."
+// injectPackages = ["org.greenleaf.utils.samples", "com.google.utils"]
+//}
android {
compileSdkVersion 25
- buildToolsVersion "25.0.3"
defaultConfig {
applicationId "org.davy.commons.samples"
- minSdkVersion 19
+ minSdkVersion 17
targetSdkVersion 25
versionCode 1
versionName "1.0"
@@ -17,15 +22,35 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
+ buildToolsVersion '25.0.3'
+
+ lintOptions {
+ checkReleaseBuilds false
+ // Or, if you prefer, you can continue to check for errors in release builds,
+ // but continue the build even when errors are found:
+ abortOnError false
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
}
dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
- exclude group: 'com.android.support', module: 'support-annotations'
- })
- compile project(':library')
- compile 'com.android.support:appcompat-v7:25.3.1'
- compile 'com.android.support.constraint:constraint-layout:1.0.2'
- testCompile 'junit:junit:4.12'
+ implementation fileTree(include: ['*.jar'], dir: 'libs')
+ implementation 'com.android.support:appcompat-v7:25.4.0'
+ implementation project(path: ':library')
}
+//
+//buildscript {
+// repositories {
+// mavenCentral()
+// google()
+// maven{
+// url uri('../repo')
+// }
+// }
+// dependencies {
+// classpath 'org.greenleaf.utils:injectplugin:1.0.0'
+// }
+//}
\ No newline at end of file
diff --git a/samples/src/androidTest/java/org/davy/commons/samples/ExampleInstrumentedTest.java b/samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java
similarity index 95%
rename from samples/src/androidTest/java/org/davy/commons/samples/ExampleInstrumentedTest.java
rename to samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java
index 1449e7b..0fa6420 100644
--- a/samples/src/androidTest/java/org/davy/commons/samples/ExampleInstrumentedTest.java
+++ b/samples/src/androidTest/java/org/greenleaf/utils/samples/ExampleInstrumentedTest.java
@@ -1,4 +1,4 @@
-package org.davy.commons.samples;
+package org.greenleaf.utils.samples;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
diff --git a/samples/src/main/AndroidManifest.xml b/samples/src/main/AndroidManifest.xml
index 0d9ec8a..edfdd9e 100644
--- a/samples/src/main/AndroidManifest.xml
+++ b/samples/src/main/AndroidManifest.xml
@@ -1,6 +1,10 @@
+
+ package="org.greenleaf.utils.samples">
+
+
+
+&'""""'&&&&]]>Sanguinaria canadensis4Mostly Shady$2.44031599
+
+
+ Columbine
+ Aquilegia canadensis
+ 3
+ Mostly Shady
+ $9.37
+ 030699
+
+
+ Marsh Marigold
+ Caltha palustris
+ 4
+ Mostly Sunny
+ $6.81
+ 051799
+
+
+ Cowslip
+ Caltha palustris
+ 4
+ Mostly Shady
+ $9.90
+ 030699
+
+
+ Dutchman's-Breeches
+ Dicentra cucullaria
+ 3
+ Mostly Shady
+ $6.44
+ 012099
+
+
+ Ginger, Wild
+ Asarum canadense
+ 3
+ Mostly Shady
+ $9.03
+ 041899
+
+
+ Hepatica
+ Hepatica americana
+ 4
+ Mostly Shady
+ $4.45
+ 012699
+
+
+ Liverleaf
+ Hepatica americana
+ 4
+ Mostly Shady
+ $3.99
+ 010299
+
+
+ Jack-In-The-Pulpit
+ Arisaema triphyllum
+ 4
+ Mostly Shady
+ $3.23
+ 020199
+
+
+ Mayapple
+ Podophyllum peltatum
+ 3
+ Mostly Shady
+ $2.98
+ 060599
+
+
+ Phlox, Woodland
+ Phlox divaricata
+ 3
+ Sun or Shade
+ $2.80
+ 012299
+
+
+ Phlox, Blue
+ Phlox divaricata
+ 3
+ Sun or Shade
+ $5.59
+ 021699
+
+
+ Spring-Beauty
+ Claytonia Virginica
+ 7
+ Mostly Shady
+ $6.59
+ 020199
+
+
+ Trillium
+ Trillium grandiflorum
+ 5
+ Sun or Shade
+ $3.90
+ 042999
+
+
+ Wake Robin
+ Trillium grandiflorum
+ 5
+ Sun or Shade
+ $3.20
+ 022199
+
+
+ Violet, Dog-Tooth
+ Erythronium americanum
+ 4
+ Shade
+ $9.04
+ 020199
+
+
+ Trout Lily
+ Erythronium americanum
+ 4
+ Shade
+ $6.94
+ 032499
+
+
+ Adder's-Tongue
+ Erythronium americanum
+ 4
+ Shade
+ $9.58
+ 041399
+
+
+ Anemone
+ Anemone blanda
+ 6
+ Mostly Shady
+ $8.86
+ 122698
+
+
+ Grecian Windflower
+ Anemone blanda
+ 6
+ Mostly Shady
+ $9.16
+ 071099
+
+
+ Bee Balm
+ Monarda didyma
+ 4
+ Shade
+ $4.59
+ 050399
+
+
+ Bergamot
+ Monarda didyma
+ 4
+ Shade
+ $7.16
+ 042799
+
+
+ Black-Eyed Susan
+ Rudbeckia hirta
+ Annual
+ Sunny
+ $9.80
+ 061899
+
+
+ Buttercup
+ Ranunculus
+ 4
+ Shade
+ $2.57
+ 061099
+
+
+ Crowfoot
+ Ranunculus
+ 4
+ Shade
+ $9.34
+ 040399
+
+
+ Butterfly Weed
+ Asclepias tuberosa
+ Annual
+ Sunny
+ $2.78
+ 063099
+
+
+ Cinquefoil
+ Potentilla
+ Annual
+ Shade
+ $7.06
+ 052599
+
+
+ Primrose
+ Oenothera
+ 3 - 5
+ Sunny
+ $6.56
+ 013099
+
+
+ Gentian
+ Gentiana
+ 4
+ Sun or Shade
+ $7.81
+ 051899
+
+
+ Blue Gentian
+ Gentiana
+ 4
+ Sun or Shade
+ $8.56
+ 050299
+
+
+ Jacob's Ladder
+ Polemonium caeruleum
+ Annual
+ Shade
+ $9.26
+ 022199
+
+
+ Greek Valerian
+ Polemonium caeruleum
+ Annual
+ Shade
+ $4.36
+ 071499
+
+
+ California Poppy
+ Eschscholzia californica
+ Annual
+ Sun
+ $7.89
+ 032799
+
+
+ Shooting Star
+ Dodecatheon
+ Annual
+ Mostly Shady
+ $8.60
+ 051399
+
+
+ Snakeroot
+ Cimicifuga
+ Annual
+ Shade
+ $5.63
+ 071199
+
+
+ Cardinal Flower
+ Lobelia cardinalis
+ 2
+ Shade
+ $3.02
+ 022299
+
+
\ No newline at end of file
diff --git a/samples/src/main/java/com/google/utils/Utils.java b/samples/src/main/java/com/google/utils/Utils.java
new file mode 100644
index 0000000..e7655f3
--- /dev/null
+++ b/samples/src/main/java/com/google/utils/Utils.java
@@ -0,0 +1,4 @@
+package com.google.utils;
+
+public class Utils {
+}
diff --git a/samples/src/main/java/org/davy/commons/samples/MainActivity.java b/samples/src/main/java/org/davy/commons/samples/MainActivity.java
deleted file mode 100644
index 7c0f6f5..0000000
--- a/samples/src/main/java/org/davy/commons/samples/MainActivity.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.davy.commons.samples;
-
-import android.os.Build;
-import android.support.v7.app.AppCompatActivity;
-import android.os.Bundle;
-import android.widget.Toast;
-
-import org.davy.commons.NetworkUtil;
-
-public class MainActivity extends AppCompatActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- Toast.makeText(this, NetworkUtil.getCurrentIp(this), Toast.LENGTH_LONG).show();
- }
-}
diff --git a/samples/src/main/java/org/greenleaf/utils/samples/InjectedClsss.java b/samples/src/main/java/org/greenleaf/utils/samples/InjectedClsss.java
new file mode 100644
index 0000000..04a9100
--- /dev/null
+++ b/samples/src/main/java/org/greenleaf/utils/samples/InjectedClsss.java
@@ -0,0 +1,7 @@
+package org.greenleaf.utils.samples;
+
+public class InjectedClsss {
+ public InjectedClsss() {
+
+ }
+}
diff --git a/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java b/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java
new file mode 100644
index 0000000..6d24c2d
--- /dev/null
+++ b/samples/src/main/java/org/greenleaf/utils/samples/MainActivity.java
@@ -0,0 +1,22 @@
+package org.greenleaf.utils.samples;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+import org.greenleaf.utils.AssetsUtils;
+
+public class MainActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ AssetsUtils.asset2String(getApplicationContext(), "data.xml");
+ }
+ }).start();
+ new InjectedClsss();
+ }
+}
diff --git a/samples/src/main/res/layout/activity_main.xml b/samples/src/main/res/layout/activity_main.xml
index d28508d..9daf193 100644
--- a/samples/src/main/res/layout/activity_main.xml
+++ b/samples/src/main/res/layout/activity_main.xml
@@ -1,9 +1,8 @@
-
+ tools:context="org.greenleaf.utils.samples.MainActivity">
-
+
diff --git a/samples/src/test/java/org/davy/commons/samples/ExampleUnitTest.java b/samples/src/test/java/org/davy/commons/samples/ExampleUnitTest.java
deleted file mode 100644
index c530269..0000000
--- a/samples/src/test/java/org/davy/commons/samples/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.davy.commons.samples;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 2129435..1c651fc 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1,2 @@
include ':samples', ':library'
+//, ':injectplugin'