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 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 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'