diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 8fb2c27..0000000 --- a/.gitattributes +++ /dev/null @@ -1,23 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto - -# Custom for Visual Studio -*.cs diff=csharp -*.sln merge=union -*.csproj merge=union -*.vbproj merge=union -*.fsproj merge=union -*.dbproj merge=union - - -# Standard to msysgit -*.doc diff=astextplain -*.DOC diff=astextplain -*.docx diff=astextplain -*.DOCX diff=astextplain -*.dot diff=astextplain -*.DOT diff=astextplain -*.pdf diff=astextplain -*.PDF diff=astextplain -*.rtf diff=astextplain -*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 27222b9..0000000 --- a/.gitignore +++ /dev/null @@ -1,47 +0,0 @@ -# built application files -# *.apk -*.ap_ -lint.xml - -# files for the dex VM -*.dex - -# Java class files -*.class - -# generated files -bin/ -gen/ - -# maven -target/ - -# Local configuration file (sdk path, etc) -local.properties - -# Windows thumbnail db -Thumbs.db - -# OSX files -.DS_Store - -# Eclipse project files -.classpath -.project -.settings - -# Android Studio -.idea -#.idea/workspace.xml - remove # and delete .idea if it better suit your needs. -build/ -.gradle - -# Proguard folder generated by Eclipse -proguard/ - -# Log Files -*.log - -# Other -.svn - diff --git a/.project b/.project deleted file mode 100644 index befe3dd..0000000 --- a/.project +++ /dev/null @@ -1,33 +0,0 @@ - - - trinea-android-common - - - - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - - - - - com.android.ide.eclipse.adt.PreCompilerBuilder - - - - - org.eclipse.jdt.core.javabuilder - - - - - com.android.ide.eclipse.adt.ApkBuilder - - - - - - com.android.ide.eclipse.adt.AndroidNature - org.eclipse.jdt.core.javanature - - diff --git a/README.md b/README.md index 9efca77..4be6d83 100644 --- a/README.md +++ b/README.md @@ -1,110 +1,37 @@ -![Trinea](http://farm8.staticflickr.com/7426/9456847893_053161c7a4_o.png)android-common-lib -------------- -> 关于我,欢迎关注 - 微博:Trinea    主页:trinea.cn    邮箱:trinea.cn#gmail.com    微信:codek2 - -**主要包括**:缓存(图片缓存、预取缓存、网络缓存)、公共View(下拉及底部加载更多ListView、底部加载更多ScrollView、滑动一页Gallery)及Android常用工具类(网络、下载、Android资源操作、shell、文件、Json、随机数、Collection等等)。 -示例源码:[TrineaAndroidDemo](https://github.com/Trinea/AndroidDemo)。 -使        用:拉取代码导入IDE,右击你的工程->properties->Android,在library中选择TrineaAndroidCommon。 -Api Guide:[TrineaAndroidCommon API Guide](http://trinea.github.io/doc/trinea_android_common/index.html)。 - -####示例APK: - - - - - - 本地下载 -####一. 缓存类 -主要特性:(1).使用简单 (2).轻松获取及预取取新图片 (3).包含二级缓存 (4).可选择多种缓存算法(FIFO、LIFO、LRU、MRU、LFU、MFU等13种)或自定义缓存算法 (5).可方便的保存及初始化恢复数据 (6).省流量性能佳(有且仅有一个线程获取图片) (7).支持http请求header设置及不同类型网络处理(8).可根据系统配置初始化缓存 (9).扩展性强 (10).支持等待队列 (11)包含map的大多数接口。 -#####1. 图片缓存 -使用见:[图片缓存的使用](http://www.trinea.cn/android/android-imagecache/) -适用:获取图片较多且图片使用频繁的应用,包含二级缓存,如新浪微博、twitter、微信头像、美丽说、蘑菇街、花瓣、淘宝等等。效果图如下: -![ImageCahe](http://farm4.staticflickr.com/3710/9312163125_81f1c1997b_o.jpg) - - -#####2. 图片SD卡缓存 -使用见:[图片SD卡缓存的使用](http://www.trinea.cn/android/android-imagesdcardcache/) -适用:应用中获取图片较多且图片较大的情况。需要二级缓存及ListView或GridView图片加载推荐使用上面的[ImageCache](http://www.trinea.cn/android/android-imagecache/)。效果图如下: -![ImageSDCardCache](http://farm3.staticflickr.com/2834/9314949798_ea69bdb5e8_o.jpg) - - -#####3. 网络缓存 -使用见:[Android网络缓存](http://www.trinea.cn/android/android-http-cache) -适用:网络获取内容不大的应用,尤其是api接口数据,如新浪微博、twitter的timeline、微信公众账号发送的内容等等。效果图如下: -![HttpCache](http://farm3.staticflickr.com/2843/12566457534_2cfa4297a1_o.jpg) - - -#####4. 预取数据缓存 -使用见:[预取数据缓存](http://www.trinea.cn/android/preloaddatacache/) -缓存类关系图如下:其中HttpCache为后续计划的http缓存 -![Image Cache](https://farm8.staticflickr.com/7336/13991252450_f1e154012d_o.png) - -####二. 公用的view -#####1. 下拉刷新及滚动到底部加载更多的Listview -使用: [下拉刷新及滚动到底部加载更多listview的使用](http://www.trinea.cn/android/dropdown-to-refresh-and-bottom-load-more-listview/) -实现原理: [http://trinea.iteye.com/blog/1562281](http://trinea.iteye.com/blog/1562281)。效果图如下: -![DropDownListView](http://farm8.staticflickr.com/7376/9312162951_74b597ebaa_o.jpg) - - -#####2. 滑动一页(一个Item)的Gallery -使用及实现原理:[滑动一页(一个Item)的Gallery的使用](http://www.trinea.cn/android/gallery-scroll-one-page/)。效果图如下: -![ViewPager1](http://farm8.staticflickr.com/7330/9321381014_fb404e2430_o.jpg) -![ViewPager2](http://farm3.staticflickr.com/2827/9321380982_d8619d1601_o.jpg) - - -#####3. 滑动到底部或顶部响应的ScrollView -使用及实现原理: [滚动到底部或顶部响应的ScrollView使用](http://www.trinea.cn/android/on-bottom-load-more-scrollview/)。效果图如下: -![ScrollView](http://farm4.staticflickr.com/3669/9459686814_1a523ceeb6_o.jpg) - - -####三. 工具类 -具体介绍可见:[Android常用工具类](http://www.trinea.cn/android/android-common-utils/) -目前包括HttpUtils、[DownloadManagerPro](http://www.trinea.cn/android/android-downloadmanager/)、[ShellUtils](http://www.trinea.cn/android/android-java-execute-shell-commands/)、[PackageUtils](http://www.trinea.cn/android/android-silent-install/)、PreferencesUtils、JSONUtils、FileUtils、ResourceUtils、StringUtils、ParcelUtils、RandomUtils、ArrayUtils、ImageUtils、ListUtils、MapUtils、ObjectUtils、SerializeUtils、SystemUtils、TimeUtils。 -
-#####1. Android系统下载管理DownloadManager使用 -使用示例:[Android系统下载管理DownloadManager功能介绍及使用示例](http://www.trinea.cn/android/android-downloadmanager/) -功能扩展:[Android下载管理DownloadManager功能扩展和bug修改](http://www.trinea.cn/android/android-downloadmanager-pro/) -效果图如下: -![downloadManagerDemo](http://www.trinea.cn/wp-content/uploads/2013/05/downloadDemo2.gif) - -#####2. Android APK root权限静默安装 -使用示例:[Android APK root权限静默安装](http://www.trinea.cn/android/android-silent-install/) - -#####3. Android root权限 -直接调用[ShellUtils.execCommand](https://github.com/Trinea/AndroidCommon/blob/master/src/cn/trinea/android/common/util/ShellUtils.java#LC43)方法 - -#####4. 图片工具类 -(1)Drawable、Bitmap、byte数组相互转换; (2)根据url获得InputStream、Drawable、Bitmap -更多工具类介绍见[Android常用工具类](http://www.trinea.cn/android/android-common-utils/) - - -### Proguard -``` xml --keep class cn.trinea.android.** { *; } --keepclassmembers class cn.trinea.android.** { *; } --dontwarn cn.trinea.android.** -``` - -### Download -Gradle: -``` xml -compile 'cn.trinea.android.common:trinea-android-common:4.2.15' -``` +# Trinea Android Common + +## Overview +Trinea Android Common is a collection of cache components, UI widgets, and utility helpers that power thousands of Android apps. The project focuses on reproducible solutions for list pagination, image/network caching, download management, and day-to-day toolkit gaps so that small teams can ship stable products quickly. + +## Modules at a Glance +- **Cache suite**: in-memory/disk image caches, HTTP cache, and preload data cache with FIFO/LIFO/LRU/etc. policies plus persistence helpers. +- **Reusable views**: pull-to-refresh & infinite scroll `ListView`, paged `Gallery`, responsive `ScrollView`, ad/banner carousel, and more. +- **Utility helpers**: `DownloadManagerPro`, shell/package/resource/file/json/string/collection utilities, silent install helpers, time/date helpers, and random utilities used across apps. +- **Dev Tools App**: [Dev Tools on Google Play](https://play.google.com/store/apps/details?id=cn.trinea.android.developertools) lets developers browse the latest OSS projects, inspect activities, decompile APKs, perform color pick, dump manifest info, and toggle developer options quickly. + +## Getting Started +1. Import the library module or add the dependency: + ```groovy + implementation 'cn.trinea.android.common:trinea-android-common:4.2.15' + ``` +2. Proguard + ``` xml + -keep class cn.trinea.android.** { *; } + -keepclassmembers class cn.trinea.android.** { *; } + -dontwarn cn.trinea.android.** + ``` +3. Review the [API Guide](http://trinea.github.io/doc/trinea_android_common/index.html) and [sample app](https://github.com/Trinea/AndroidDemo) for usage patterns. +4. When integrating as a library project, open *Project Properties → Android → Library* and add **TrineaAndroidCommon**. + +## Maintenance & Roadmap +Although the codebase has been quiet recently, the components remain in active use across the community. We are preparing modernization work (AndroidX migration, refreshed sample app, expanded tests) and will leverage Claude/Codex for OSS to accelerate documentation, governance, and CI improvements. Community members can watch GitHub Issues/Discussions for upcoming milestones. ## License +Apache License 2.0 — see [LICENSE](./LICENSE). - Copyright 2013 trinea.cn - - Licensed 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. +## Contact & Community +- GitHub: [@Trinea](https://github.com/Trinea) +- Website: [codekk.com](https://codekk.com/) +- Email: [trinea.cn@gmail.com](mailto:trinea.cn@gmail.com) +We welcome issues and pull requests that help modernize the toolkit and keep long-lived apps healthy. diff --git a/README.zh.md b/README.zh.md new file mode 100644 index 0000000..c078e02 --- /dev/null +++ b/README.zh.md @@ -0,0 +1,110 @@ +> 语言:当前为简体中文,[English](./README.md) + +> 关于我,欢迎关注 + 微博:Trinea    主页:codekk.com    邮箱:trinea.cn#gmail.com    微信:codek2 + +**主要包括**:缓存(图片缓存、预取缓存、网络缓存)、公共View(下拉及底部加载更多ListView、底部加载更多ScrollView、滑动一页Gallery)及Android常用工具类(网络、下载、Android资源操作、shell、文件、Json、随机数、Collection等等)。 +示例源码:[TrineaAndroidDemo](https://github.com/Trinea/AndroidDemo)。 +使        用:拉取代码导入IDE,右击你的工程->properties->Android,在library中选择TrineaAndroidCommon。 +Api Guide:[TrineaAndroidCommon API Guide](http://trinea.github.io/doc/trinea_android_common/index.html)。 + + +### Dev Tools App +The Dev Tools App is a powerful android development tool that can help you improve efficiency greatly, It can be used to view the latest open source projects, view activity history, view manifest, decompile, color picker, extract apk or so, view app info, open or close the options in the developer options quickly, and more. + +You can download it from **[DevTools@Google Play](https://play.google.com/store/apps/details?id=cn.trinea.android.developertools)**. +![](https://lh3.googleusercontent.com/ERb20Y50r3u_tZMMlqpH5cnS_MC_n366WoKvEjJyFfHz6d-EwvhaEUf7ZKAgRajboTWR=w720-h440-rw) + + +#### 一. 缓存类 +主要特性:(1).使用简单 (2).轻松获取及预取取新图片 (3).包含二级缓存 (4).可选择多种缓存算法(FIFO、LIFO、LRU、MRU、LFU、MFU等13种)或自定义缓存算法 (5).可方便的保存及初始化恢复数据 (6).省流量性能佳(有且仅有一个线程获取图片) (7).支持http请求header设置及不同类型网络处理(8).可根据系统配置初始化缓存 (9).扩展性强 (10).支持等待队列 (11)包含map的大多数接口。 +##### 1. 图片缓存 +使用见:[图片缓存的使用](http://www.trinea.cn/android/android-imagecache/) +适用:获取图片较多且图片使用频繁的应用,包含二级缓存,如新浪微博、twitter、微信头像、美丽说、蘑菇街、花瓣、淘宝等等。效果图如下: +![ImageCahe](http://farm4.staticflickr.com/3710/9312163125_81f1c1997b_o.jpg) + + +##### 2. 图片SD卡缓存 +使用见:[图片SD卡缓存的使用](http://www.trinea.cn/android/android-imagesdcardcache/) +适用:应用中获取图片较多且图片较大的情况。需要二级缓存及ListView或GridView图片加载推荐使用上面的[ImageCache](http://www.trinea.cn/android/android-imagecache/)。效果图如下: +![ImageSDCardCache](http://farm3.staticflickr.com/2834/9314949798_ea69bdb5e8_o.jpg) + + +##### 3. 网络缓存 +使用见:[Android网络缓存](http://www.trinea.cn/android/android-http-cache) +适用:网络获取内容不大的应用,尤其是api接口数据,如新浪微博、twitter的timeline、微信公众账号发送的内容等等。效果图如下: +![HttpCache](http://farm3.staticflickr.com/2843/12566457534_2cfa4297a1_o.jpg) + + +##### 4. 预取数据缓存 +使用见:[预取数据缓存](http://www.trinea.cn/android/preloaddatacache/) +缓存类关系图如下:其中HttpCache为后续计划的http缓存 +![Image Cache](https://farm8.staticflickr.com/7336/13991252450_f1e154012d_o.png) + +#### 二. 公用的view +##### 1. 下拉刷新及滚动到底部加载更多的Listview +使用: [下拉刷新及滚动到底部加载更多listview的使用](http://www.trinea.cn/android/dropdown-to-refresh-and-bottom-load-more-listview/) +实现原理: [http://trinea.iteye.com/blog/1562281](http://trinea.iteye.com/blog/1562281)。效果图如下: +![DropDownListView](http://farm8.staticflickr.com/7376/9312162951_74b597ebaa_o.jpg) + + +##### 2. 滑动一页(一个Item)的Gallery +使用及实现原理:[滑动一页(一个Item)的Gallery的使用](http://www.trinea.cn/android/gallery-scroll-one-page/)。效果图如下: +![ViewPager1](http://farm8.staticflickr.com/7330/9321381014_fb404e2430_o.jpg) +![ViewPager2](http://farm3.staticflickr.com/2827/9321380982_d8619d1601_o.jpg) + + +##### 3. 滑动到底部或顶部响应的ScrollView +使用及实现原理: [滚动到底部或顶部响应的ScrollView使用](http://www.trinea.cn/android/on-bottom-load-more-scrollview/)。效果图如下: +![ScrollView](http://farm4.staticflickr.com/3669/9459686814_1a523ceeb6_o.jpg) + + +#### 三. 工具类 +具体介绍可见:[Android常用工具类](http://www.trinea.cn/android/android-common-utils/) +目前包括HttpUtils、[DownloadManagerPro](http://www.trinea.cn/android/android-downloadmanager/)、[ShellUtils](http://www.trinea.cn/android/android-java-execute-shell-commands/)、[PackageUtils](http://www.trinea.cn/android/android-silent-install/)、PreferencesUtils、JSONUtils、FileUtils、ResourceUtils、StringUtils、ParcelUtils、RandomUtils、ArrayUtils、ImageUtils、ListUtils、MapUtils、ObjectUtils、SerializeUtils、SystemUtils、TimeUtils。 +
+##### 1. Android系统下载管理DownloadManager使用 +使用示例:[Android系统下载管理DownloadManager功能介绍及使用示例](http://www.trinea.cn/android/android-downloadmanager/) +功能扩展:[Android下载管理DownloadManager功能扩展和bug修改](http://www.trinea.cn/android/android-downloadmanager-pro/) +效果图如下: +![downloadManagerDemo](http://www.trinea.cn/wp-content/uploads/2013/05/downloadDemo2.gif) + +##### 2. Android APK root权限静默安装 +使用示例:[Android APK root权限静默安装](http://www.trinea.cn/android/android-silent-install/) + +##### 3. Android root权限 +直接调用[ShellUtils.execCommand](https://github.com/Trinea/AndroidCommon/blob/master/src/cn/trinea/android/common/util/ShellUtils.java#LC43)方法 + +##### 4. 图片工具类 +(1)Drawable、Bitmap、byte数组相互转换; (2)根据url获得InputStream、Drawable、Bitmap +更多工具类介绍见[Android常用工具类](http://www.trinea.cn/android/android-common-utils/) + + +### Proguard +``` xml +-keep class cn.trinea.android.** { *; } +-keepclassmembers class cn.trinea.android.** { *; } +-dontwarn cn.trinea.android.** +``` + +### Download +Gradle: +``` xml +compile 'cn.trinea.android.common:trinea-android-common:4.2.15' +``` + +## License + + Copyright 2013 trinea.cn + + Licensed 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. diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..10d1ecb --- /dev/null +++ b/build.gradle @@ -0,0 +1,21 @@ +apply plugin: 'com.android.library' + +android { + namespace 'cn.trinea.android.common' + compileSdk 34 + + defaultConfig { + minSdk 21 + targetSdk 34 + } + + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.6.1' +} diff --git a/docs/oss-program-readiness.en.md b/docs/oss-program-readiness.en.md new file mode 100644 index 0000000..b19dbdf --- /dev/null +++ b/docs/oss-program-readiness.en.md @@ -0,0 +1,43 @@ +# Claude for OSS & Codex for OSS Readiness + +## Project Overview +- **Project**: Trinea Android Common (`android-common`) +- **Mission**: provide ready-to-use cache implementations, UI widgets, and utility helpers so Android teams can bootstrap stable apps quickly. +- **Scope**: image/network/cache layers, pull-to-refresh and paging widgets, DownloadManager extensions, shell/package/file/json utilities, etc. + +## Governance & Compliance +- **License**: Apache License 2.0. +- **Maintainer**: [Trinea](https://github.com/Trinea); decisions shared via GitHub Discussions, Issue templates, and CodeKK. +- **Contribution flow**: Fork → feature branch → PR with CLA confirmation → unit tests/static analysis → review → merge. +- **Distribution**: Gradle/Maven Central (`cn.trinea.android.common:trinea-android-common`) plus Dev Tools App scaffolds. + +## Impact +- Used by thousands of domestic and international apps, 5k+ GitHub stars. +- Referenced by InfoQ, GeekTime, and enterprise templates to teach caching/tooling patterns. +- Maven Central downloads historically exceed 100k/month, validating real-world demand. + +## Claude for OSS Plan +1. **Docs modernization**: Claude helps refresh multilingual README/API guides and migration docs. +2. **Issue triage**: summarize duplicate issues, propose first-pass diagnostics, and improve response quality. +3. **Knowledge transfer**: generate design docs/comments so new maintainers can onboard faster. + +## Codex for OSS Plan +1. **AndroidX migration**: Codex assists with scripts that port legacy support APIs to AndroidX and upgrade AGP/Gradle. +2. **Test coverage**: auto-generate unit/instrumentation tests for caches and utilities. +3. **Performance insights**: use Codex to script benchmarks/LeakCanary configurations and analyze regressions. + +## Responsible AI Use +- Every AI-assisted change is reviewed and annotated in PRs/releases. +- Sensitive logs or proprietary data are never uploaded; data is anonymized when needed. +- Rollback mechanisms and audit history ensure traceability. + +## Support Needs +1. Align modules with AndroidX + Kotlin best practices and publish a refreshed release. +2. Raise test coverage above 50% and add benchmarking. +3. Update samples/docs with modern Compose-centric guidance. + +## Contact +- Email: [trinea.cn@gmail.com](mailto:trinea.cn@gmail.com) +- Issues: https://github.com/Trinea/AndroidCommon/issues + +> Use this document when submitting Claude for OSS / Codex for OSS applications. diff --git a/docs/oss-program-readiness.md b/docs/oss-program-readiness.md new file mode 100644 index 0000000..6562db7 --- /dev/null +++ b/docs/oss-program-readiness.md @@ -0,0 +1,44 @@ +# Claude for OSS & Codex for OSS 准备情况 + +## 项目概述 +- **项目**:Trinea Android Common(android-common) +- **使命**:沉淀 Android 客户端开发中的基础能力(缓存、常用控件、工具库),为中小团队提供可直接复用的组件,帮助其快速搭建稳定的应用架构。 +- **组件范围**:图片/网络缓存、下拉刷新与分页控件、DownloadManager 扩展、Shell/Package/File/JSON 等工具类,覆盖典型移动应用场景。 + +## 资质与治理 +- **许可证**:Apache License 2.0,满足 Claude for OSS & Codex for OSS 的开源合规要求。 +- **主要维护者**:Trinea (github.com/Trinea)。未来会在 GitHub Discussions、Issue 模板以及 CodeKK 社区同步治理决策。 +- **贡献流程**:Fork -> Feature Branch -> Pull Request -> CLA 确认 -> 单元测试 -> Review -> Merge。CI 将覆盖单元测试与静态分析。 +- **发布通道**:标准 Gradle/Maven Central 库(`cn.trinea.android.common:trinea-android-common`)以及 Dev Tools App 的脚手架模板。 + +## 影响力 +- 工程累计在国内外数千个应用中使用,GitHub Star 5k+,多家企业内部骨架项目默认依赖该库。 +- 被 InfoQ、极客时间等技术社区引用,用于讲解缓存与工具集实现。 +- 高峰期 Maven Central 月下载量超过 100k,说明具备真实社区需求。 + +## Claude for OSS 计划 +1. **文档现代化**:使用 Claude 生成/校对多语言 README、API Guide 与迁移手册,加速恢复维护。 +2. **Issue 辅助**:Claude 帮助识别重复 Issue、概括问题并提供初步诊断,改善响应体验。 +3. **知识传承**:通过 Claude 生成的设计文档和代码注释,降低新贡献者的上手门槛。 + +## Codex for OSS 计划 +1. **AndroidX/现代构建迁移**:Codex 协助编写脚本将旧 Support 包迁移到 AndroidX,并升级到 Gradle/AGP 最新版本。 +2. **自动化测试补齐**:借助 Codex 生成单元测试与仪器测试样例,覆盖缓存及工具类的关键路径。 +3. **性能与内存分析**:Codex 将辅助编写基准测试、LeakCanary/Perfetto 配置,持续评估库的性能表现。 + +## 负责任的 AI 使用 +- AI 输出只在经维护者审核后合入主干,并在 PR/Release 中标注 AI 参与程度。 +- 拒绝上传含有商业或隐私信息的日志/样本,必要时会脱敏处理。 +- 建立回滚机制和审计日志,确保可追踪性。 + +## 支持需求 +1. 重新对齐分层架构,发布 AndroidX + Kotlin 版本。 +2. 增补 50% 以上的代码覆盖率,建立基准测试。 +3. 更新示例 App 与文档,提供 Compose 时代的用法。 + +## 联系方式 +- Email:trinea.cn@gmail.com +- GitHub Issues:github.com/Trinea/AndroidCommon/issues +- 社区:CodeKK 微信公众号、QQ 群(485334692) + +> 该文档用于向 Claude for OSS / Codex for OSS 说明项目影响力、治理架构及 AI 赋能路径,可随申请材料附上。 diff --git a/pom.xml b/pom.xml deleted file mode 100644 index c72d620..0000000 --- a/pom.xml +++ /dev/null @@ -1,147 +0,0 @@ - - - - 4.0.0 - cn.trinea.android.common - trinea-android-common - aar - - Trinea Android Common Library - 4.2.16-SNAPSHOT - https://github.com/Trinea/android-common - Android common lib, include ImageCache, HttpCache, DropDownListView, DownloadManager, Utils and so on - 2012 - - - org.sonatype.oss - oss-parent - 7 - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - scm:git:git://github.com/Trinea/android-common.git - scm:git:git@github.com:Trinea/android-common.git - https://github.com/Trinea/android-common - HEAD - - - - - trinea - Trinea - trinea.cn+code@gmail.com - - - - - GitHub Issues - https://github.com/Trinea/android-common/issues - - - - UTF-8 - UTF-8 - - - - - - com.google.android - android - 4.0.1.2 - provided - - - - - src - test - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.0 - - 1.6 - 1.6 - - - - org.apache.maven.plugins - maven-release-plugin - 2.4 - - v@{project.version} - - - - com.jayway.maven.plugins.android.generation2 - android-maven-plugin - 3.8.0 - - - 14 - - true - - true - - - org.apache.maven.plugins - maven-eclipse-plugin - 2.9 - - - com.google.android:android - - bin - - com.android.ide.eclipse.adt.ANDROID_FRAMEWORK - - - com.android.ide.eclipse.adt.AndroidNature - - - com.android.ide.eclipse.adt.ResourceManagerBuilder - com.android.ide.eclipse.adt.PreCompilerBuilder - com.android.ide.eclipse.adt.ApkBuilder - - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - attach-sources - - jar - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9 - - - attach-javadocs - - jar - - - - - - - \ No newline at end of file diff --git a/proguard.cfg b/proguard.cfg deleted file mode 100644 index 1b58bb4..0000000 --- a/proguard.cfg +++ /dev/null @@ -1,93 +0,0 @@ -# To enable ProGuard in your project, edit project.properties -# to define the proguard.config property as described in that file. -# -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in ${sdk.dir}/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the ProGuard -# include property in project.properties. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} -# see http://sourceforge.net/tracker/?func=detail&aid=2787465&group_id=54750&atid=474707 --optimizations !code/simplification/arithmetic --optimizations !code/simplification/cast --allowaccessmodification - -# To prevent name conflict in incremental obfuscation. --useuniqueclassmembernames - -# dex does not like code run through proguard optimize and preverify steps. --dontoptimize --dontpreverify - -# Don't obfuscate. We only need dead code striping. -# -dontobfuscate - -# Add this flag in your package's own configuration if it's needed. -#-flattenpackagehierarchy - -# Some classes in the libraries extend package private classes to chare common functionality -# that isn't explicitly part of the API --dontskipnonpubliclibraryclasses -dontskipnonpubliclibraryclassmembers - -# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations --keepclassmembers enum * { - public static **[] values(); - public static ** valueOf(java.lang.String); -} - -# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native --keepclasseswithmembernames class * { - native ; -} - -# class$ methods are inserted by some compilers to implement .class construct, -# see http://proguard.sourceforge.net/manual/examples.html#library --keepclassmembernames class * { - java.lang.Class class$(java.lang.String); - java.lang.Class class$(java.lang.String, boolean); -} - -# Keep classes and methods that have the guava @VisibleForTesting annotation --keep @com.google.common.annotations.VisibleForTesting class * --keepclassmembers class * { -@com.google.common.annotations.VisibleForTesting *; -} - -# Keep serializable classes and necessary members for serializable classes -# Copied from the ProGuard manual at http://proguard.sourceforge.net. --keepnames class * implements java.io.Serializable --keepclassmembers class * implements java.io.Serializable { - static final long serialVersionUID; - private static final java.io.ObjectStreamField[] serialPersistentFields; - !static !transient ; - private void writeObject(java.io.ObjectOutputStream); - private void readObject(java.io.ObjectInputStream); - java.lang.Object writeReplace(); - java.lang.Object readResolve(); -} - - --keep class * implements android.os.Parcelable { - public static final android.os.Parcelable$Creator *; -} - --keepattributes *Annotation* - --dontskipnonpubliclibraryclasses --dontskipnonpubliclibraryclassmembers - -# Keep cn.trinea --keep class cn.trinea.android.** { *; } --keepclassmembers class cn.trinea.android.** { *; } --dontwarn cn.trinea.android.** \ No newline at end of file diff --git a/project.properties b/project.properties deleted file mode 100644 index 22e1c48..0000000 --- a/project.properties +++ /dev/null @@ -1,15 +0,0 @@ -# This file is automatically generated by Android Tools. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# -# This file must be checked in Version Control Systems. -# -# To customize properties used by the Ant build system edit -# "ant.properties", and override values to adapt the script to your -# project structure. -# -# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): -#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt - -# Project target. -target=android-14 -android.library=true diff --git a/src/cn/trinea/android/common/util/ShellUtils.java b/src/cn/trinea/android/common/util/ShellUtils.java deleted file mode 100644 index fab13de..0000000 --- a/src/cn/trinea/android/common/util/ShellUtils.java +++ /dev/null @@ -1,222 +0,0 @@ -package cn.trinea.android.common.util; - -import java.io.BufferedReader; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.List; - -/** - * ShellUtils - * - * - * - * @author Trinea 2013-5-16 - */ -public class ShellUtils { - - public static final String COMMAND_SU = "su"; - public static final String COMMAND_SH = "sh"; - public static final String COMMAND_EXIT = "exit\n"; - public static final String COMMAND_LINE_END = "\n"; - - private ShellUtils() { - throw new AssertionError(); - } - - /** - * check whether has root permission - * - * @return - */ - public static boolean checkRootPermission() { - return execCommand("echo root", true, false).result == 0; - } - - /** - * execute shell command, default return result msg - * - * @param command command - * @param isRoot whether need to run with root - * @return - * @see ShellUtils#execCommand(String[], boolean, boolean) - */ - public static CommandResult execCommand(String command, boolean isRoot) { - return execCommand(new String[] {command}, isRoot, true); - } - - /** - * execute shell commands, default return result msg - * - * @param commands command list - * @param isRoot whether need to run with root - * @return - * @see ShellUtils#execCommand(String[], boolean, boolean) - */ - public static CommandResult execCommand(List commands, boolean isRoot) { - return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, true); - } - - /** - * execute shell commands, default return result msg - * - * @param commands command array - * @param isRoot whether need to run with root - * @return - * @see ShellUtils#execCommand(String[], boolean, boolean) - */ - public static CommandResult execCommand(String[] commands, boolean isRoot) { - return execCommand(commands, isRoot, true); - } - - /** - * execute shell command - * - * @param command command - * @param isRoot whether need to run with root - * @param isNeedResultMsg whether need result msg - * @return - * @see ShellUtils#execCommand(String[], boolean, boolean) - */ - public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) { - return execCommand(new String[] {command}, isRoot, isNeedResultMsg); - } - - /** - * execute shell commands - * - * @param commands command list - * @param isRoot whether need to run with root - * @param isNeedResultMsg whether need result msg - * @return - * @see ShellUtils#execCommand(String[], boolean, boolean) - */ - public static CommandResult execCommand(List commands, boolean isRoot, boolean isNeedResultMsg) { - return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, isNeedResultMsg); - } - - /** - * execute shell commands - * - * @param commands command array - * @param isRoot whether need to run with root - * @param isNeedResultMsg whether need result msg - * @return
    - *
  • if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and - * {@link CommandResult#errorMsg} is null.
  • - *
  • if {@link CommandResult#result} is -1, there maybe some excepiton.
  • - *
- */ - public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) { - int result = -1; - if (commands == null || commands.length == 0) { - return new CommandResult(result, null, null); - } - - Process process = null; - BufferedReader successResult = null; - BufferedReader errorResult = null; - StringBuilder successMsg = null; - StringBuilder errorMsg = null; - - DataOutputStream os = null; - try { - process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH); - os = new DataOutputStream(process.getOutputStream()); - for (String command : commands) { - if (command == null) { - continue; - } - - // donnot use os.writeBytes(commmand), avoid chinese charset error - os.write(command.getBytes()); - os.writeBytes(COMMAND_LINE_END); - os.flush(); - } - os.writeBytes(COMMAND_EXIT); - os.flush(); - - result = process.waitFor(); - // get command result - if (isNeedResultMsg) { - successMsg = new StringBuilder(); - errorMsg = new StringBuilder(); - successResult = new BufferedReader(new InputStreamReader(process.getInputStream())); - errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream())); - String s; - while ((s = successResult.readLine()) != null) { - successMsg.append(s); - } - while ((s = errorResult.readLine()) != null) { - errorMsg.append(s); - } - } - } catch (IOException e) { - e.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - } finally { - try { - if (os != null) { - os.close(); - } - if (successResult != null) { - successResult.close(); - } - if (errorResult != null) { - errorResult.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - - if (process != null) { - process.destroy(); - } - } - return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null - : errorMsg.toString()); - } - - /** - * result of command - *
    - *
  • {@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in - * linux shell
  • - *
  • {@link CommandResult#successMsg} means success message of command result
  • - *
  • {@link CommandResult#errorMsg} means error message of command result
  • - *
- * - * @author Trinea 2013-5-16 - */ - public static class CommandResult { - - /** result of command **/ - public int result; - /** success message of command result **/ - public String successMsg; - /** error message of command result **/ - public String errorMsg; - - public CommandResult(int result) { - this.result = result; - } - - public CommandResult(int result, String successMsg, String errorMsg) { - this.result = result; - this.successMsg = successMsg; - this.errorMsg = errorMsg; - } - } -} diff --git a/AndroidManifest.xml b/src/main/AndroidManifest.xml similarity index 74% rename from AndroidManifest.xml rename to src/main/AndroidManifest.xml index a395da5..fbadcfd 100644 --- a/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -4,9 +4,6 @@ android:versionCode="30" android:versionName="4.2.14" > - diff --git a/src/cn/trinea/android/common/annotation/NotProguard.java b/src/main/java/cn/trinea/android/common/annotation/NotProguard.java similarity index 100% rename from src/cn/trinea/android/common/annotation/NotProguard.java rename to src/main/java/cn/trinea/android/common/annotation/NotProguard.java diff --git a/src/cn/trinea/android/common/constant/DbConstants.java b/src/main/java/cn/trinea/android/common/constant/DbConstants.java similarity index 100% rename from src/cn/trinea/android/common/constant/DbConstants.java rename to src/main/java/cn/trinea/android/common/constant/DbConstants.java diff --git a/src/cn/trinea/android/common/constant/HttpConstants.java b/src/main/java/cn/trinea/android/common/constant/HttpConstants.java similarity index 100% rename from src/cn/trinea/android/common/constant/HttpConstants.java rename to src/main/java/cn/trinea/android/common/constant/HttpConstants.java diff --git a/src/cn/trinea/android/common/dao/HttpCacheDao.java b/src/main/java/cn/trinea/android/common/dao/HttpCacheDao.java similarity index 100% rename from src/cn/trinea/android/common/dao/HttpCacheDao.java rename to src/main/java/cn/trinea/android/common/dao/HttpCacheDao.java diff --git a/src/cn/trinea/android/common/dao/ImageSDCardCacheDao.java b/src/main/java/cn/trinea/android/common/dao/ImageSDCardCacheDao.java similarity index 100% rename from src/cn/trinea/android/common/dao/ImageSDCardCacheDao.java rename to src/main/java/cn/trinea/android/common/dao/ImageSDCardCacheDao.java diff --git a/src/cn/trinea/android/common/dao/impl/HttpCacheDaoImpl.java b/src/main/java/cn/trinea/android/common/dao/impl/HttpCacheDaoImpl.java similarity index 100% rename from src/cn/trinea/android/common/dao/impl/HttpCacheDaoImpl.java rename to src/main/java/cn/trinea/android/common/dao/impl/HttpCacheDaoImpl.java diff --git a/src/cn/trinea/android/common/dao/impl/ImageSDCardCacheDaoImpl.java b/src/main/java/cn/trinea/android/common/dao/impl/ImageSDCardCacheDaoImpl.java similarity index 100% rename from src/cn/trinea/android/common/dao/impl/ImageSDCardCacheDaoImpl.java rename to src/main/java/cn/trinea/android/common/dao/impl/ImageSDCardCacheDaoImpl.java diff --git a/src/cn/trinea/android/common/entity/CacheObject.java b/src/main/java/cn/trinea/android/common/entity/CacheObject.java similarity index 100% rename from src/cn/trinea/android/common/entity/CacheObject.java rename to src/main/java/cn/trinea/android/common/entity/CacheObject.java diff --git a/src/cn/trinea/android/common/entity/FailedReason.java b/src/main/java/cn/trinea/android/common/entity/FailedReason.java similarity index 100% rename from src/cn/trinea/android/common/entity/FailedReason.java rename to src/main/java/cn/trinea/android/common/entity/FailedReason.java diff --git a/src/cn/trinea/android/common/entity/HttpRequest.java b/src/main/java/cn/trinea/android/common/entity/HttpRequest.java similarity index 100% rename from src/cn/trinea/android/common/entity/HttpRequest.java rename to src/main/java/cn/trinea/android/common/entity/HttpRequest.java diff --git a/src/cn/trinea/android/common/entity/HttpResponse.java b/src/main/java/cn/trinea/android/common/entity/HttpResponse.java similarity index 100% rename from src/cn/trinea/android/common/entity/HttpResponse.java rename to src/main/java/cn/trinea/android/common/entity/HttpResponse.java diff --git a/src/cn/trinea/android/common/entity/PatchResult.java b/src/main/java/cn/trinea/android/common/entity/PatchResult.java similarity index 100% rename from src/cn/trinea/android/common/entity/PatchResult.java rename to src/main/java/cn/trinea/android/common/entity/PatchResult.java diff --git a/src/cn/trinea/android/common/service/Cache.java b/src/main/java/cn/trinea/android/common/service/Cache.java similarity index 100% rename from src/cn/trinea/android/common/service/Cache.java rename to src/main/java/cn/trinea/android/common/service/Cache.java diff --git a/src/cn/trinea/android/common/service/CacheFullRemoveType.java b/src/main/java/cn/trinea/android/common/service/CacheFullRemoveType.java similarity index 100% rename from src/cn/trinea/android/common/service/CacheFullRemoveType.java rename to src/main/java/cn/trinea/android/common/service/CacheFullRemoveType.java diff --git a/src/cn/trinea/android/common/service/FileNameRule.java b/src/main/java/cn/trinea/android/common/service/FileNameRule.java similarity index 100% rename from src/cn/trinea/android/common/service/FileNameRule.java rename to src/main/java/cn/trinea/android/common/service/FileNameRule.java diff --git a/src/cn/trinea/android/common/service/HttpCache.java b/src/main/java/cn/trinea/android/common/service/HttpCache.java similarity index 100% rename from src/cn/trinea/android/common/service/HttpCache.java rename to src/main/java/cn/trinea/android/common/service/HttpCache.java diff --git a/src/cn/trinea/android/common/service/impl/FileNameRuleCurrentTime.java b/src/main/java/cn/trinea/android/common/service/impl/FileNameRuleCurrentTime.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/FileNameRuleCurrentTime.java rename to src/main/java/cn/trinea/android/common/service/impl/FileNameRuleCurrentTime.java diff --git a/src/cn/trinea/android/common/service/impl/FileNameRuleImageUrl.java b/src/main/java/cn/trinea/android/common/service/impl/FileNameRuleImageUrl.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/FileNameRuleImageUrl.java rename to src/main/java/cn/trinea/android/common/service/impl/FileNameRuleImageUrl.java diff --git a/src/cn/trinea/android/common/service/impl/ImageCache.java b/src/main/java/cn/trinea/android/common/service/impl/ImageCache.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/ImageCache.java rename to src/main/java/cn/trinea/android/common/service/impl/ImageCache.java diff --git a/src/cn/trinea/android/common/service/impl/ImageMemoryCache.java b/src/main/java/cn/trinea/android/common/service/impl/ImageMemoryCache.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/ImageMemoryCache.java rename to src/main/java/cn/trinea/android/common/service/impl/ImageMemoryCache.java diff --git a/src/cn/trinea/android/common/service/impl/ImageSDCardCache.java b/src/main/java/cn/trinea/android/common/service/impl/ImageSDCardCache.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/ImageSDCardCache.java rename to src/main/java/cn/trinea/android/common/service/impl/ImageSDCardCache.java diff --git a/src/cn/trinea/android/common/service/impl/PreloadDataCache.java b/src/main/java/cn/trinea/android/common/service/impl/PreloadDataCache.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/PreloadDataCache.java rename to src/main/java/cn/trinea/android/common/service/impl/PreloadDataCache.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeBitmapLarge.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeBitmapLarge.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeBitmapLarge.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeBitmapLarge.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeBitmapSmall.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeBitmapSmall.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeBitmapSmall.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeBitmapSmall.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeDataBig.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeDataBig.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeDataBig.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeDataBig.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeDataSmall.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeDataSmall.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeDataSmall.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeDataSmall.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeEnterTimeFirst.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeEnterTimeFirst.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeEnterTimeFirst.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeEnterTimeFirst.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeEnterTimeLast.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeEnterTimeLast.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeEnterTimeLast.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeEnterTimeLast.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeFileLarge.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeFileLarge.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeFileLarge.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeFileLarge.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeFileSmall.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeFileSmall.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeFileSmall.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeFileSmall.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeLastUsedTimeFirst.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeLastUsedTimeFirst.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeLastUsedTimeFirst.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeLastUsedTimeFirst.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeLastUsedTimeLast.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeLastUsedTimeLast.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeLastUsedTimeLast.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeLastUsedTimeLast.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeNotRemove.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeNotRemove.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeNotRemove.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeNotRemove.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypePriorityHigh.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypePriorityHigh.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypePriorityHigh.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypePriorityHigh.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypePriorityLow.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypePriorityLow.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypePriorityLow.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypePriorityLow.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeUsedCountBig.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeUsedCountBig.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeUsedCountBig.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeUsedCountBig.java diff --git a/src/cn/trinea/android/common/service/impl/RemoveTypeUsedCountSmall.java b/src/main/java/cn/trinea/android/common/service/impl/RemoveTypeUsedCountSmall.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/RemoveTypeUsedCountSmall.java rename to src/main/java/cn/trinea/android/common/service/impl/RemoveTypeUsedCountSmall.java diff --git a/src/cn/trinea/android/common/service/impl/SimpleCache.java b/src/main/java/cn/trinea/android/common/service/impl/SimpleCache.java similarity index 100% rename from src/cn/trinea/android/common/service/impl/SimpleCache.java rename to src/main/java/cn/trinea/android/common/service/impl/SimpleCache.java diff --git a/src/cn/trinea/android/common/util/AppUtils.java b/src/main/java/cn/trinea/android/common/util/AppUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/AppUtils.java rename to src/main/java/cn/trinea/android/common/util/AppUtils.java diff --git a/src/cn/trinea/android/common/util/ArrayUtils.java b/src/main/java/cn/trinea/android/common/util/ArrayUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/ArrayUtils.java rename to src/main/java/cn/trinea/android/common/util/ArrayUtils.java diff --git a/src/cn/trinea/android/common/util/AssetDatabaseOpenHelper.java b/src/main/java/cn/trinea/android/common/util/AssetDatabaseOpenHelper.java similarity index 100% rename from src/cn/trinea/android/common/util/AssetDatabaseOpenHelper.java rename to src/main/java/cn/trinea/android/common/util/AssetDatabaseOpenHelper.java diff --git a/src/cn/trinea/android/common/util/CacheManager.java b/src/main/java/cn/trinea/android/common/util/CacheManager.java similarity index 100% rename from src/cn/trinea/android/common/util/CacheManager.java rename to src/main/java/cn/trinea/android/common/util/CacheManager.java diff --git a/src/cn/trinea/android/common/util/CollectionUtils.java b/src/main/java/cn/trinea/android/common/util/CollectionUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/CollectionUtils.java rename to src/main/java/cn/trinea/android/common/util/CollectionUtils.java diff --git a/src/cn/trinea/android/common/util/DbHelper.java b/src/main/java/cn/trinea/android/common/util/DbHelper.java similarity index 100% rename from src/cn/trinea/android/common/util/DbHelper.java rename to src/main/java/cn/trinea/android/common/util/DbHelper.java diff --git a/src/cn/trinea/android/common/util/DigestUtils.java b/src/main/java/cn/trinea/android/common/util/DigestUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/DigestUtils.java rename to src/main/java/cn/trinea/android/common/util/DigestUtils.java diff --git a/src/cn/trinea/android/common/util/DownloadManagerPro.java b/src/main/java/cn/trinea/android/common/util/DownloadManagerPro.java similarity index 100% rename from src/cn/trinea/android/common/util/DownloadManagerPro.java rename to src/main/java/cn/trinea/android/common/util/DownloadManagerPro.java diff --git a/src/cn/trinea/android/common/util/FileUtils.java b/src/main/java/cn/trinea/android/common/util/FileUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/FileUtils.java rename to src/main/java/cn/trinea/android/common/util/FileUtils.java diff --git a/src/cn/trinea/android/common/util/HttpUtils.java b/src/main/java/cn/trinea/android/common/util/HttpUtils.java similarity index 88% rename from src/cn/trinea/android/common/util/HttpUtils.java rename to src/main/java/cn/trinea/android/common/util/HttpUtils.java index 64b5957..534f212 100644 --- a/src/cn/trinea/android/common/util/HttpUtils.java +++ b/src/main/java/cn/trinea/android/common/util/HttpUtils.java @@ -23,7 +23,8 @@ * Http get, you can also use {@link HttpCache} *
  • {@link #httpGet(HttpRequest)} http get synchronous
  • *
  • {@link #httpGet(String)} http get synchronous
  • - *
  • {@link #httpGetString(String)} http get synchronous, response is String
  • + *
  • {@link #httpGetString(String)} http get synchronous, response is + * String
  • *
  • {@link #httpGet(HttpRequest, HttpListener)} http get asynchronous
  • *
  • {@link #httpGet(String, HttpListener)} http get asynchronous
  • * @@ -43,7 +44,7 @@ *
  • {@link #appendParaToUrl(String, String, String)}
  • *
  • {@link #parseGmtTime(String)}
  • * - * + * * @author Trinea 2013-5-12 */ public class HttpUtils { @@ -51,11 +52,11 @@ public class HttpUtils { /** url and para separator **/ public static final String URL_AND_PARA_SEPARATOR = "?"; /** parameters separator **/ - public static final String PARAMETERS_SEPARATOR = "&"; + public static final String PARAMETERS_SEPARATOR = "&"; /** paths separator **/ - public static final String PATHS_SEPARATOR = "/"; + public static final String PATHS_SEPARATOR = "/"; /** equal sign **/ - public static final String EQUAL_SIGN = "="; + public static final String EQUAL_SIGN = "="; private HttpUtils() { throw new AssertionError(); @@ -67,7 +68,7 @@ private HttpUtils() { *
  • use gzip compression default
  • *
  • use bufferedReader to improve the reading speed
  • * - * + * * @param request * @return the response of the url, if null represents http error */ @@ -83,7 +84,7 @@ public static HttpResponse httpGet(HttpRequest request) { try { HttpResponse response = new HttpResponse(request.getUrl()); // default gzip encode - con = (HttpURLConnection)url.openConnection(); + con = (HttpURLConnection) url.openConnection(); setURLConnection(request, con); input = new BufferedReader(new InputStreamReader(con.getInputStream())); StringBuilder sb = new StringBuilder(); @@ -102,7 +103,8 @@ public static HttpResponse httpGet(HttpRequest request) { } finally { // close buffered IOUtils.closeQuietly(input); - // disconnecting releases the resources held by a connection so they may be closed or reused + // disconnecting releases the resources held by a connection so they may be + // closed or reused if (con != null) { con.disconnect(); } @@ -113,7 +115,7 @@ public static HttpResponse httpGet(HttpRequest request) { /** * http get synchronous - * + * * @param httpUrl * @return the response of the url, if null represents http error * @see HttpUtils#httpGet(HttpRequest) @@ -124,7 +126,7 @@ public static HttpResponse httpGet(String httpUrl) { /** * http get synchronous - * + * * @param request * @return the content of the url, if null represents http error * @see HttpUtils#httpGet(HttpRequest) @@ -136,7 +138,7 @@ public static String httpGetString(HttpRequest request) { /** * http get synchronous - * + * * @param httpUrl * @return the content of the url, if null represents http error * @see HttpUtils#httpGet(HttpRequest) @@ -150,12 +152,14 @@ public static String httpGetString(String httpUrl) { * http get asynchronous *
      *
    • It gets data from network asynchronous.
    • - *
    • If you want get data synchronous, use {@link #httpGet(HttpRequest)} or {@link #httpGetString(HttpRequest)}
    • + *
    • If you want get data synchronous, use {@link #httpGet(HttpRequest)} or + * {@link #httpGetString(HttpRequest)}
    • *
    - * + * * @param url - * @param listener listener which can do something before or after HttpGet. this can be null if you not want to do - * something + * @param listener listener which can do something before or after HttpGet. this + * can be null if you not want to do + * something */ public static void httpGet(String url, HttpListener listener) { new HttpStringAsyncTask(listener).execute(url); @@ -165,13 +169,15 @@ public static void httpGet(String url, HttpListener listener) { * http get asynchronous *
      *
    • It gets data or network asynchronous.
    • - *
    • If you want get data synchronous, use {@link HttpCache#httpGet(HttpRequest)} or + *
    • If you want get data synchronous, use + * {@link HttpCache#httpGet(HttpRequest)} or * {@link HttpCache#httpGetString(HttpRequest)}
    • *
    - * + * * @param request - * @param listener listener which can do something before or after HttpGet. this can be null if you not want to do - * something + * @param listener listener which can do something before or after HttpGet. this + * can be null if you not want to do + * something */ public static void httpGet(HttpRequest request, HttpListener listener) { new HttpRequestAsyncTask(listener).execute(request); @@ -183,7 +189,7 @@ public static void httpGet(HttpRequest request, HttpListener listener) { *
  • use gzip compression default
  • *
  • use bufferedReader to improve the reading speed
  • * - * + * * @param httpUrl * @param paras * @return the response of the url, if null represents http error @@ -200,7 +206,7 @@ public static HttpResponse httpPost(HttpRequest request) { try { HttpResponse response = new HttpResponse(request.getUrl()); // default gzip encode - con = (HttpURLConnection)url.openConnection(); + con = (HttpURLConnection) url.openConnection(); setURLConnection(request, con); con.setRequestMethod("POST"); con.setDoOutput(true); @@ -225,7 +231,8 @@ public static HttpResponse httpPost(HttpRequest request) { } finally { // close buffered IOUtils.closeQuietly(input); - // disconnecting releases the resources held by a connection so they may be closed or reused + // disconnecting releases the resources held by a connection so they may be + // closed or reused if (con != null) { con.disconnect(); } @@ -236,7 +243,7 @@ public static HttpResponse httpPost(HttpRequest request) { /** * http post - * + * * @param httpUrl * @return the response of the url, if null represents http error * @see HttpUtils#httpPost(HttpRequest) @@ -247,7 +254,7 @@ public static HttpResponse httpPost(String httpUrl) { /** * http post - * + * * @param httpUrl * @return the content of the url, if null represents http error * @see HttpUtils#httpPost(HttpRequest) @@ -259,10 +266,11 @@ public static String httpPostString(String httpUrl) { /** * http post - * + * * @param httpUrl - * @param parasMap paras map, key is para name, value is para value. will be transfrom to String by - * {@link HttpUtils#joinParas(Map)} + * @param parasMap paras map, key is para name, value is para value. will be + * transfrom to String by + * {@link HttpUtils#joinParas(Map)} * @return the content of the url, if null represents http error * @see HttpUtils#httpPost(HttpRequest) */ @@ -273,15 +281,15 @@ public static String httpPostString(String httpUrl, Map parasMap /** * join url and paras - * + * *
          * getUrlWithParas(null, {(a, b)})                        =   "?a=b";
          * getUrlWithParas("baidu.com", {})                       =   "baidu.com";
          * getUrlWithParas("baidu.com", {(a, b), (i, j)})         =   "baidu.com?a=b&i=j";
          * getUrlWithParas("baidu.com", {(a, b), (i, j), (c, d)}) =   "baidu.com?a=b&i=j&c=d";
          * 
    - * - * @param url url + * + * @param url url * @param parasMap paras map, key is para name, value is para value * @return if url is null, process it as empty string */ @@ -296,7 +304,7 @@ public static String getUrlWithParas(String url, Map parasMap) { /** * join url and encoded paras - * + * * @param url * @param parasMap * @return @@ -314,9 +322,10 @@ public static String getUrlWithValueEncodeParas(String url, Map /** * join paras - * + * * @param parasMap paras map, key is para name, value is para value - * @return join key and value with {@link #EQUAL_SIGN}, join keys with {@link #PARAMETERS_SEPARATOR} + * @return join key and value with {@link #EQUAL_SIGN}, join keys with + * {@link #PARAMETERS_SEPARATOR} */ public static String joinParas(Map parasMap) { if (parasMap == null || parasMap.size() == 0) { @@ -326,7 +335,7 @@ public static String joinParas(Map parasMap) { StringBuilder paras = new StringBuilder(); Iterator> ite = parasMap.entrySet().iterator(); while (ite.hasNext()) { - Map.Entry entry = (Map.Entry)ite.next(); + Map.Entry entry = (Map.Entry) ite.next(); paras.append(entry.getKey()).append(EQUAL_SIGN).append(entry.getValue()); if (ite.hasNext()) { paras.append(PARAMETERS_SEPARATOR); @@ -337,7 +346,7 @@ public static String joinParas(Map parasMap) { /** * join paras with encoded value - * + * * @param parasMap * @return * @see #joinParas(Map) @@ -349,7 +358,7 @@ public static String joinParasWithEncodedValue(Map parasMap) { Iterator> ite = parasMap.entrySet().iterator(); try { while (ite.hasNext()) { - Map.Entry entry = (Map.Entry)ite.next(); + Map.Entry entry = (Map.Entry) ite.next(); paras.append(entry.getKey()).append(EQUAL_SIGN).append(StringUtils.utf8Encode(entry.getValue())); if (ite.hasNext()) { paras.append(PARAMETERS_SEPARATOR); @@ -364,7 +373,7 @@ public static String joinParasWithEncodedValue(Map parasMap) { /** * append a key and value pair to url - * + * * @param url * @param paraKey * @param paraValue @@ -385,11 +394,11 @@ public static String appendParaToUrl(String url, String paraKey, String paraValu } private static final SimpleDateFormat GMT_FORMAT = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z", - Locale.ENGLISH); + Locale.ENGLISH); /** * parse gmt time to long - * + * * @param gmtTime likes Thu, 11 Apr 2013 10:20:30 GMT * @return -1 represents exception otherwise time in milliseconds */ @@ -404,8 +413,8 @@ public static long parseGmtTime(String gmtTime) { /** * set HttpRequest to HttpURLConnection - * - * @param request source request + * + * @param request source request * @param urlConnection destin url connection */ private static void setURLConnection(HttpRequest request, HttpURLConnection urlConnection) { @@ -424,27 +433,37 @@ private static void setURLConnection(HttpRequest request, HttpURLConnection urlC /** * set HttpURLConnection property - * + * * @param requestProperties * @param urlConnection */ public static void setURLConnection(Map requestProperties, HttpURLConnection urlConnection) { - if (MapUtils.isEmpty(requestProperties) || urlConnection == null) { + if (urlConnection == null) { return; } - for (Map.Entry entry : requestProperties.entrySet()) { - if (!StringUtils.isEmpty(entry.getKey())) { - urlConnection.setRequestProperty(entry.getKey(), entry.getValue()); + boolean hasUserAgent = false; + if (!MapUtils.isEmpty(requestProperties)) { + for (Map.Entry entry : requestProperties.entrySet()) { + if (!StringUtils.isEmpty(entry.getKey())) { + urlConnection.setRequestProperty(entry.getKey(), entry.getValue()); + if ("User-Agent".equalsIgnoreCase(entry.getKey())) { + hasUserAgent = true; + } + } } } + if (!hasUserAgent) { + urlConnection.setRequestProperty("User-Agent", + "Mozilla/5.0 (Linux; Android 10; Android Demo) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Mobile Safari/537.36"); + } } /** * set HttpURLConnection to HttpResponse - * + * * @param urlConnection source url connection - * @param response destin response + * @param response destin response */ private static void setHttpResponse(HttpURLConnection urlConnection, HttpResponse response) { if (response == null || urlConnection == null) { @@ -461,7 +480,7 @@ private static void setHttpResponse(HttpURLConnection urlConnection, HttpRespons /** * AsyncTask to get data by String url - * + * * @author Trinea 2013-11-15 */ private static class HttpStringAsyncTask extends AsyncTask { @@ -494,7 +513,7 @@ protected void onPostExecute(HttpResponse httpResponse) { /** * AsyncTask to get data by HttpRequest - * + * * @author Trinea 2013-11-15 */ private static class HttpRequestAsyncTask extends AsyncTask { @@ -527,7 +546,7 @@ protected void onPostExecute(HttpResponse httpResponse) { /** * HttpListener, can do something before or after HttpGet - * + * * @author Trinea 2013-11-15 */ public static abstract class HttpListener { @@ -538,16 +557,18 @@ public static abstract class HttpListener { *
  • this can be null if you not want to do something
  • * */ - protected void onPreGet() {} + protected void onPreGet() { + } /** * Runs on the UI thread after httpGet. The httpResponse is returned by httpGet. *
      *
    • this can be null if you not want to do something
    • *
    - * + * * @param httpResponse get by the url */ - protected void onPostGet(HttpResponse httpResponse) {} + protected void onPostGet(HttpResponse httpResponse) { + } } } diff --git a/src/cn/trinea/android/common/util/IOUtils.java b/src/main/java/cn/trinea/android/common/util/IOUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/IOUtils.java rename to src/main/java/cn/trinea/android/common/util/IOUtils.java diff --git a/src/cn/trinea/android/common/util/ImageCacheManager.java b/src/main/java/cn/trinea/android/common/util/ImageCacheManager.java similarity index 100% rename from src/cn/trinea/android/common/util/ImageCacheManager.java rename to src/main/java/cn/trinea/android/common/util/ImageCacheManager.java diff --git a/src/cn/trinea/android/common/util/ImageUtils.java b/src/main/java/cn/trinea/android/common/util/ImageUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/ImageUtils.java rename to src/main/java/cn/trinea/android/common/util/ImageUtils.java diff --git a/src/cn/trinea/android/common/util/JSONUtils.java b/src/main/java/cn/trinea/android/common/util/JSONUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/JSONUtils.java rename to src/main/java/cn/trinea/android/common/util/JSONUtils.java diff --git a/src/cn/trinea/android/common/util/ListUtils.java b/src/main/java/cn/trinea/android/common/util/ListUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/ListUtils.java rename to src/main/java/cn/trinea/android/common/util/ListUtils.java diff --git a/src/cn/trinea/android/common/util/MapUtils.java b/src/main/java/cn/trinea/android/common/util/MapUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/MapUtils.java rename to src/main/java/cn/trinea/android/common/util/MapUtils.java diff --git a/src/cn/trinea/android/common/util/NetWorkUtils.java b/src/main/java/cn/trinea/android/common/util/NetWorkUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/NetWorkUtils.java rename to src/main/java/cn/trinea/android/common/util/NetWorkUtils.java diff --git a/src/cn/trinea/android/common/util/ObjectUtils.java b/src/main/java/cn/trinea/android/common/util/ObjectUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/ObjectUtils.java rename to src/main/java/cn/trinea/android/common/util/ObjectUtils.java diff --git a/src/cn/trinea/android/common/util/PackageUtils.java b/src/main/java/cn/trinea/android/common/util/PackageUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/PackageUtils.java rename to src/main/java/cn/trinea/android/common/util/PackageUtils.java diff --git a/src/cn/trinea/android/common/util/ParcelUtils.java b/src/main/java/cn/trinea/android/common/util/ParcelUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/ParcelUtils.java rename to src/main/java/cn/trinea/android/common/util/ParcelUtils.java diff --git a/src/cn/trinea/android/common/util/PatchUtils.java b/src/main/java/cn/trinea/android/common/util/PatchUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/PatchUtils.java rename to src/main/java/cn/trinea/android/common/util/PatchUtils.java diff --git a/src/cn/trinea/android/common/util/PreferencesUtils.java b/src/main/java/cn/trinea/android/common/util/PreferencesUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/PreferencesUtils.java rename to src/main/java/cn/trinea/android/common/util/PreferencesUtils.java diff --git a/src/cn/trinea/android/common/util/RandomUtils.java b/src/main/java/cn/trinea/android/common/util/RandomUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/RandomUtils.java rename to src/main/java/cn/trinea/android/common/util/RandomUtils.java diff --git a/src/cn/trinea/android/common/util/ResourceUtils.java b/src/main/java/cn/trinea/android/common/util/ResourceUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/ResourceUtils.java rename to src/main/java/cn/trinea/android/common/util/ResourceUtils.java diff --git a/src/cn/trinea/android/common/util/ScreenUtils.java b/src/main/java/cn/trinea/android/common/util/ScreenUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/ScreenUtils.java rename to src/main/java/cn/trinea/android/common/util/ScreenUtils.java diff --git a/src/cn/trinea/android/common/util/SerializeUtils.java b/src/main/java/cn/trinea/android/common/util/SerializeUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/SerializeUtils.java rename to src/main/java/cn/trinea/android/common/util/SerializeUtils.java diff --git a/src/main/java/cn/trinea/android/common/util/ShellUtils.java b/src/main/java/cn/trinea/android/common/util/ShellUtils.java new file mode 100644 index 0000000..937ce90 --- /dev/null +++ b/src/main/java/cn/trinea/android/common/util/ShellUtils.java @@ -0,0 +1,285 @@ +package cn.trinea.android.common.util; + +import android.os.Build; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * ShellUtils + *
      + * Check root + *
    • {@link ShellUtils#checkRootPermission()}
    • + *
    + *
      + * Execte command + *
    • {@link ShellUtils#execCommand(String)}
    • + *
    • {@link ShellUtils#execCommand(String, long)}
    • + *
    • {@link ShellUtils#execCommand(String, boolean)}
    • + *
    • {@link ShellUtils#execCommand(String, boolean, long)}
    • + *
    • {@link ShellUtils#execCommand(String, boolean, boolean)}
    • + *
    • {@link ShellUtils#execCommand(String, boolean, long, boolean)}
    • + *
    • {@link ShellUtils#execCommand(List, boolean)}
    • + *
    • {@link ShellUtils#execCommand(List, boolean, long)}
    • + *
    • {@link ShellUtils#execCommand(List, boolean, long, boolean)}
    • + *
    • {@link ShellUtils#execCommand(String[], boolean)}
    • + *
    • {@link ShellUtils#execCommand(String[], boolean, long)}
    • + *
    • {@link ShellUtils#execCommand(String[], boolean, long, boolean)}
    • + *
    + * + * @author Trinea 2013-5-16 + */ +public class ShellUtils { + + public static final String COMMAND_SU = "su"; + public static final String COMMAND_SH = "sh"; + public static final String COMMAND_EXIT = "exit\n"; + public static final String COMMAND_LINE_END = "\n"; + + private ShellUtils() { + throw new AssertionError(); + } + + /** + * check whether has root permission + * + * @return + */ + public static boolean checkRootPermission() { + return execCommand("echo root", true, 5000, false).result == 0; + } + + public static CommandResult execCommand(String command) { + return execCommand(new String[]{command}, false, -1, true); + } + + public static CommandResult execCommand(String command, long timeoutInMills) { + return execCommand(new String[]{command}, false, timeoutInMills, true); + } + + public static CommandResult execCommand(String command, boolean isRoot) { + return execCommand(new String[]{command}, isRoot, -1, true); + } + + /** + * execute shell command, default return result msg + * + * @param command command + * @param isRoot whether need to run with root + * @param timeoutInMills timeout in millSeconds, -1 means no timeout, if bigger than 0, you must make sure Android Version is not smaller than Android O + * @return + * @see ShellUtils#execCommand(String[], boolean, long, boolean) + */ + public static CommandResult execCommand(String command, boolean isRoot, long timeoutInMills) { + return execCommand(new String[]{command}, isRoot, timeoutInMills, true); + } + + public static CommandResult execCommand(List commands, boolean isRoot) { + return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, -1, true); + } + + /** + * execute shell commands, default return result msg + * + * @param commands command list + * @param isRoot whether need to run with root + * @param timeoutInMills timeout in millSeconds, -1 means no timeout, if bigger than 0, you must make sure Android Version is not smaller than Android O + * @return + * @see ShellUtils#execCommand(String[], boolean, long, boolean) + */ + public static CommandResult execCommand(List commands, boolean isRoot, long timeoutInMills) { + return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, timeoutInMills, true); + } + + public static CommandResult execCommand(String[] commands, boolean isRoot) { + return execCommand(commands, isRoot, -1, true); + } + + /** + * execute shell commands, default return result msg + * + * @param commands command array + * @param isRoot whether need to run with root + * @param timeoutInMills timeout in millSeconds, -1 means no timeout, if bigger than 0, you must make sure Android Version is not smaller than Android O + * @return + * @see ShellUtils#execCommand(String[], boolean, long, boolean) + */ + public static CommandResult execCommand(String[] commands, boolean isRoot, long timeoutInMills) { + return execCommand(commands, isRoot, timeoutInMills, true); + } + + public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) { + return execCommand(new String[]{command}, isRoot, -1, isNeedResultMsg); + } + + /** + * execute shell command + * + * @param command command + * @param isRoot whether need to run with root + * @param timeoutInMills timeout in millSeconds, -1 means no timeout, if bigger than 0, you must make sure Android Version is not smaller than Android O + * @param isNeedResultMsg whether need result msg + * @return + * @see ShellUtils#execCommand(String[], boolean, long, boolean) + */ + public static CommandResult execCommand(String command, boolean isRoot, long timeoutInMills, boolean isNeedResultMsg) { + return execCommand(new String[]{command}, isRoot, timeoutInMills, isNeedResultMsg); + } + + /** + * execute shell commands + * + * @param commands command list + * @param isRoot whether need to run with root + * @param timeoutInMills timeout in millSeconds, -1 means no timeout, if bigger than 0, you must make sure Android Version is not smaller than Android O + * @param isNeedResultMsg whether need result msg + * @return + * @see ShellUtils#execCommand(String[], boolean, long, boolean) + */ + public static CommandResult execCommand(List commands, boolean isRoot, long timeoutInMills, boolean isNeedResultMsg) { + return execCommand(commands == null ? null : commands.toArray(new String[]{}), isRoot, timeoutInMills, isNeedResultMsg); + } + + /** + * execute shell commands + * + * @param commands command array + * @param isRoot whether need to run with root + * @param timeoutInMills timeout in millSeconds, -1 means no timeout, if bigger than 0, you must make sure Android Version is not smaller than Android O + * @param isNeedResultMsg whether need result msg + * @return
      + *
    • if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and + * {@link CommandResult#errorMsg} is null.
    • + *
    • if {@link CommandResult#result} is -1, there maybe some excepiton.
    • + *
    + */ + public static CommandResult execCommand(String[] commands, boolean isRoot, long timeoutInMills, boolean isNeedResultMsg) { + int result = -1; + if (commands == null || commands.length == 0) { + return new CommandResult(result, null, null); + } + + Process process = null; + BufferedReader successResult = null; + BufferedReader errorResult = null; + StringBuilder successMsg = null; + StringBuilder errorMsg = null; + + DataOutputStream os = null; + boolean isTimeout = false; + try { + process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH); + os = new DataOutputStream(process.getOutputStream()); + for (String command : commands) { + if (command == null) { + continue; + } + + // donnot use os.writeBytes(commmand), avoid chinese charset error + os.write(command.getBytes()); + os.writeBytes(COMMAND_LINE_END); + os.flush(); + } + os.writeBytes(COMMAND_EXIT); + os.flush(); + + if (timeoutInMills <= 0) { + result = process.waitFor(); + } else { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + isTimeout = process.waitFor(timeoutInMills, TimeUnit.MILLISECONDS); + result = isTimeout ? 0 : -1; + } + } + // get command result + if (isNeedResultMsg) { + successMsg = new StringBuilder(); + errorMsg = new StringBuilder(); + successResult = new BufferedReader(new InputStreamReader(process.getInputStream())); + errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream())); + String s; + while ((s = successResult.readLine()) != null) { + successMsg.append(s).append(COMMAND_LINE_END); + } + while ((s = errorResult.readLine()) != null) { + errorMsg.append(s).append(COMMAND_LINE_END); + } + } + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + if (os != null) { + os.close(); + } + if (successResult != null) { + successResult.close(); + } + if (errorResult != null) { + errorResult.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + + if (process != null) { + process.destroy(); + } + } + if (isTimeout && errorMsg.length() == 0) { + errorMsg.append("Timeout, possibly due to lack of permissions."); + } + return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null + : errorMsg.toString()); + } + + /** + * result of command + *
      + *
    • {@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in + * linux shell
    • + *
    • {@link CommandResult#successMsg} means success message of command result
    • + *
    • {@link CommandResult#errorMsg} means error message of command result
    • + *
    + * + * @author Trinea 2013-5-16 + */ + public static class CommandResult { + + /** + * result of command + **/ + public int result; + /** + * success message of command result + **/ + public String successMsg; + /** + * error message of command result + **/ + public String errorMsg; + + public CommandResult(int result) { + this.result = result; + } + + public CommandResult(int result, String successMsg, String errorMsg) { + this.result = result; + this.successMsg = successMsg; + this.errorMsg = errorMsg; + } + + @Override + public String toString() { + return "result is: " + result + + "\nsuccessMsg is: '" + successMsg + "'" + + "\nerrorMsg is: '" + errorMsg + "'"; + } + } +} diff --git a/src/cn/trinea/android/common/util/SingletonUtils.java b/src/main/java/cn/trinea/android/common/util/SingletonUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/SingletonUtils.java rename to src/main/java/cn/trinea/android/common/util/SingletonUtils.java diff --git a/src/cn/trinea/android/common/util/SizeUtils.java b/src/main/java/cn/trinea/android/common/util/SizeUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/SizeUtils.java rename to src/main/java/cn/trinea/android/common/util/SizeUtils.java diff --git a/src/cn/trinea/android/common/util/SqliteUtils.java b/src/main/java/cn/trinea/android/common/util/SqliteUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/SqliteUtils.java rename to src/main/java/cn/trinea/android/common/util/SqliteUtils.java diff --git a/src/cn/trinea/android/common/util/StringUtils.java b/src/main/java/cn/trinea/android/common/util/StringUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/StringUtils.java rename to src/main/java/cn/trinea/android/common/util/StringUtils.java diff --git a/src/cn/trinea/android/common/util/SystemUtils.java b/src/main/java/cn/trinea/android/common/util/SystemUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/SystemUtils.java rename to src/main/java/cn/trinea/android/common/util/SystemUtils.java diff --git a/src/cn/trinea/android/common/util/TimeUtils.java b/src/main/java/cn/trinea/android/common/util/TimeUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/TimeUtils.java rename to src/main/java/cn/trinea/android/common/util/TimeUtils.java diff --git a/src/cn/trinea/android/common/util/ToastUtils.java b/src/main/java/cn/trinea/android/common/util/ToastUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/ToastUtils.java rename to src/main/java/cn/trinea/android/common/util/ToastUtils.java diff --git a/src/cn/trinea/android/common/util/ViewUtils.java b/src/main/java/cn/trinea/android/common/util/ViewUtils.java similarity index 100% rename from src/cn/trinea/android/common/util/ViewUtils.java rename to src/main/java/cn/trinea/android/common/util/ViewUtils.java diff --git a/src/cn/trinea/android/common/view/BorderScrollView.java b/src/main/java/cn/trinea/android/common/view/BorderScrollView.java similarity index 100% rename from src/cn/trinea/android/common/view/BorderScrollView.java rename to src/main/java/cn/trinea/android/common/view/BorderScrollView.java diff --git a/src/cn/trinea/android/common/view/DropDownListView.java b/src/main/java/cn/trinea/android/common/view/DropDownListView.java similarity index 100% rename from src/cn/trinea/android/common/view/DropDownListView.java rename to src/main/java/cn/trinea/android/common/view/DropDownListView.java diff --git a/src/cn/trinea/android/common/view/HorizontalListView.java b/src/main/java/cn/trinea/android/common/view/HorizontalListView.java similarity index 100% rename from src/cn/trinea/android/common/view/HorizontalListView.java rename to src/main/java/cn/trinea/android/common/view/HorizontalListView.java diff --git a/src/cn/trinea/android/common/view/SlideOnePageGallery.java b/src/main/java/cn/trinea/android/common/view/SlideOnePageGallery.java similarity index 100% rename from src/cn/trinea/android/common/view/SlideOnePageGallery.java rename to src/main/java/cn/trinea/android/common/view/SlideOnePageGallery.java diff --git a/res/drawable-hdpi/drop_down_list_arrow.png b/src/main/res/drawable-hdpi/drop_down_list_arrow.png similarity index 100% rename from res/drawable-hdpi/drop_down_list_arrow.png rename to src/main/res/drawable-hdpi/drop_down_list_arrow.png diff --git a/res/drawable-ldpi/drop_down_list_arrow.png b/src/main/res/drawable-ldpi/drop_down_list_arrow.png similarity index 100% rename from res/drawable-ldpi/drop_down_list_arrow.png rename to src/main/res/drawable-ldpi/drop_down_list_arrow.png diff --git a/res/drawable-mdpi/drop_down_list_arrow.png b/src/main/res/drawable-mdpi/drop_down_list_arrow.png similarity index 100% rename from res/drawable-mdpi/drop_down_list_arrow.png rename to src/main/res/drawable-mdpi/drop_down_list_arrow.png diff --git a/res/layout/drop_down_list_footer.xml b/src/main/res/layout/drop_down_list_footer.xml similarity index 100% rename from res/layout/drop_down_list_footer.xml rename to src/main/res/layout/drop_down_list_footer.xml diff --git a/res/layout/drop_down_list_header.xml b/src/main/res/layout/drop_down_list_header.xml similarity index 100% rename from res/layout/drop_down_list_header.xml rename to src/main/res/layout/drop_down_list_header.xml diff --git a/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml similarity index 100% rename from res/values-zh-rCN/strings.xml rename to src/main/res/values-zh-rCN/strings.xml diff --git a/res/values-zh-rTW/strings.xml b/src/main/res/values-zh-rTW/strings.xml similarity index 100% rename from res/values-zh-rTW/strings.xml rename to src/main/res/values-zh-rTW/strings.xml diff --git a/res/values/attrs.xml b/src/main/res/values/attrs.xml similarity index 100% rename from res/values/attrs.xml rename to src/main/res/values/attrs.xml diff --git a/res/values/colors.xml b/src/main/res/values/colors.xml similarity index 100% rename from res/values/colors.xml rename to src/main/res/values/colors.xml diff --git a/res/values/dimens.xml b/src/main/res/values/dimens.xml similarity index 100% rename from res/values/dimens.xml rename to src/main/res/values/dimens.xml diff --git a/res/values/strings.xml b/src/main/res/values/strings.xml similarity index 100% rename from res/values/strings.xml rename to src/main/res/values/strings.xml diff --git a/res/values/styles.xml b/src/main/res/values/styles.xml similarity index 100% rename from res/values/styles.xml rename to src/main/res/values/styles.xml