├── .gitignore ├── LICENSE ├── android.keystore ├── app ├── .gitignore ├── build.gradle ├── libs │ ├── XposedBridgeApi-54.jar │ ├── umeng-analytics-7.4.0.jar │ └── umeng-common-1.4.0.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ ├── app.env.phone.json │ └── xposed_init │ ├── ic_launcher-web.png │ ├── java │ └── com │ │ └── sollyu │ │ └── android │ │ └── appenv │ │ ├── activitys │ │ ├── ActivityAbout.kt │ │ ├── ActivityBase.kt │ │ ├── ActivityDetail.kt │ │ ├── ActivityLog.kt │ │ ├── ActivityMain.kt │ │ ├── ActivityRegister.kt │ │ ├── ActivityScanQR.kt │ │ ├── ActivitySettings.kt │ │ ├── ActivitySplash.kt │ │ └── ActivityWeb.kt │ │ ├── bean │ │ ├── BeanHookInfo.kt │ │ └── PhoneModel.kt │ │ ├── commons │ │ ├── Application.kt │ │ ├── FloatingActionMenuBehavior.java │ │ ├── PhoneReport.kt │ │ ├── Phones.kt │ │ ├── Random.kt │ │ ├── Settings.kt │ │ ├── SettingsXposed.kt │ │ ├── Solution.kt │ │ ├── XposedEntry.kt │ │ ├── XposedEntryJava.java │ │ └── libs │ │ │ ├── IMEIGen.kt │ │ │ └── RandomMac.kt │ │ ├── define │ │ └── AppEnvConstants.java │ │ └── events │ │ └── EventSample.kt │ └── res │ ├── drawable-land │ └── splash_img.png │ ├── drawable-port │ └── splash_img.png │ ├── drawable-v21 │ ├── ic_menu_camera.xml │ ├── ic_menu_gallery.xml │ ├── ic_menu_manage.xml │ ├── ic_menu_send.xml │ ├── ic_menu_share.xml │ └── ic_menu_slideshow.xml │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ ├── ic_auto_fix.xml │ ├── ic_cancel_w.xml │ ├── ic_cloud_download.xml │ ├── ic_credit_card.xml │ ├── ic_crop_landscape.xml │ ├── ic_delete.xml │ ├── ic_domain.xml │ ├── ic_done_all.xml │ ├── ic_done_all_w.xml │ ├── ic_folder.xml │ ├── ic_folder_shared.xml │ ├── ic_folder_shared_w.xml │ ├── ic_info.xml │ ├── ic_info_outline.xml │ ├── ic_launch.xml │ ├── ic_launcher_background.xml │ ├── ic_menu.xml │ ├── ic_refresh.xml │ ├── ic_refresh_w.xml │ ├── ic_remove_circle.xml │ ├── ic_remove_circle_w.xml │ ├── ic_save.xml │ ├── ic_save_w.xml │ ├── ic_scan.xml │ ├── ic_search_w.xml │ ├── ic_settings.xml │ ├── ic_swap_horiz.xml │ ├── ic_system_update.xml │ ├── ic_thumb_up.xml │ ├── ic_unknown_6.xml │ ├── ic_video_youtube_w.xml │ ├── ic_wb_cloudy.xml │ ├── ios_back_drawable.xml │ └── splash_layer.xml │ ├── layout │ ├── activity_about.xml │ ├── activity_detail.xml │ ├── activity_log.xml │ ├── activity_main.xml │ ├── activity_register.xml │ ├── activity_scan_qr.xml │ ├── activity_settings.xml │ ├── activity_web.xml │ ├── app_bar_activity_main.xml │ ├── content_activity_about.xml │ ├── content_activity_detail.xml │ ├── content_activity_main.xml │ ├── include_toolbar.xml │ ├── item_listview.xml │ └── nav_header_activity_main.xml │ ├── menu │ ├── activity_detail.xml │ ├── activity_log.xml │ ├── activity_main.xml │ ├── activity_main_drawer.xml │ └── menu_activity_about.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-ldpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── values-en │ └── strings.xml │ ├── values-night │ └── styles.xml │ ├── values-notnight │ └── styles.xml │ ├── values-v21 │ └── styles.xml │ ├── values-zh-rCN │ └── strings.xml │ ├── values-zh-rTW │ └── strings.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── drawables.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── online ├── app.env.phone.json └── app.env.soft.json ├── readme.md └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /.idea/ 4 | /local.properties 5 | !/.idea/workspace.xml 6 | !/.idea/libraries 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | -------------------------------------------------------------------------------- /android.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-hacker/AppEnv-Kotlin/b11cddbed9427886cce8dd9d21da487a9aa68632/android.keystore -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | apply plugin: 'com.android.application' 10 | apply plugin: 'kotlin-android' 11 | apply plugin: 'kotlin-android-extensions' 12 | 13 | static def getGitVersion() { 14 | return 'git rev-parse --short HEAD'.execute().text.trim() 15 | } 16 | 17 | android { 18 | compileSdkVersion 27 19 | flavorDimensions "default" 20 | 21 | defaultConfig { 22 | applicationId "com.sollyu.xposed.hook.model" 23 | minSdkVersion 16 24 | targetSdkVersion 27 25 | versionCode 591 26 | versionName "3.2.10." + getGitVersion() 27 | } 28 | buildTypes { 29 | release { 30 | minifyEnabled false 31 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 32 | } 33 | } 34 | productFlavors { 35 | official { 36 | dimension "default" 37 | } 38 | github { 39 | dimension "default" 40 | } 41 | coolapk { 42 | dimension "default" 43 | } 44 | oschina { 45 | dimension "default" 46 | } 47 | ys168 { 48 | dimension "default" 49 | } 50 | play { 51 | dimension "default" 52 | } 53 | } 54 | android.applicationVariants.all { variant -> 55 | variant.outputs.each { output -> 56 | output.outputFileName = new File(applicationId + "-" + buildType.name + "-v" + defaultConfig.versionName + "-" + defaultConfig.versionCode + "-" + variant.productFlavors[0].name + "-" + new Date().format("yyyyMMdd", TimeZone.getTimeZone("UTC")) + ".apk"); 57 | } 58 | } 59 | } 60 | 61 | dependencies { 62 | compileOnly fileTree(include: ['*.jar'], dir: 'libs') 63 | implementation files('libs/umeng-analytics-7.4.0.jar') 64 | implementation files('libs/umeng-common-1.4.0.jar') 65 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 66 | implementation 'com.android.support:appcompat-v7:27.1.1' 67 | implementation 'com.android.support:design:27.1.1' 68 | implementation 'com.android.support.constraint:constraint-layout:1.1.1' 69 | implementation 'eu.chainfire:libsuperuser:1.0.0.201704021214' 70 | implementation 'org.apache.commons:commons-text:1.1' 71 | implementation 'commons-io:commons-io:2.6' 72 | implementation 'org.xutils:xutils:3.5.0' 73 | implementation 'com.elvishew:xlog:1.4.0' 74 | implementation 'com.alibaba:fastjson:1.1.56.android' 75 | implementation 'com.squareup.okhttp:okhttp:2.7.5' 76 | implementation 'com.github.kingsollyu:NotProguard:1.0.0' 77 | implementation 'com.github.kingsollyu:OptionItem:1.2.2' 78 | implementation 'com.github.clans:fab:1.6.4' 79 | implementation 'de.psdev.licensesdialog:licensesdialog:1.8.3' 80 | implementation 'org.greenrobot:eventbus:3.1.1' 81 | implementation 'com.afollestad.material-dialogs:core:0.9.5.0' 82 | implementation 'com.github.rubensousa:bottomsheetbuilder:1.6.0' 83 | implementation 'ru.alexbykov:nopermission:1.1.2' 84 | implementation 'com.just.agentweb:agentweb:3.0.0-rc' 85 | implementation 'com.dlazaro66.qrcodereaderview:qrcodereaderview:2.0.3' 86 | } 87 | 88 | repositories { 89 | maven { url 'https://jitpack.io' } 90 | } -------------------------------------------------------------------------------- /app/libs/XposedBridgeApi-54.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-hacker/AppEnv-Kotlin/b11cddbed9427886cce8dd9d21da487a9aa68632/app/libs/XposedBridgeApi-54.jar -------------------------------------------------------------------------------- /app/libs/umeng-analytics-7.4.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-hacker/AppEnv-Kotlin/b11cddbed9427886cce8dd9d21da487a9aa68632/app/libs/umeng-analytics-7.4.0.jar -------------------------------------------------------------------------------- /app/libs/umeng-common-1.4.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-hacker/AppEnv-Kotlin/b11cddbed9427886cce8dd9d21da487a9aa68632/app/libs/umeng-common-1.4.0.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 64 | 65 | 68 | 71 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /app/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | com.sollyu.android.appenv.commons.XposedEntryJava -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-hacker/AppEnv-Kotlin/b11cddbed9427886cce8dd9d21da487a9aa68632/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/activitys/ActivityAbout.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.activitys 10 | 11 | import android.app.Activity 12 | import android.content.Intent 13 | import android.net.Uri 14 | import android.text.Html 15 | import android.text.method.LinkMovementMethod 16 | import com.sollyu.android.appenv.BuildConfig 17 | import com.sollyu.android.appenv.R 18 | import com.sollyu.android.appenv.commons.Phones 19 | import com.sollyu.android.appenv.commons.Settings 20 | import com.sollyu.android.appenv.commons.SettingsXposed 21 | import kotlinx.android.synthetic.main.activity_about.* 22 | import kotlinx.android.synthetic.main.content_activity_about.* 23 | 24 | class ActivityAbout : ActivityBase() { 25 | 26 | companion object { 27 | fun launch(activity: Activity) { 28 | activity.startActivity(Intent(activity, ActivityAbout::class.java)) 29 | } 30 | } 31 | 32 | override fun onInitView() { 33 | super.onInitView() 34 | setContentView(R.layout.activity_about) 35 | setSupportActionBar(toolbar) 36 | 37 | supportActionBar?.setTitle(R.string.title_activity_about) 38 | supportActionBar?.setHomeButtonEnabled(true) 39 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 40 | 41 | } 42 | 43 | @Suppress("DEPRECATION") 44 | override fun onInitData() { 45 | super.onInitData() 46 | textView.movementMethod = LinkMovementMethod.getInstance() 47 | textView.isClickable = true 48 | textView.text = Html.fromHtml(getString(R.string.about_text, 49 | BuildConfig.VERSION_NAME, 50 | Settings.Instance.file.absolutePath, 51 | Phones.Instance.phoneFile.absolutePath, 52 | SettingsXposed.Instance.file.absolutePath)) 53 | } 54 | 55 | override fun onInitListener() { 56 | super.onInitListener() 57 | fab.setOnClickListener { startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/kingsollyu/AppEnv-Kotlin/issues"))) } 58 | } 59 | 60 | override fun getMobclickAgentTag(): String { 61 | return "About" 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/activitys/ActivityBase.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.activitys 10 | 11 | import android.annotation.SuppressLint 12 | import android.app.Activity 13 | import android.os.Bundle 14 | import android.os.Handler 15 | import android.support.v7.app.AppCompatActivity 16 | import android.view.MenuItem 17 | import com.sollyu.android.appenv.commons.Settings 18 | import com.sollyu.android.appenv.commons.SettingsXposed 19 | import com.umeng.analytics.MobclickAgent 20 | 21 | /** 22 | * 作者:sollyu 23 | * 时间:2017/11/20 24 | * 说明:基础的Activity类 25 | */ 26 | @SuppressLint("Registered") 27 | abstract class ActivityBase : AppCompatActivity() { 28 | 29 | override fun onCreate(savedInstanceState: Bundle?) { 30 | super.onCreate(savedInstanceState) 31 | 32 | onInitView() 33 | onInitData() 34 | onInitListener() 35 | activity.runOnUiThread { onInitDone() } 36 | } 37 | 38 | open fun onInitView() {} 39 | 40 | open fun onInitData() {} 41 | 42 | open fun onInitListener() {} 43 | 44 | open fun onInitDone() {} 45 | 46 | abstract fun getMobclickAgentTag():String 47 | 48 | val activity: Activity 49 | get() = this 50 | 51 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 52 | if (item.itemId == android.R.id.home) { 53 | onBackPressed() 54 | } 55 | return super.onOptionsItemSelected(item) 56 | } 57 | 58 | override fun onResume() { 59 | super.onResume() 60 | MobclickAgent.onPageStart(getMobclickAgentTag()) 61 | MobclickAgent.onResume(activity) 62 | } 63 | 64 | override fun onPause() { 65 | super.onPause() 66 | MobclickAgent.onPageEnd(getMobclickAgentTag()) 67 | MobclickAgent.onPause(activity) 68 | 69 | SettingsXposed.Instance.resetPermissions() 70 | } 71 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/activitys/ActivityLog.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.activitys 10 | 11 | import android.app.Activity 12 | import android.content.Intent 13 | import android.text.method.ScrollingMovementMethod 14 | import android.view.Menu 15 | import android.view.MenuItem 16 | import com.sollyu.android.appenv.R 17 | import com.sollyu.android.appenv.commons.Application 18 | import kotlinx.android.synthetic.main.activity_log.* 19 | import kotlinx.android.synthetic.main.include_toolbar.* 20 | import org.apache.commons.io.FileUtils 21 | import java.io.File 22 | 23 | class ActivityLog : ActivityBase() { 24 | companion object { 25 | fun launch(activity: Activity) { 26 | activity.startActivity(Intent(activity, ActivityLog::class.java)) 27 | } 28 | } 29 | 30 | override fun getMobclickAgentTag(): String { 31 | return "Log" 32 | } 33 | 34 | override fun onInitView() { 35 | super.onInitView() 36 | setContentView(R.layout.activity_log) 37 | setSupportActionBar(toolbar) 38 | supportActionBar?.setTitle(R.string.settings_log) 39 | supportActionBar?.setHomeButtonEnabled(true) 40 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 41 | 42 | textView.movementMethod = ScrollingMovementMethod.getInstance() 43 | textView.setHorizontallyScrolling(true) 44 | } 45 | 46 | override fun onInitData() { 47 | super.onInitData() 48 | onItemClickReloadLog() 49 | } 50 | 51 | override fun onCreateOptionsMenu(menu: Menu): Boolean { 52 | // Inflate the menu; this adds items to the action bar if it is present. 53 | menuInflater.inflate(R.menu.activity_log, menu) 54 | return true 55 | } 56 | 57 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 58 | when (item.itemId) { 59 | R.id.menuDeleteLog -> { 60 | this.onItemClickDeleteLog() 61 | } 62 | R.id.menuReloadLog -> { 63 | this.onItemClickReloadLog() 64 | } 65 | } 66 | return super.onOptionsItemSelected(item) 67 | } 68 | 69 | private fun onItemClickDeleteLog() { 70 | val logFile = File(Application.Instance.externalCacheDir.absolutePath, "log") 71 | if (logFile.exists()) { 72 | FileUtils.forceDelete(logFile) 73 | } 74 | onItemClickReloadLog() 75 | } 76 | 77 | private fun onItemClickReloadLog() { 78 | val logFile = File(Application.Instance.externalCacheDir.absolutePath, "log") 79 | if (logFile.exists() && logFile.canRead()) { 80 | textView.text = FileUtils.readFileToString(logFile, "UTF-8") 81 | } else { 82 | textView.text = "" 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/activitys/ActivityRegister.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | @file:Suppress("UNUSED_PARAMETER") 10 | 11 | package com.sollyu.android.appenv.activitys 12 | 13 | import android.app.Activity 14 | import android.content.Intent 15 | import android.view.View 16 | import com.afollestad.materialdialogs.MaterialDialog 17 | import com.alibaba.fastjson.JSON 18 | import com.sollyu.android.appenv.R 19 | import com.sollyu.android.appenv.define.AppEnvConstants 20 | import com.squareup.okhttp.* 21 | import kotlinx.android.synthetic.main.activity_register.* 22 | import kotlinx.android.synthetic.main.include_toolbar.* 23 | import org.xutils.view.annotation.Event 24 | import org.xutils.x 25 | import java.io.IOException 26 | 27 | class ActivityRegister : ActivityBase() { 28 | 29 | companion object { 30 | fun launch(activity: Activity) { 31 | activity.startActivity(Intent(activity, ActivityRegister::class.java)) 32 | } 33 | } 34 | 35 | override fun getMobclickAgentTag(): String { 36 | return "Register" 37 | } 38 | 39 | override fun onInitView() { 40 | super.onInitView() 41 | setContentView(R.layout.activity_register) 42 | x.view().inject(activity) 43 | 44 | setSupportActionBar(toolbar) 45 | supportActionBar?.setTitle(R.string.register_title) 46 | supportActionBar?.setHomeButtonEnabled(true) 47 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 48 | } 49 | 50 | @Suppress("unused") 51 | @Event(R.id.btnLogin) 52 | private fun onItemClickLogin(view: View) { 53 | 54 | val postBody = FormEncodingBuilder() 55 | .add("user_name" , etUserName.text.toString()) 56 | .add("user_password" , etPwd.text.toString()) 57 | .add("user_password_confirm", etPwdConfirm.text.toString()) 58 | .add("user_email" , etEMail.text.toString()) 59 | .build() 60 | 61 | val materialDialog = MaterialDialog.Builder(activity).title(R.string.tip).content(R.string.register_processing).progress(true, 0).cancelable(false).show() 62 | OkHttpClient().newCall(Request.Builder().url(AppEnvConstants.URL_APPENV_REGISTER).post(postBody).build()).enqueue(object : Callback{ 63 | override fun onFailure(request: Request, e: IOException) { 64 | materialDialog.dismiss() 65 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.error).content(e.message?:"null").show() } 66 | } 67 | 68 | override fun onResponse(response: Response) { 69 | materialDialog.dismiss() 70 | val serverResult = response.body().string() 71 | try { 72 | val resultJsonObject = JSON.parseObject(serverResult) 73 | if (resultJsonObject.getInteger("ret") == 200) { 74 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.tip).content("注册成功").canceledOnTouchOutside(false).positiveText(android.R.string.ok).onPositive { _, _ -> activity.finish() }.show() } 75 | } else { 76 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.tip).content("注册失败:\n" + resultJsonObject.getString("msg")).positiveText(android.R.string.ok).show() } 77 | } 78 | } catch (e: Exception) { 79 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.tip).content("注册失败,原因未知").positiveText(android.R.string.ok).show() } 80 | } 81 | } 82 | }) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/activitys/ActivityScanQR.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.activitys 10 | 11 | import android.Manifest 12 | import android.app.Activity 13 | import android.content.Intent 14 | import android.util.Log 15 | import android.widget.Toast 16 | import com.afollestad.materialdialogs.MaterialDialog 17 | import com.alibaba.fastjson.JSON 18 | import com.elvishew.xlog.XLog 19 | import com.sollyu.android.appenv.R 20 | import com.sollyu.android.appenv.commons.SettingsXposed 21 | import com.sollyu.android.appenv.define.AppEnvConstants 22 | import com.sollyu.android.appenv.events.EventSample 23 | import com.squareup.okhttp.Callback 24 | import com.squareup.okhttp.OkHttpClient 25 | import com.squareup.okhttp.Request 26 | import com.squareup.okhttp.Response 27 | import kotlinx.android.synthetic.main.activity_scan_qr.* 28 | import kotlinx.android.synthetic.main.activity_scan_qr.view.* 29 | import kotlinx.android.synthetic.main.include_toolbar.* 30 | import org.greenrobot.eventbus.EventBus 31 | import ru.alexbykov.nopermission.PermissionHelper 32 | import java.io.IOException 33 | 34 | class ActivityScanQR : ActivityBase(){ 35 | private val permissionHelper by lazy { PermissionHelper(activity) } 36 | private val fromActivity by lazy { activity.intent.getIntExtra("fromActivity", ActivityScanQR.FROM_DETAIL) } 37 | 38 | companion object { 39 | val FROM_DETAIL = 1 40 | 41 | fun launch(activity: Activity, fromActivity: Int) { 42 | val intent = Intent(activity, ActivityScanQR::class.java) 43 | intent.putExtra("fromActivity", fromActivity) 44 | activity.startActivity(intent) 45 | } 46 | } 47 | 48 | override fun getMobclickAgentTag(): String { 49 | return "ScanQR" 50 | } 51 | 52 | override fun onInitView() { 53 | super.onInitView() 54 | setContentView(R.layout.activity_scan_qr) 55 | 56 | setSupportActionBar(toolbar) 57 | supportActionBar?.setTitle(R.string.scan_qr) 58 | supportActionBar?.setHomeButtonEnabled(true) 59 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 60 | } 61 | 62 | override fun onInitDone() { 63 | super.onInitDone() 64 | 65 | permissionHelper.check(Manifest.permission.CAMERA) 66 | permissionHelper.onSuccess{ 67 | var justOnce = 0 68 | qrCodeReaderView.setQRDecodingEnabled(true); 69 | qrCodeReaderView.setAutofocusInterval(2000L) 70 | qrCodeReaderView.setTorchEnabled(true) 71 | qrCodeReaderView.setOnQRCodeReadListener { text, _ -> 72 | qrCodeReaderView.stopCamera() 73 | if (text.startsWith(AppEnvConstants.URL_APPENV_SHARE_START)) { 74 | 75 | if (justOnce > 0) { 76 | return@setOnQRCodeReadListener 77 | } 78 | justOnce += 1 79 | 80 | val materialDialog = MaterialDialog.Builder(activity).title(R.string.tip).content("下载中……").progress(true, 0).cancelable(false).show() 81 | OkHttpClient().newCall(Request.Builder().url(text).build()).enqueue(object : Callback { 82 | override fun onFailure(request: Request, e: IOException) { 83 | materialDialog.dismiss() 84 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.tip).content("下载出现错误:\n" + Log.getStackTraceString(e)).positiveText(android.R.string.ok).show() } 85 | } 86 | 87 | override fun onResponse(response: Response) { 88 | materialDialog.dismiss() 89 | val serverResult = response.body().string() 90 | try { 91 | val resultJsonObject = JSON.parseObject(serverResult) 92 | if (resultJsonObject.getInteger("ret") == 200) { 93 | if (fromActivity == FROM_DETAIL) { 94 | EventBus.getDefault().post(EventSample(EventSample.TYPE.DETAIL_JSON_2_UI, resultJsonObject.getJSONObject("data"))) 95 | activity.finish() 96 | } 97 | } else { 98 | qrCodeReaderView.startCamera() 99 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.tip).content("下载出现错误:\n" + resultJsonObject.getString("msg")).positiveText(android.R.string.ok).show() } 100 | } 101 | } catch (e: Exception) { 102 | qrCodeReaderView.startCamera() 103 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.tip).content("下载出现错误").positiveText(android.R.string.ok).show() } 104 | } 105 | } 106 | }) 107 | } else { 108 | MaterialDialog.Builder(activity).title(R.string.tip).content("此二维码不是应用变量分享的内容").onAny { _, _ -> qrCodeReaderView.startCamera() }.show() 109 | } 110 | } 111 | qrCodeReaderView.setBackCamera() 112 | qrCodeReaderView.startCamera() 113 | } 114 | permissionHelper.onDenied { 115 | MaterialDialog.Builder(activity) 116 | .title(R.string.tip) 117 | .content(R.string.splash_permission_write_storage_denied_content) 118 | .positiveText(android.R.string.ok) 119 | .show() 120 | } 121 | permissionHelper.onNeverAskAgain { 122 | Toast.makeText(activity, R.string.splash_permission_write_storage_denied_content, Toast.LENGTH_LONG).show() 123 | } 124 | permissionHelper.run() 125 | } 126 | 127 | override fun onResume() { 128 | super.onResume() 129 | qrCodeReaderView.startCamera() 130 | } 131 | 132 | override fun onPause() { 133 | super.onPause() 134 | qrCodeReaderView.stopCamera() 135 | } 136 | 137 | override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { 138 | super.onRequestPermissionsResult(requestCode, permissions, grantResults) 139 | permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults) 140 | } 141 | 142 | } 143 | -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/activitys/ActivitySplash.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.activitys 10 | 11 | import android.Manifest 12 | import android.os.Handler 13 | import android.widget.Toast 14 | import com.afollestad.materialdialogs.MaterialDialog 15 | import com.elvishew.xlog.XLog 16 | import com.sollyu.android.appenv.R 17 | import com.sollyu.android.appenv.commons.Application 18 | import ru.alexbykov.nopermission.PermissionHelper 19 | 20 | 21 | /** 22 | * 作者:sollyu 23 | * 时间:2017/11/20 24 | * 说明:闪屏界面 25 | */ 26 | class ActivitySplash : ActivityBase(), Runnable { 27 | 28 | private val permissionHelper by lazy { PermissionHelper(activity) } 29 | 30 | override fun run() { 31 | 32 | /* Xposed 没有成功的状态 */ 33 | if (!Application.Instance.isXposedWork()) { 34 | XLog.e("Xposed Is Not Work") 35 | MaterialDialog 36 | .Builder(activity) 37 | .title(R.string.splash_xposed_not_work_title) 38 | .content(R.string.splash_xposed_not_work_content) 39 | .positiveText(android.R.string.ok) 40 | .onAny { _, _ -> ActivityMain.launch(activity) } 41 | .canceledOnTouchOutside(false) 42 | .show() 43 | return 44 | } 45 | 46 | /* 状态检查结束、进入主界面 */ 47 | ActivityMain.launch(activity) 48 | } 49 | 50 | override fun onInitDone() { 51 | super.onInitDone() 52 | 53 | permissionHelper.check(Manifest.permission.WRITE_EXTERNAL_STORAGE) 54 | permissionHelper.onSuccess { 55 | Handler().postAtTime(this, 1000) 56 | } 57 | permissionHelper.onDenied { 58 | MaterialDialog.Builder(activity) 59 | .title(R.string.tip) 60 | .content(R.string.splash_permission_write_storage_denied_content) 61 | .positiveText(android.R.string.ok).onPositive { _, _ -> Handler().postAtTime(this, 1000) } 62 | .show() 63 | } 64 | permissionHelper.onNeverAskAgain { 65 | Toast.makeText(activity, R.string.splash_permission_write_storage_denied_content, Toast.LENGTH_LONG).show() 66 | } 67 | permissionHelper.run() 68 | } 69 | 70 | override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { 71 | super.onRequestPermissionsResult(requestCode, permissions, grantResults) 72 | permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults) 73 | } 74 | 75 | override fun getMobclickAgentTag(): String { 76 | return "Splash" 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/activitys/ActivityWeb.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.activitys 10 | 11 | import android.app.Activity 12 | import android.content.Intent 13 | import android.util.Log 14 | import android.view.MenuItem 15 | import android.webkit.JavascriptInterface 16 | import android.webkit.WebView 17 | import android.widget.LinearLayout 18 | import com.afollestad.materialdialogs.MaterialDialog 19 | import com.alibaba.fastjson.JSON 20 | import com.elvishew.xlog.XLog 21 | import com.just.agentweb.AgentWeb 22 | import com.just.agentweb.AgentWebConfig 23 | import com.just.agentweb.ChromeClientCallbackManager 24 | import com.sollyu.android.appenv.R 25 | import com.sollyu.android.appenv.commons.SettingsXposed 26 | import com.sollyu.android.appenv.define.AppEnvConstants 27 | import com.sollyu.android.appenv.events.EventSample 28 | import com.squareup.okhttp.Callback 29 | import com.squareup.okhttp.OkHttpClient 30 | import com.squareup.okhttp.Request 31 | import com.squareup.okhttp.Response 32 | import kotlinx.android.synthetic.main.activity_web.* 33 | import kotlinx.android.synthetic.main.include_toolbar.* 34 | import org.greenrobot.eventbus.EventBus 35 | import java.io.IOException 36 | 37 | class ActivityWeb : ActivityBase(), ChromeClientCallbackManager.ReceivedTitleCallback { 38 | companion object { 39 | fun launch(activity: Activity, webTitle: String, webUrl: String) { 40 | val intent = Intent(activity, ActivityWeb::class.java) 41 | intent.putExtra("webTitle", webTitle) 42 | intent.putExtra("webUrl", webUrl) 43 | activity.startActivity(intent) 44 | } 45 | } 46 | 47 | val agentWeb by lazy { 48 | AgentWeb.with(activity) 49 | .setAgentWebParent(linearLayout, LinearLayout.LayoutParams(-1, -1)) 50 | .useDefaultIndicator() 51 | .defaultProgressBarColor() 52 | .setReceivedTitleCallback(this) 53 | .createAgentWeb() 54 | .ready() 55 | .go(intent.getStringExtra("webUrl")) 56 | } 57 | 58 | override fun getMobclickAgentTag(): String { 59 | return "Web" 60 | } 61 | 62 | override fun onInitView() { 63 | super.onInitView() 64 | setContentView(R.layout.activity_web) 65 | 66 | setSupportActionBar(toolbar) 67 | supportActionBar?.title = intent.getStringExtra("webTitle") 68 | supportActionBar?.setHomeButtonEnabled(true) 69 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 70 | } 71 | 72 | override fun onInitDone() { 73 | super.onInitDone() 74 | agentWeb.jsInterfaceHolder.addJavaObject("android", JsInterfaceHolder()) 75 | } 76 | 77 | override fun onReceivedTitle(view: WebView, title: String) { 78 | supportActionBar?.title = title 79 | } 80 | 81 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 82 | if (agentWeb.back()) 83 | return true 84 | 85 | if (item.itemId == android.R.id.home) { 86 | onBackPressed() 87 | } 88 | return super.onOptionsItemSelected(item) 89 | } 90 | 91 | override fun onPause() { 92 | super.onPause() 93 | agentWeb.webLifeCycle.onPause() 94 | } 95 | 96 | override fun onResume() { 97 | super.onResume() 98 | agentWeb.webLifeCycle.onResume() 99 | } 100 | 101 | override fun onDestroy() { 102 | super.onDestroy() 103 | agentWeb.webLifeCycle.onDestroy() 104 | } 105 | 106 | inner class JsInterfaceHolder{ 107 | 108 | @Suppress("unused") 109 | @JavascriptInterface 110 | fun register() { 111 | ActivityRegister.launch(activity) 112 | } 113 | 114 | @Suppress("unused") 115 | @JavascriptInterface 116 | fun downloadConfig(configId: String, packageName: String, configName: String, packageLabel: String) { 117 | MaterialDialog.Builder(activity) 118 | .title(R.string.tip) 119 | .content("确定下载:$configName 到 $packageLabel ?") 120 | .positiveText("确定") 121 | .negativeText(android.R.string.cancel) 122 | .onPositive { dialog, _ -> 123 | val cookie = AgentWebConfig.getCookiesByUrl(AppEnvConstants.URL_APPENV_SERVER) 124 | OkHttpClient().newCall(Request.Builder().url(AppEnvConstants.URL_APPENV_DOWNLOAD_PACKAGE + "?config_id=" + configId).header("Cookie", cookie).build()).enqueue(object : Callback { 125 | override fun onFailure(request: Request, e: IOException) { 126 | dialog.dismiss() 127 | XLog.e(e.toString(), e) 128 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.tip).content("下载出现错误:\n" + Log.getStackTraceString(e)).positiveText(android.R.string.ok).show() } 129 | } 130 | 131 | override fun onResponse(response: Response) { 132 | dialog.dismiss() 133 | val serverResult = response.body().string() 134 | try { 135 | val resultJsonObject = JSON.parseObject(serverResult) 136 | if (resultJsonObject.getInteger("ret") == 200) { 137 | SettingsXposed.Instance.set(packageName, resultJsonObject.getJSONObject("data")) 138 | EventBus.getDefault().postSticky(EventSample(EventSample.TYPE.MAIN_REFRESH)) 139 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.tip).content("下载并应用成功").positiveText(android.R.string.ok).show() } 140 | } else { 141 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.tip).content("下载出现错误:\n" + resultJsonObject.getString("msg")).positiveText(android.R.string.ok).show() } 142 | } 143 | } catch (e: Exception) { 144 | activity.runOnUiThread { MaterialDialog.Builder(activity).title(R.string.tip).content("下载出现错误:\n请确定您已经正确的登陆").positiveText(android.R.string.ok).show() } 145 | } 146 | } 147 | }) 148 | } 149 | .show() 150 | } 151 | } 152 | 153 | } 154 | -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/bean/BeanHookInfo.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | package com.sollyu.android.appenv.bean 9 | 10 | import com.alibaba.fastjson.JSON 11 | import com.alibaba.fastjson.JSONObject 12 | import com.alibaba.fastjson.annotation.JSONField 13 | 14 | class BeanHookInfo { 15 | @JSONField(name = "android.os.Build.ro.product.manufacturer") 16 | var buildManufacturer:String? = null 17 | 18 | @JSONField(name = "android.os.Build.ro.product.model") 19 | var buildModel:String? = null 20 | 21 | @JSONField(name = "android.os.Build.ro.serialno") 22 | var buildSerial:String? = null 23 | 24 | @JSONField(name = "android.os.Build.VERSION.RELEASE") 25 | var buildVersionName:String? = null 26 | 27 | @JSONField(name = "android.os.SystemProperties.android_id") 28 | var androidId:String? = null 29 | 30 | @JSONField(name = "android.telephony.TelephonyManager.getLine1Number") 31 | var simLine1Number:String? = null 32 | 33 | @JSONField(name = "android.telephony.TelephonyManager.getDeviceId") 34 | var simGetDeviceId:String? = null 35 | 36 | @JSONField(name = "android.telephony.TelephonyManager.getSubscriberId") 37 | var simSubscriberId:String? = null 38 | 39 | @JSONField(name = "android.telephony.TelephonyManager.getSimOperator") 40 | var simOperator:String? = null 41 | 42 | @JSONField(name = "android.telephony.TelephonyManager.getSimCountryIso") 43 | var simCountryIso:String? = null 44 | 45 | @JSONField(name = "android.telephony.TelephonyManager.getSimOperatorName") 46 | var simOperatorName:String? = null 47 | 48 | @JSONField(name = "android.telephony.TelephonyManager.getSimSerialNumber") 49 | var simSerialNumber:String? = null 50 | 51 | @JSONField(name = "android.telephony.TelephonyManager.getSimState") 52 | var simStatus:String? = null 53 | 54 | @JSONField(name = "android.net.NetworkInfo.getType") 55 | var phoneNetworkType:String? = null 56 | 57 | @JSONField(name = "android.net.wifi.WifiInfo.getSSID") 58 | var wifiName:String? = null 59 | 60 | @JSONField(name = "android.net.wifi.WifiInfo.getBSSID") 61 | var wifiBssid:String? = null 62 | 63 | @JSONField(name = "android.net.wifi.WifiInfo.getMacAddress") 64 | var wifiMacAddress:String? = null 65 | 66 | @JSONField(name = "android.content.res.language") 67 | var language:String? = null 68 | 69 | @JSONField(name = "android.content.res.display.dpi") 70 | var displayDpi:String? = null 71 | 72 | @JSONField(serialize = false) 73 | override fun toString(): String { 74 | return JSON.toJSONString(this) 75 | } 76 | 77 | fun toJSON():JSONObject{ 78 | return JSON.parseObject(toString()) 79 | } 80 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/bean/PhoneModel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.bean 10 | 11 | import com.alibaba.fastjson.JSON 12 | import com.alibaba.fastjson.annotation.JSONField 13 | 14 | /** 15 | * 作者:sollyu 16 | * 时间:2017/12/8 17 | * 说明: 18 | */ 19 | class PhoneModel { 20 | 21 | constructor() 22 | 23 | constructor(manufacturer: String?, model: String?, name: String?) { 24 | this.manufacturer = manufacturer 25 | this.model = model 26 | this.name = name 27 | } 28 | 29 | @JSONField(name = "buildManufacturer") 30 | var manufacturer: String? = null 31 | 32 | @JSONField(name = "buildModel") 33 | var model: String? = null 34 | 35 | @JSONField(name = "phoneName") 36 | var name: String? = null 37 | 38 | @JSONField(serialize = false) 39 | override fun toString(): String { 40 | return JSON.toJSONString(this) 41 | } 42 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/commons/Application.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.commons 10 | 11 | import android.annotation.SuppressLint 12 | import android.support.v7.app.AppCompatDelegate 13 | import android.util.Log 14 | import com.elvishew.xlog.LogConfiguration 15 | import com.elvishew.xlog.LogLevel 16 | import com.elvishew.xlog.XLog 17 | import com.elvishew.xlog.flattener.Flattener 18 | import com.elvishew.xlog.printer.AndroidPrinter 19 | import com.elvishew.xlog.printer.file.FilePrinter 20 | import com.elvishew.xlog.printer.file.backup.NeverBackupStrategy 21 | import com.sollyu.android.appenv.BuildConfig 22 | import com.sollyu.android.not.proguard.NotProguard 23 | import com.umeng.analytics.MobclickAgent 24 | import com.umeng.commonsdk.UMConfigure 25 | import org.apache.commons.io.FileUtils 26 | import org.apache.commons.io.IOUtils 27 | import java.text.SimpleDateFormat 28 | import java.util.* 29 | 30 | /** 31 | * 作者:sollyu 32 | * 时间:2017/11/20 33 | * 说明: 34 | */ 35 | class Application : android.app.Application(), Thread.UncaughtExceptionHandler { 36 | 37 | companion object { 38 | @SuppressLint("StaticFieldLeak") 39 | lateinit var Instance: com.sollyu.android.appenv.commons.Application 40 | private set 41 | } 42 | 43 | init { 44 | Instance = this 45 | } 46 | 47 | override fun onCreate() { 48 | super.onCreate() 49 | 50 | // 初始化日志 51 | val logConfiguration = LogConfiguration.Builder().tag("AppEnv").logLevel(if (BuildConfig.DEBUG) LogLevel.ALL else LogLevel.WARN).build() 52 | val logAndroid = AndroidPrinter() 53 | val logFile = FilePrinter.Builder(Instance.externalCacheDir.absolutePath).backupStrategy(NeverBackupStrategy()).logFlattener(MyLogFlattener()).build() 54 | 55 | XLog.init(logConfiguration, logAndroid, logFile) 56 | // 添加崩溃捕获 57 | Thread.setDefaultUncaughtExceptionHandler(this) 58 | 59 | // 设置主题默认值 60 | AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO) 61 | 62 | // 友盟统计 63 | UMConfigure.init(Instance, "558a1cb667e58e7649000228", BuildConfig.FLAVOR, MobclickAgent.EScenarioType.E_UM_NORMAL.toValue(), "") 64 | 65 | // 初始化机型 66 | if (!Phones.Instance.phoneFile.exists()) { 67 | FileUtils.writeStringToFile(Phones.Instance.phoneFile, IOUtils.toString(Instance.assets.open("app.env.phone.json"), "UTF-8"), "UTF-8") 68 | } 69 | Phones.Reload() 70 | 71 | // 汇报机型 72 | PhoneReport.Instance.start() 73 | } 74 | 75 | override fun uncaughtException(t: Thread?, throwable: Throwable?) { 76 | XLog.e(throwable?.message, throwable) 77 | } 78 | 79 | @NotProguard 80 | open fun isXposedWork(): Boolean { 81 | // In some frameworks, short methods (less than two Dalvik instructions) 82 | // can not be hooked stably. This log just makes the method longer to hook. 83 | Log.v("fake", "$javaClass.isModuleLoaded() invoked.") 84 | return false 85 | } 86 | 87 | inner class MyLogFlattener : Flattener { 88 | override fun flatten(logLevel: Int, tag: String, message: String): CharSequence { 89 | return SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(Date(System.currentTimeMillis())) + " [" + LogLevel.getShortLevelName(logLevel) + "] " + message 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/commons/FloatingActionMenuBehavior.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.commons; 10 | 11 | import android.content.Context; 12 | import android.support.design.widget.CoordinatorLayout; 13 | import android.support.design.widget.Snackbar; 14 | import android.util.AttributeSet; 15 | import android.view.View; 16 | 17 | /** 18 | * Created by Andrey Kalashnikov on 08.10.16. 19 | * KSystems 20 | * andrey.k@ksyste.ms 21 | */ 22 | @SuppressWarnings("unused") 23 | public class FloatingActionMenuBehavior extends CoordinatorLayout.Behavior { 24 | 25 | public FloatingActionMenuBehavior(Context context, AttributeSet attrs) { 26 | super(); 27 | } 28 | 29 | @Override 30 | public boolean layoutDependsOn(CoordinatorLayout parent, com.github.clans.fab.FloatingActionMenu child, View dependency) { 31 | return dependency instanceof Snackbar.SnackbarLayout; 32 | } 33 | 34 | @Override 35 | public boolean onDependentViewChanged(CoordinatorLayout parent, com.github.clans.fab.FloatingActionMenu child, View dependency) { 36 | float translationY = Math.min(0, dependency.getTranslationY() - dependency.getHeight()); 37 | child.setTranslationY(translationY); 38 | return true; 39 | } 40 | 41 | @Override 42 | public void onDependentViewRemoved(CoordinatorLayout parent, com.github.clans.fab.FloatingActionMenu child, View dependency) { 43 | float translationY = Math.max(0, dependency.getTranslationY() - dependency.getHeight()); 44 | child.setTranslationY(translationY); 45 | super.onDependentViewRemoved(parent, child, dependency); 46 | } 47 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/commons/PhoneReport.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.commons 10 | 11 | import android.annotation.SuppressLint 12 | import android.content.Context 13 | import android.net.wifi.WifiInfo 14 | import android.net.wifi.WifiManager 15 | import android.os.Build 16 | import android.preference.PreferenceManager 17 | import android.provider.Settings 18 | import android.telephony.TelephonyManager 19 | import com.alibaba.fastjson.JSON 20 | import com.elvishew.xlog.XLog 21 | import com.sollyu.android.appenv.define.AppEnvConstants 22 | import com.squareup.okhttp.* 23 | import org.apache.commons.io.FileUtils 24 | import java.io.File 25 | import java.io.IOException 26 | 27 | /** 28 | * 作者:sollyu 29 | * 时间:2017/12/28 30 | * 说明: 31 | */ 32 | class PhoneReport { 33 | companion object { 34 | var Instance = PhoneReport() 35 | } 36 | 37 | @SuppressLint("WifiManagerLeak", "HardwareIds") 38 | fun start() { 39 | val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(Application.Instance) 40 | if (sharedPreferences.getBoolean("report_phone", false)) { 41 | return 42 | } 43 | 44 | val umengFile = File(Application.Instance.filesDir, ".umeng/exchangeIdentity.json") 45 | if (!umengFile.exists() || !umengFile.canRead()) { 46 | return 47 | } 48 | 49 | val umengJson = JSON.parseObject(FileUtils.readFileToString(umengFile, "UTF-8")) 50 | if (umengJson.getString("umid") == null || umengJson.getString("umid").isEmpty()) { 51 | return 52 | } 53 | 54 | val postBody = FormEncodingBuilder() 55 | postBody.add("android.umeng.umid" , umengJson.getString("umid")) 56 | postBody.add("android.os.Build.ro.product.manufacturer", Build.MANUFACTURER) 57 | postBody.add("android.os.Build.ro.product.model" , Build.MODEL) 58 | postBody.add("android.os.Build.ro.product.fingerprint" , Build.FINGERPRINT) 59 | postBody.add("android.os.Build.ro.serialno" , Build.SERIAL) 60 | postBody.add("android.os.Build.VERSION.RELEASE" , Build.VERSION.RELEASE) 61 | postBody.add("android.os.SystemProperties.android_id" , Settings.Secure.getString(Application.Instance.contentResolver, Settings.Secure.ANDROID_ID)) 62 | 63 | arrayListOf("getLine1Number", "getDeviceId", "getSubscriberId", "getSimOperator", "getSimCountryIso", "getSimOperatorName", "getSimSerialNumber", "getSimState").forEach { 64 | try { 65 | val telephonyManager = Application.Instance.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager 66 | postBody.add("android.telephony.TelephonyManager.$it", TelephonyManager::class.java.getMethod(it).invoke(telephonyManager).toString()) 67 | } catch (t: Throwable) { } 68 | } 69 | 70 | arrayListOf("getSSID", "getBSSID", "getMacAddress").forEach { 71 | try { 72 | val wifiManager = Application.Instance.getSystemService(Context.WIFI_SERVICE) as WifiManager 73 | val connectionInfo = wifiManager.connectionInfo 74 | postBody.add("android.net.wifi.WifiInfo.$it", WifiInfo::class.java.getMethod(it).invoke(connectionInfo).toString()) 75 | } catch (t: Throwable) { } 76 | } 77 | 78 | OkHttpClient().newCall(Request.Builder().url(AppEnvConstants.URL_APPENV_REPORT_PHONE).post(postBody.build()).build()).enqueue(object : Callback{ 79 | override fun onFailure(request: Request, e: IOException) { } 80 | 81 | override fun onResponse(response: Response) { 82 | val serverResult = response.body().string() 83 | try { 84 | val resultJsonObject = JSON.parseObject(serverResult) 85 | if (resultJsonObject.getInteger("ret") == 200) { 86 | sharedPreferences.edit().putBoolean("report_phone", true).apply() 87 | } 88 | } catch (e: Exception) { } 89 | } 90 | }) 91 | } 92 | 93 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/commons/Phones.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.commons 10 | 11 | import com.alibaba.fastjson.JSON 12 | import com.alibaba.fastjson.annotation.JSONField 13 | import com.elvishew.xlog.XLog 14 | import com.sollyu.android.appenv.bean.PhoneModel 15 | import org.apache.commons.io.FileUtils 16 | import java.io.File 17 | import java.util.* 18 | 19 | /** 20 | * 作者:sollyu 21 | * 时间:2017/12/8 22 | * 说明: 23 | */ 24 | class Phones { 25 | companion object { 26 | var Instance = Phones() 27 | 28 | @Synchronized 29 | fun Reload() { 30 | if (Instance.phoneFile.exists()) { 31 | Instance = JSON.toJavaObject(JSON.parseObject(FileUtils.readFileToString(Instance.phoneFile, "UTF-8")), Phones::class.java) 32 | } 33 | } 34 | } 35 | 36 | @JSONField(name = "VersionName") 37 | var versionName = "1.0.1" 38 | 39 | @JSONField(name = "VersionCode") 40 | var versionCode = 1 41 | 42 | @JSONField(name = "PhoneList") 43 | var phoneList = HashMap>() 44 | 45 | @JSONField(serialize = false) 46 | val phoneFile = File(Application.Instance.getExternalFilesDir(null), "appenv.phone.json") 47 | 48 | @JSONField(serialize = false) 49 | fun save() { 50 | if (!Instance.phoneFile.parentFile.exists() && !Instance.phoneFile.parentFile.mkdirs()) return 51 | FileUtils.writeStringToFile(Instance.phoneFile, JSON.toJSONString(Instance, true), "UTF-8") 52 | } 53 | 54 | @JSONField(serialize = false) 55 | override fun toString(): String { 56 | return JSON.toJSONString(this) 57 | } 58 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/commons/Settings.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.commons 10 | 11 | import com.alibaba.fastjson.JSON 12 | import com.alibaba.fastjson.JSONObject 13 | import org.apache.commons.io.FileUtils 14 | import java.io.File 15 | 16 | /** 17 | * 作者:sollyu 18 | * 时间:2017/11/21 19 | * 说明: 20 | */ 21 | class Settings { 22 | companion object { 23 | val Instance = Settings() 24 | } 25 | 26 | val file: File by lazy { File(Application.Instance.getExternalFilesDir(null), "appenv.setting.json") } 27 | var jsonObject: JSONObject = JSONObject() 28 | 29 | init { 30 | reload() 31 | } 32 | 33 | /** 34 | * 重新加载配置文件 35 | */ 36 | @Synchronized 37 | fun reload() { 38 | var jsonObjectTmp = JSONObject() 39 | if (file.exists()) { 40 | jsonObjectTmp = JSON.parseObject(FileUtils.readFileToString(file, "UTF-8")) 41 | } 42 | jsonObject = jsonObjectTmp 43 | } 44 | 45 | /** 46 | * 保存配置文件 47 | */ 48 | @Synchronized 49 | fun save() { 50 | FileUtils.write(file, JSON.toJSONString(jsonObject, true), "UTF-8") 51 | } 52 | 53 | /** 54 | * 删除一个配置文件 55 | */ 56 | fun remove(keyName: String) { 57 | jsonObject.remove(keyName) 58 | save() 59 | } 60 | 61 | /** 62 | * 是否显示系统程序 63 | */ 64 | var isShowSystemApp: Boolean 65 | get() = jsonObject.getBooleanValue("isShowSystemApp") 66 | set(value) = jsonObject.put("isShowSystemApp", value).let { save() } 67 | 68 | /** 69 | * 是否显示桌面图标 70 | */ 71 | var isShowDesktopIcon: Boolean 72 | get() = jsonObject.getBoolean("isShowDesktopIcon") ?: true 73 | set(value) = jsonObject.put("isShowDesktopIcon", value).let { save() } 74 | 75 | /** 76 | * 是否直接使用root权限 77 | */ 78 | var isUseRoot: Boolean 79 | get() = jsonObject.getBoolean("isUseRoot") ?: false 80 | set(value) = jsonObject.put("isUseRoot", value).let { save() } 81 | 82 | /** 83 | * 是否使用SD卡配置 84 | */ 85 | var isUseAppDataConfig: Boolean 86 | get() = jsonObject.getBoolean("isUseAppDataConfig") ?: false 87 | set(value) = jsonObject.put("isUseAppDataConfig", value).let { save() } 88 | 89 | /** 90 | * 使用/data/local/tmp存储配置 91 | */ 92 | var isUseDataLocalTmpConfig: Boolean 93 | get() = jsonObject.getBoolean("isUseDataLocalTmpConfig") ?: false 94 | set(value) = jsonObject.put("isUseDataLocalTmpConfig", value).let { save() } 95 | 96 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/commons/SettingsXposed.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.commons 10 | 11 | import com.alibaba.fastjson.JSON 12 | import com.alibaba.fastjson.JSONObject 13 | import org.apache.commons.io.FileUtils 14 | import java.io.File 15 | import com.elvishew.xlog.XLog 16 | import eu.chainfire.libsuperuser.Shell 17 | 18 | 19 | /** 20 | * 作者:sollyu 21 | * 时间:2017/11/21 22 | * 说明: 23 | */ 24 | class SettingsXposed { 25 | companion object { 26 | var Instance = SettingsXposed() 27 | 28 | @Synchronized 29 | fun Reload() { 30 | Instance = SettingsXposed() 31 | } 32 | 33 | @Synchronized 34 | fun Save() { 35 | when { 36 | Settings.Instance.isUseDataLocalTmpConfig -> { 37 | XLog.d("use data local tmp") 38 | // 使用Root命令进行创建 39 | if (!Instance.fileDataLocalConfig.exists()) { 40 | Shell.SU.run("touch /data/local/tmp/appenv.xposed.json") 41 | Shell.SU.run("chmod 777 /data/local/tmp/appenv.xposed.json") 42 | } 43 | 44 | // 文件依然还不存在 45 | if (!Instance.fileDataLocalConfig.exists()) { 46 | XLog.e("/data/local/tmp/appenv.xposed.json not exist") 47 | throw RuntimeException("/data/local/tmp/appenv.xposed.json not exist") 48 | } 49 | 50 | // 文件没有写的权限 51 | if (!Instance.fileDataLocalConfig.canWrite()) { 52 | Shell.SU.run("chmod 777 /data/local/tmp/appenv.xposed.json") 53 | } 54 | // 文件依然没有写的权限 55 | if (!Instance.fileDataLocalConfig.canWrite()) { 56 | XLog.e("/data/local/tmp/appenv.xposed.json can not write") 57 | throw RuntimeException("/data/local/tmp/appenv.xposed.json can not write") 58 | } 59 | 60 | FileUtils.write(Instance.fileDataLocalConfig, JSON.toJSONString(Instance.jsonObject, true), "UTF-8") 61 | try { FileUtils.forceDelete(Instance.fileAppDataConfig) } catch (e: Exception) { } 62 | try { FileUtils.forceDelete(Instance.fileExtendConfig) } catch (e: Exception) { } 63 | } 64 | Settings.Instance.isUseAppDataConfig -> { 65 | XLog.d("use app data") 66 | FileUtils.write(Instance.fileAppDataConfig, JSON.toJSONString(Instance.jsonObject, true), "UTF-8") 67 | try { FileUtils.forceDelete(Instance.fileExtendConfig) } catch (e: Exception) { } 68 | try { Shell.SU.run("rm " + Instance.fileDataLocalConfig) } catch (e: Exception) { } 69 | } 70 | else -> { 71 | XLog.d("use ext") 72 | FileUtils.write(Instance.fileExtendConfig, JSON.toJSONString(Instance.jsonObject, true), "UTF-8") 73 | try { FileUtils.forceDelete(Instance.fileAppDataConfig) } catch (e: Exception) { } 74 | try { Shell.SU.run("rm " + Instance.fileDataLocalConfig) } catch (e: Exception) { XLog.e(e.message, e) } 75 | } 76 | } 77 | } 78 | } 79 | 80 | private val fileAppDataConfig = File(Application.Instance.filesDir, "appenv.xposed.json") 81 | private val fileExtendConfig = File(Application.Instance.getExternalFilesDir(null), "appenv.xposed.json") 82 | private val fileDataLocalConfig = File("/data/local/tmp/appenv.xposed.json") 83 | 84 | val file: File by lazy { 85 | if (Settings.Instance.isUseAppDataConfig) 86 | fileAppDataConfig 87 | else if (Settings.Instance.isUseDataLocalTmpConfig) 88 | fileDataLocalConfig 89 | else 90 | fileExtendConfig 91 | } 92 | 93 | var jsonObject = JSONObject() 94 | 95 | init { 96 | reload() 97 | } 98 | 99 | /** 100 | * 重新加载配置文件 101 | */ 102 | @Synchronized 103 | fun reload() { 104 | var jsonObjectTmp = JSONObject() 105 | if (file.exists()) { 106 | jsonObjectTmp = JSON.parseObject(FileUtils.readFileToString(file, "UTF-8")) 107 | } 108 | jsonObject = jsonObjectTmp 109 | } 110 | 111 | /** 112 | * 保存配置文件 113 | */ 114 | @Synchronized 115 | fun save() { 116 | FileUtils.write(file, JSON.toJSONString(jsonObject, true), "UTF-8") 117 | } 118 | 119 | fun resetPermissions() { 120 | if (Settings.Instance.isUseAppDataConfig) { 121 | XLog.d("${file.absolutePath} resetPermissions") 122 | file.setReadable(true, false) 123 | file.setWritable(true, false) 124 | file.setExecutable(true,false) 125 | } 126 | } 127 | 128 | /** 129 | * 删除一个配置文件 130 | */ 131 | fun remove(packageName: String) { 132 | jsonObject.remove(packageName) 133 | save() 134 | } 135 | 136 | fun get(packageName: String): JSONObject? { 137 | return jsonObject.getJSONObject(packageName) 138 | } 139 | 140 | fun set(packageName: String, jsonObject: JSONObject) { 141 | this.jsonObject.put(packageName, jsonObject) 142 | this.save() 143 | } 144 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/commons/Solution.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.commons 10 | 11 | import com.alibaba.fastjson.JSON 12 | import com.alibaba.fastjson.JSONObject 13 | import org.apache.commons.io.FileUtils 14 | import java.io.File 15 | 16 | /** 17 | * 作者:sollyu 18 | * 时间:2017/12/12 19 | * 说明: 20 | */ 21 | class Solution { 22 | companion object { 23 | val Instance = Solution() 24 | } 25 | 26 | private val defaultConfigFile: File by lazy { File(Application.Instance.getExternalFilesDir(null), "appenv.solution.json") } 27 | 28 | var jsonObject = JSONObject() 29 | 30 | init { 31 | reload() 32 | } 33 | 34 | /** 35 | * 重新加载配置文件 36 | */ 37 | @Synchronized 38 | fun reload() { 39 | var jsonObjectTmp = JSONObject() 40 | if (defaultConfigFile.exists()) { 41 | jsonObjectTmp = JSON.parseObject(FileUtils.readFileToString(defaultConfigFile, "UTF-8")) 42 | } 43 | jsonObject = jsonObjectTmp 44 | } 45 | 46 | /** 47 | * 保存配置文件 48 | */ 49 | @Synchronized 50 | fun save() { 51 | FileUtils.write(defaultConfigFile, JSON.toJSONString(jsonObject, true), "UTF-8") 52 | } 53 | 54 | /** 55 | * 删除一个配置文件 56 | */ 57 | fun remove(packageName: String) { 58 | jsonObject.remove(packageName) 59 | save() 60 | } 61 | 62 | fun get(packageName: String): JSONObject? { 63 | return jsonObject.getJSONObject(packageName) 64 | } 65 | 66 | fun set(packageName: String, jsonObject: JSONObject) { 67 | this.jsonObject.put(packageName, jsonObject) 68 | this.save() 69 | } 70 | 71 | 72 | 73 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/commons/libs/IMEIGen.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.commons.libs 10 | 11 | /** 12 | * 作者:sollyu 13 | * 时间:2017/12/12 14 | * 说明: 15 | */ 16 | object IMEIGen { 17 | /** 18 | * IMEI 校验码 19 | 20 | * @param code 21 | * * 22 | * @return 23 | */ 24 | fun genCode(code: String): String { 25 | var sum1 = 0 26 | var sum2 = 0 27 | var temp: Int 28 | val chs = code.toCharArray() 29 | for (i in chs.indices) { 30 | val num = chs[i] - '0' 31 | if (i % 2 == 0) { 32 | sum1 += num 33 | } else { 34 | temp = num * 2 35 | if (temp < 10) { 36 | sum2 += temp 37 | } else { 38 | sum2 = sum2 + temp + 1 - 10 39 | } 40 | } 41 | } 42 | val total = sum1 + sum2 43 | /*如果得出的数个位是0则校验位为0,否则为10减去个位数 */ 44 | return if (total % 10 == 0) { 45 | "0" 46 | } else { 47 | (10 - total % 10).toString() + "" 48 | } 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/define/AppEnvConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.define; 10 | 11 | /** 12 | * 作者:sollyu 13 | * 时间:2017/12/8 14 | * 说明:常量定义类 15 | */ 16 | public class AppEnvConstants { 17 | public static final String URL_APPENV_HOST = "https://appenv.sollyu.com"; 18 | public static final String URL_APPENV_SERVER = URL_APPENV_HOST + "/admin"; 19 | public static final String URL_APPENV_UPLOAD_PACKAGE = URL_APPENV_SERVER + "/api/upload/package"; 20 | public static final String URL_APPENV_DOWNLOAD_PACKAGE = URL_APPENV_SERVER + "/api/download/package"; 21 | public static final String URL_APPENV_RANDOM_PACKAGE = URL_APPENV_SERVER + "/api/random/package"; 22 | public static final String URL_APPENV_SHARE_START = URL_APPENV_HOST + "/share"; 23 | public static final String URL_APPENV_REPORT_PHONE = URL_APPENV_HOST + "/api/phone/report"; 24 | public static final String URL_APPENV_REGISTER = URL_APPENV_HOST + "/api/register"; 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/com/sollyu/android/appenv/events/EventSample.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2017 Sollyu 3 | * 4 | * Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. 5 | * 6 | * This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 7 | */ 8 | 9 | package com.sollyu.android.appenv.events 10 | 11 | /** 12 | * 作者:sollyu 13 | * 时间:2017/10/30 14 | * 说明: 15 | */ 16 | class EventSample { 17 | enum class TYPE { 18 | MAIN_REFRESH, MAIN_LIST_CLEAR, MAIN_THEME_NIGHT, 19 | DETAIL_JSON_2_UI, 20 | } 21 | 22 | constructor(eventTYPE: TYPE) { 23 | this.eventTYPE = eventTYPE 24 | } 25 | 26 | constructor(eventTYPE: TYPE, value: Any) { 27 | this.eventTYPE = eventTYPE 28 | this.value = value 29 | } 30 | 31 | val eventTYPE: TYPE 32 | var value: Any? = null 33 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-land/splash_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-hacker/AppEnv-Kotlin/b11cddbed9427886cce8dd9d21da487a9aa68632/app/src/main/res/drawable-land/splash_img.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-port/splash_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/android-hacker/AppEnv-Kotlin/b11cddbed9427886cce8dd9d21da487a9aa68632/app/src/main/res/drawable-port/splash_img.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_camera.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_gallery.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_manage.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_send.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_share.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_slideshow.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 15 | 20 | 21 | 27 | 30 | 33 | 34 | 35 | 36 | 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_auto_fix.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cancel_w.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cloud_download.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_credit_card.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_crop_landscape.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_domain.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_done_all.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_done_all_w.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_folder.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_folder_shared.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_folder_shared_w.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info_outline.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launch.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 24 | 26 | 28 | 30 | 32 | 34 | 36 | 38 | 40 | 42 | 44 | 46 | 48 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 64 | 66 | 68 | 70 | 72 | 74 | 75 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_refresh.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_refresh_w.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_remove_circle.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_remove_circle_w.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_save.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_save_w.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_scan.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search_w.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_swap_horiz.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_system_update.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_thumb_up.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_unknown_6.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_video_youtube_w.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_wb_cloudy.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ios_back_drawable.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/splash_layer.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_about.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 16 | 17 | 23 | 24 | 32 | 33 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 20 | 21 | 22 | 23 | 36 | 37 | 45 | 46 | 47 | 55 | 56 | 64 | 65 | 72 | 73 | 80 | 81 | 89 | 90 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_log.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 21 | 22 | 23 | 24 | 27 | 28 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 23 | 24 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_register.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 21 | 22 | 23 | 24 | 27 | 28 | 34 | 35 | 36 | 37 | 44 | 45 | 51 | 52 | 62 | 63 | 64 | 65 | 66 | 67 | 74 | 75 | 81 | 82 | 92 | 93 | 94 | 95 | 96 | 97 | 104 | 105 | 111 | 112 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 135 | 136 | 142 | 143 | 153 | 154 | 155 | 156 | 157 | 158 |