├── .gitignore
├── .idea
├── compiler.xml
├── copyright
│ └── profiles_settings.xml
├── encodings.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── README_en.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── me
│ │ └── sweetll
│ │ └── evilhide
│ │ └── ApplicationTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── kotlin
│ │ └── me
│ │ │ └── sweetll
│ │ │ └── evilhide
│ │ │ ├── AppApplication.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── ProxyActivity.kt
│ │ │ ├── SettingsActivity.kt
│ │ │ ├── adapter
│ │ │ ├── AppAdapter.kt
│ │ │ └── BindingAdapter.kt
│ │ │ ├── config
│ │ │ ├── Settings.kt
│ │ │ └── SharedPreferenceConfig.kt
│ │ │ ├── extension
│ │ │ ├── SharedPreferenceExtensions.kt
│ │ │ └── StringExtensions.kt
│ │ │ ├── fragment
│ │ │ └── SettingFragment.kt
│ │ │ ├── model
│ │ │ └── AppInfo.kt
│ │ │ ├── receiver
│ │ │ └── CallReceiver.kt
│ │ │ ├── service
│ │ │ └── HiddenService.kt
│ │ │ └── viewmodel
│ │ │ └── AppViewModel.kt
│ └── res
│ │ ├── drawable
│ │ ├── ic_add.xml
│ │ └── ic_settings.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ ├── activity_settings.xml
│ │ └── item_app.xml
│ │ ├── menu
│ │ └── menu_main.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ ├── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ │ └── xml
│ │ └── settings.xml
│ └── test
│ └── java
│ └── me
│ └── sweetll
│ └── evilhide
│ └── ExampleUnitTest.kt
├── build.gradle
├── demo.gif
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | 1.8
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 中文 | [English][2]
2 |
3 | # Evil Hide
4 | 隐藏app的app。用处自己挖掘。
5 |
6 | 
7 |
8 | ### 注意:
9 | 只在Nexus 4、Nexus 5X上测试通过,小米手机不能使用(MIUI会把不在近期任务列表里的应用杀掉,导致应用的BroadcastReceiver不能响应拨号事件)
10 |
11 | ### 特点:
12 | - 可以隐藏软件自身的图标,并通过在拨号盘输入暗号启动应用
13 | - 不需要root!(仅限`原生Android 5.0`以上,一般而言,Nexus家族是可以使用的,包括但不限于Nexus 4、Nexus 5、Nexus 5x、Nexus 6P等,第三方厂商自己修改过的ROM不可使用,包括但不限于三星,小米,华为等)
14 |
15 | ### 原理
16 | 在Android 5.0以下使用以下命令显示和隐藏(需要root权限):
17 | ```
18 | adb shell pm endable
19 | adb shell pm disable
20 | ```
21 | 在Android 5.0及以上使用以下命令显示和隐藏(不需要root,但是需要系统权限):
22 | ```
23 | adb shell pm hide
24 | adb shell pm unhide
25 | ```
26 |
27 | 区别:
28 | `hide`命令相当于`uninstall -k`卸载应用但是保留数据
29 |
30 | 实际上,`hide`命令最终调用了以下函数(来自`android.content.pm.PackageManager`). 不幸的是, 它被标识为`@hide`, 所以在Android SDK中,你无法通过正常手段调用它.
31 | ```
32 | /**
33 | * Puts the package in a hidden state, which is almost like an uninstalled state,
34 | * making the package unavailable, but it doesn't remove the data or the actual
35 | * package file. Application can be unhidden by either resetting the hidden state
36 | * or by installing it, such as with {@link #installExistingPackage(String)}
37 | * @hide
38 | */
39 | public abstract boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
40 | UserHandle userHandle);
41 | ```
42 |
43 |
44 | ### 用法:
45 | 如果你想使用非root版本,请确保满足条件并切换到`noroot`分支
46 | ```
47 | git checkout noroot
48 | ```
49 |
50 | 本软件的默认启动密码是`#1234`
51 | 启动方式:
52 | 打开拨号盘,输入`#1234`,再拨出,就可以启动本应用了,然后在应用列表里选择应用是否隐藏即可
53 |
54 | ### 待做列表:
55 | - [x] Android 6.0的权限管理
56 | - [x] 当检测到手机是Android 4.4以上时,使用`pm hide`代替`pm disable`
57 | - [ ] 使用密码启动被隐藏的应用
58 |
59 | [1]: https://github.com/blackbbc/Evil-Hide/blob/master/README.md
60 | [2]: https://github.com/blackbbc/Evil-Hide/blob/master/README_en.md
61 |
--------------------------------------------------------------------------------
/README_en.md:
--------------------------------------------------------------------------------
1 | [中文][1] | English
2 |
3 | # Evil Hide
4 | This app is used to hide other apps' icon in the launcher.
5 | Note: After hide, the hidden app cannot be launched from anywhere before it is unhide.
6 |
7 | 
8 |
9 | ### Notice:
10 | Only tested on Nexus 4 and Nexus 5X. I also find that this app may not work on some ROM, such as MIUI for these ROM will kill apps that not show in the recent tasks, which cause the broadcastreceiver not work.
11 |
12 | ### Feature:
13 | - You can choose to hide the icon of this app. Then you can launch it by inputting password in the dial pad.
14 | - No root needed!(Only for rom build from `AOSP` and android version is bigger than 5.0. For example Nexus series, including Nexus 4, Nexus 5, Nexus 5x, Nexus 6p and etc)
15 |
16 | ### Theory
17 | Before Android 5.0, you can use the following shell commands to hide other apps (root permission is needed!):
18 | ```
19 | adb shell pm endable
20 | adb shell pm disable
21 | ```
22 | After Android 5.0, you can use the following shell commands to hide other apps(root permission is `not` needed!):
23 | ```
24 | adb shell pm hide
25 | adb shell pm unhide
26 | ```
27 |
28 | Difference between disable and unhide:
29 | `hide` is equals to `uninstall -k` which means uninstall application but keep data
30 |
31 | In fact, the `hide` command finally call the following function from `android.content.pm.PackageManager`. Unfortunately, it is marked as `@hide`, so you cannot use it in sdk.
32 | ```
33 | /**
34 | * Puts the package in a hidden state, which is almost like an uninstalled state,
35 | * making the package unavailable, but it doesn't remove the data or the actual
36 | * package file. Application can be unhidden by either resetting the hidden state
37 | * or by installing it, such as with {@link #installExistingPackage(String)}
38 | * @hide
39 | */
40 | public abstract boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
41 | UserHandle userHandle);
42 | ```
43 |
44 |
45 | ### Usage:
46 | If you'd like to use no root version. Please make sure you satisfy the conditions and switch to the `noroot` branch:
47 | ```
48 | git checkout noroot
49 | ```
50 |
51 | The default launch password is `#1234`
52 | Launch method:
53 | Open dial pad,input `#1234`,then press call button. This app will be launched
54 | After that, you can switch the app's hidden state in the list
55 |
56 | ### Todo list:
57 | - [x] Android M dynamic permission
58 | - [x] Support `hide` and `unhide` commands
59 | - [ ] Use password to launch hidden apps
60 |
61 | [1]: https://github.com/blackbbc/Evil-Hide/blob/master/README.md
62 | [2]: https://github.com/blackbbc/Evil-Hide/blob/master/README_en.md
63 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 |
4 | dependencies {
5 | compile fileTree(dir: 'libs', include: ['*.jar'])
6 | testCompile 'junit:junit:4.12'
7 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
8 | compile 'com.android.support:appcompat-v7:26.0.1'
9 | compile 'com.android.support:design:26.0.1'
10 | compile 'com.android.support:recyclerview-v7:26.0.1'
11 | compile 'com.karumi:dexter:4.1.0'
12 | compile 'eu.chainfire:libsuperuser:1.0.0.+'
13 | compile 'com.github.ivbaranov:materialfavoritebutton:0.1.2'
14 | kapt "com.android.databinding:compiler:$plugin_version"
15 | }
16 |
17 | android {
18 | compileSdkVersion 26
19 | buildToolsVersion "26.0.1"
20 |
21 | defaultConfig {
22 | applicationId "me.sweetll.evilhide"
23 | minSdkVersion 14
24 | targetSdkVersion 26
25 | versionCode 1
26 | versionName "1.0.0"
27 | }
28 | buildTypes {
29 | release {
30 | minifyEnabled false
31 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
32 | }
33 | }
34 | dataBinding {
35 | enabled = true
36 | }
37 | sourceSets {
38 | main.java.srcDirs += 'src/main/kotlin'
39 | }
40 | }
41 |
42 | kapt {
43 | generateStubs = true
44 | }
45 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /opt/android-sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/me/sweetll/evilhide/ApplicationTest.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide
2 |
3 | import android.app.Application
4 | import android.test.ApplicationTestCase
5 |
6 | /**
7 | * [Testing Fundamentals](http://d.android.com/tools/testing/testing_android.html)
8 | */
9 | class ApplicationTest : ApplicationTestCase(Application::class.java)
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
29 |
30 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/AppApplication.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide
2 |
3 | import android.app.Application
4 | import android.preference.PreferenceManager
5 |
6 | class AppApplication : Application() {
7 | companion object {
8 | private lateinit var INSTANCE: AppApplication
9 |
10 | fun get(): AppApplication = INSTANCE
11 | }
12 |
13 | override fun onCreate() {
14 | super.onCreate()
15 | INSTANCE = this
16 | PreferenceManager.setDefaultValues(this, R.xml.settings, false)
17 | }
18 | }
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide
2 |
3 | import android.Manifest
4 | import android.content.Intent
5 | import android.content.pm.ApplicationInfo
6 | import android.databinding.DataBindingUtil
7 | import android.support.v7.app.AppCompatActivity
8 | import android.os.Bundle
9 | import android.support.v7.widget.LinearLayoutManager
10 | import android.view.Menu
11 | import android.view.MenuItem
12 | import android.view.View
13 | import android.view.ViewGroup
14 | import android.widget.AdapterView
15 | import com.karumi.dexter.Dexter
16 | import com.karumi.dexter.listener.single.SnackbarOnDeniedPermissionListener
17 |
18 | import me.sweetll.evilhide.adapter.AppAdapter
19 | import me.sweetll.evilhide.config.Settings
20 | import me.sweetll.evilhide.databinding.ActivityMainBinding
21 | import me.sweetll.evilhide.extension.getFavorite
22 | import me.sweetll.evilhide.model.AppInfo
23 |
24 | class MainActivity : AppCompatActivity() {
25 | lateinit var binding: ActivityMainBinding
26 | val appAdapter = AppAdapter(mutableListOf())
27 |
28 | override fun onCreate(savedInstanceState: Bundle?) {
29 | super.onCreate(savedInstanceState)
30 | binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
31 | setSupportActionBar(binding.toolbar)
32 | supportActionBar!!.setDisplayShowTitleEnabled(false)
33 |
34 | initPermissions()
35 |
36 | setupRecyclerView()
37 |
38 | binding.spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
39 | override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
40 | populateAppList(position)
41 | }
42 |
43 | override fun onNothingSelected(parent: AdapterView<*>?) {
44 |
45 | }
46 | }
47 | }
48 |
49 | fun setupRecyclerView() {
50 | binding.appRecycler.layoutManager = LinearLayoutManager(this)
51 | binding.appRecycler.adapter = appAdapter
52 | }
53 |
54 | override fun onCreateOptionsMenu(menu: Menu): Boolean {
55 | menuInflater.inflate(R.menu.menu_main, menu)
56 | return true
57 | }
58 |
59 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
60 | when (item.itemId) {
61 | R.id.action_settings -> {
62 | val intent = Intent()
63 | intent.setClass(this, SettingsActivity::class.java)
64 | startActivity(intent)
65 | }
66 | }
67 | return super.onOptionsItemSelected(item)
68 | }
69 |
70 | fun initPermissions() {
71 | val snackBarPermissionListener = SnackbarOnDeniedPermissionListener.Builder
72 | .with(binding.root as ViewGroup, "需要电话权限以便从拨号盘启动")
73 | .withOpenSettingsButton("设置")
74 | .build()
75 | Dexter.withActivity(this)
76 | .withPermission(Manifest.permission.PROCESS_OUTGOING_CALLS)
77 | .withListener(snackBarPermissionListener)
78 | .check()
79 | }
80 |
81 | fun populateAppList(flag: Int) {
82 | val pm = packageManager
83 | val installedApps = pm.getInstalledApplications(0)
84 |
85 | appAdapter.setNewData(
86 | when (flag) {
87 | Settings.SPINNER_STAR_APP -> installedApps.filter { it.packageName.getFavorite() }
88 | Settings.SPINNER_HIDDEN_APP -> installedApps.filter { !it.enabled }
89 | else -> installedApps
90 | }
91 | .filter { it.packageName != BuildConfig.APPLICATION_ID && it.flags and ApplicationInfo.FLAG_SYSTEM != 1}
92 | .fold(mutableListOf(), {
93 | newData, applicationInfo ->
94 | newData.add(AppInfo(applicationInfo))
95 | newData
96 | })
97 | )
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/ProxyActivity.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide
2 |
3 | import android.content.Intent
4 | import android.support.v7.app.AppCompatActivity
5 | import android.os.Bundle
6 |
7 | class ProxyActivity : AppCompatActivity() {
8 |
9 | override fun onCreate(savedInstanceState: Bundle?) {
10 | super.onCreate(savedInstanceState)
11 | val intent = Intent(this, MainActivity::class.java)
12 | intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
13 | startActivity(intent)
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/SettingsActivity.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide
2 |
3 | import android.databinding.DataBindingUtil
4 | import android.os.Bundle
5 | import android.support.v7.app.AppCompatActivity
6 |
7 | import me.sweetll.evilhide.databinding.ActivitySettingsBinding
8 | import me.sweetll.evilhide.fragment.SettingFragment
9 |
10 | class SettingsActivity : AppCompatActivity() {
11 |
12 | public override fun onCreate(savedInstanceState: Bundle?) {
13 | super.onCreate(savedInstanceState)
14 | val binding : ActivitySettingsBinding = DataBindingUtil.setContentView(this, R.layout.activity_settings)
15 | fragmentManager.beginTransaction()
16 | .replace(android.R.id.content, SettingFragment())
17 | .commit()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/adapter/AppAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide.adapter
2 |
3 | import android.databinding.DataBindingUtil
4 | import android.support.v7.widget.RecyclerView
5 | import android.view.LayoutInflater
6 | import android.view.ViewGroup
7 | import me.sweetll.evilhide.R
8 | import me.sweetll.evilhide.databinding.ItemAppBinding
9 | import me.sweetll.evilhide.model.AppInfo
10 | import me.sweetll.evilhide.viewmodel.AppViewModel
11 |
12 | class AppAdapter(var data: MutableList) : RecyclerView.Adapter() {
13 |
14 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
15 | val binding: ItemAppBinding = DataBindingUtil.inflate(
16 | LayoutInflater.from(parent.context),
17 | R.layout.item_app,
18 | parent,
19 | false)
20 | return ViewHolder(binding)
21 | }
22 |
23 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
24 | val appInfo = data[position]
25 | holder.bindAppInfo(appInfo)
26 | }
27 |
28 | override fun getItemCount(): Int = data.size
29 |
30 | fun setNewData(newData: MutableList) {
31 | data.clear()
32 | data.addAll(newData)
33 | notifyDataSetChanged()
34 | }
35 |
36 | class ViewHolder(val binding: ItemAppBinding): RecyclerView.ViewHolder(binding.root) {
37 | fun bindAppInfo(appInfo: AppInfo) {
38 | binding.starBtn.setOnFavoriteChangeListener{
39 | button, favorite ->
40 | if (button.isPressed) {
41 | binding.viewModel?.onFavoriteChange(favorite)
42 | }
43 | }
44 | binding.switchBtn.setOnCheckedChangeListener {
45 | button, check ->
46 | if (button.isPressed) {
47 | binding.viewModel?.onCheckChange(check)
48 | }
49 | }
50 | binding.switchBtn.isChecked = appInfo.hidden
51 | binding.viewModel = AppViewModel(itemView.context, appInfo)
52 | }
53 | }
54 |
55 | }
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/adapter/BindingAdapter.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide.adapter
2 |
3 | import android.databinding.BindingAdapter
4 | import android.graphics.drawable.Drawable
5 | import android.widget.ImageView
6 | import android.widget.Switch
7 | import com.github.ivbaranov.mfb.MaterialFavoriteButton
8 |
9 | @BindingAdapter("drawable")
10 | fun setImageSrc(imageView: ImageView, drawable: Drawable) {
11 | imageView.setImageDrawable(drawable)
12 | }
13 |
14 | @BindingAdapter("favorite")
15 | fun setFavorite(materialFavoriteButton: MaterialFavoriteButton, favorite: Boolean) {
16 | materialFavoriteButton.setFavorite(favorite, false)
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/config/Settings.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide.config
2 |
3 | object Settings {
4 | val SPINNER_STAR_APP = 0
5 | val SPINNER_HIDDEN_APP = 1
6 | val SPINNER_ALL_APP = 2
7 |
8 | val KEY_PREF_LAUNCH_PASSWORD = "me.sweetll.evilhide.launch.password"
9 | val KEY_PREF_INVISIBLE = "me.sweetll.evilhide.invisible"
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/config/SharedPreferenceConfig.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide.config
2 |
3 | import android.content.Context
4 | import android.content.SharedPreferences
5 | import me.sweetll.evilhide.AppApplication
6 |
7 | object SharedPreferenceConfig {
8 | val FILE_NAME = "me.sweetll.evilhide_app"
9 |
10 | val PREFIX_PREF_KEY_B_FAVORITE = "favorite_"
11 | val PREFIX_PREF_KEY_B_HIDDEN = "hidden_"
12 | val PREFIX_PREF_KEY_S_PASSWORD = "password_"
13 |
14 | val sp: SharedPreferences by lazy {
15 | AppApplication.get()
16 | .getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/extension/SharedPreferenceExtensions.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide.extension
2 |
3 | import android.content.SharedPreferences
4 |
5 | fun SharedPreferences.edit(func: SharedPreferences.Editor.() -> Unit) {
6 | val editor = edit()
7 | editor.func()
8 | editor.apply()
9 | }
10 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/extension/StringExtensions.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide.extension
2 |
3 | import me.sweetll.evilhide.config.SharedPreferenceConfig.PREFIX_PREF_KEY_B_FAVORITE
4 | import me.sweetll.evilhide.config.SharedPreferenceConfig.PREFIX_PREF_KEY_B_HIDDEN
5 | import me.sweetll.evilhide.config.SharedPreferenceConfig.PREFIX_PREF_KEY_S_PASSWORD
6 | import me.sweetll.evilhide.config.SharedPreferenceConfig.sp
7 |
8 | fun String.getFavorite(): Boolean = sp.getBoolean("$PREFIX_PREF_KEY_B_FAVORITE$this", false)
9 | fun String.saveFavorite(favorite: Boolean) {
10 | sp.edit {
11 | putBoolean("$PREFIX_PREF_KEY_B_FAVORITE${this@saveFavorite}", favorite)
12 | }
13 | }
14 |
15 | fun String.getHidden(): Boolean = sp.getBoolean("$PREFIX_PREF_KEY_B_HIDDEN$this", false)
16 | fun String.saveHidden(hidden: Boolean) {
17 | sp.edit {
18 | putBoolean("$PREFIX_PREF_KEY_B_HIDDEN${this@saveHidden}", hidden)
19 | }
20 | }
21 |
22 | fun String.getPassword(): String = sp.getString("$PREFIX_PREF_KEY_S_PASSWORD$this", "")
23 | fun String.savePassword(password: String) {
24 | sp.edit {
25 | putString("$PREFIX_PREF_KEY_S_PASSWORD${this@savePassword}", password)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/fragment/SettingFragment.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide.fragment
2 |
3 | import android.content.ComponentName
4 | import android.content.SharedPreferences
5 | import android.content.pm.PackageManager
6 | import android.os.Bundle
7 | import android.os.Handler
8 | import android.preference.PreferenceFragment
9 | import android.widget.Toast
10 | import me.sweetll.evilhide.AppApplication
11 | import me.sweetll.evilhide.MainActivity
12 | import me.sweetll.evilhide.ProxyActivity
13 |
14 | import me.sweetll.evilhide.R
15 | import me.sweetll.evilhide.config.Settings
16 |
17 | class SettingFragment : PreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener {
18 | val handler = Handler()
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 | addPreferencesFromResource(R.xml.settings)
23 | }
24 |
25 | override fun onResume() {
26 | super.onResume()
27 | preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
28 | }
29 |
30 | override fun onPause() {
31 | super.onPause()
32 | preferenceScreen.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
33 | }
34 |
35 | override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
36 | if (key == Settings.KEY_PREF_INVISIBLE) {
37 | val selfInvisible = sharedPreferences.getBoolean(key, false)
38 | val p = activity.packageManager
39 | val componentName = ComponentName(activity, ProxyActivity::class.java)
40 | when (selfInvisible) {
41 | true -> {
42 | Toast.makeText(AppApplication.get(), "程序将在3s后退出,退出后请从拨号盘进入", Toast.LENGTH_LONG).show()
43 | handler.postDelayed({
44 | p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0)
45 | }, 3000)
46 | }
47 | false -> p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/model/AppInfo.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide.model
2 |
3 |
4 | import android.content.pm.ApplicationInfo
5 | import me.sweetll.evilhide.AppApplication
6 | import me.sweetll.evilhide.extension.*
7 | import me.sweetll.evilhide.service.HiddenService
8 |
9 | class AppInfo(val applicationInfo: ApplicationInfo) {
10 | val packageName: String
11 | get() = applicationInfo.packageName
12 |
13 | var favorite: Boolean
14 | get() = packageName.getFavorite()
15 | set(value) {
16 | packageName.saveFavorite(value)
17 | }
18 | var hidden: Boolean
19 | get() = !applicationInfo.enabled
20 | set(value) {
21 | val cmd = "pm ${if (value) "disable" else "enable"} $packageName"
22 | HiddenService.performAction(cmd)
23 | applicationInfo.enabled = !applicationInfo.enabled
24 | }
25 | var password: String
26 | get() = packageName.getPassword()
27 | set(value) {
28 | packageName.savePassword(value)
29 | }
30 | }
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/receiver/CallReceiver.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide.receiver
2 |
3 | import android.content.BroadcastReceiver
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.preference.PreferenceManager
7 |
8 | import me.sweetll.evilhide.MainActivity
9 | import me.sweetll.evilhide.config.Settings
10 | import me.sweetll.evilhide.ProxyActivity
11 |
12 | class CallReceiver : BroadcastReceiver() {
13 | override fun onReceive(context: Context, intent: Intent) {
14 | var phoneNumber: String? = resultData
15 | val preferences = PreferenceManager.getDefaultSharedPreferences(context)
16 | val launchPassword = preferences.getString(Settings.KEY_PREF_LAUNCH_PASSWORD, "#1234")
17 | if (phoneNumber == null) {
18 | phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER)
19 | }
20 |
21 | if (phoneNumber == launchPassword) {
22 | val i = Intent()
23 | i.setClassName("me.sweetll.evilhide", "me.sweetll.evilhide.MainActivity")
24 | i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
25 | context.startActivity(i)
26 | resultData = null
27 | } else {
28 | //查询preference
29 | }
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/service/HiddenService.kt:
--------------------------------------------------------------------------------
1 |
2 | package me.sweetll.evilhide.service
3 |
4 | import android.app.IntentService
5 | import android.content.Intent
6 | import android.util.Log
7 |
8 | import eu.chainfire.libsuperuser.Shell
9 | import me.sweetll.evilhide.AppApplication
10 |
11 | class HiddenService : IntentService("hidden-service") {
12 |
13 | override fun onCreate() {
14 | super.onCreate()
15 | }
16 |
17 | override fun onHandleIntent(intent: Intent?) {
18 | intent?.let {
19 | val action = it.action
20 | if (!action.isNullOrEmpty()) {
21 | Log.d("evil", "action = $action")
22 | Shell.SU.run(action)
23 | }
24 | }
25 | }
26 |
27 | companion object {
28 | fun performAction(action: String) {
29 | val svc = Intent(AppApplication.get(), HiddenService::class.java)
30 | svc.action = action
31 | AppApplication.get().startService(svc)
32 | }
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/kotlin/me/sweetll/evilhide/viewmodel/AppViewModel.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide.viewmodel
2 |
3 | import android.content.Context
4 | import android.databinding.ObservableBoolean
5 | import android.databinding.ObservableField
6 | import android.graphics.drawable.Drawable
7 | import android.support.v7.app.AlertDialog
8 | import android.view.View
9 | import android.widget.EditText
10 | import me.sweetll.evilhide.model.AppInfo
11 | import me.sweetll.evilhide.service.HiddenService
12 |
13 | class AppViewModel(val context: Context, val appInfo: AppInfo) {
14 | val appName: ObservableField = ObservableField()
15 | val appIcon: ObservableField = ObservableField()
16 | val isStar: ObservableBoolean = ObservableBoolean()
17 | val isHidden: ObservableBoolean = ObservableBoolean()
18 |
19 | init {
20 | val pm = context.packageManager
21 | appName.set(pm.getApplicationLabel(appInfo.applicationInfo).toString())
22 | appIcon.set(pm.getApplicationIcon(appInfo.applicationInfo))
23 | isStar.set(appInfo.favorite)
24 | isHidden.set(appInfo.hidden)
25 | }
26 |
27 | @Suppress("UNUSED_PARAMETER")
28 | fun onClickApp(view: View) {
29 | val intent = context.packageManager.getLaunchIntentForPackage(appInfo.packageName)
30 | intent?.let { context.startActivity(it) }
31 | }
32 |
33 | @Suppress("UNUSED_PARAMETER")
34 | fun onClickAdd(view: View) {
35 | val passwordEdit = EditText(context)
36 | passwordEdit.setText(appInfo.password)
37 | AlertDialog.Builder(context)
38 | .setTitle("请输入启动该应用的密码")
39 | .setView(passwordEdit)
40 | .setNegativeButton("取消", null)
41 | .setPositiveButton("确定", {
42 | dialog, which ->
43 | appInfo.password = passwordEdit.text.toString()
44 | })
45 | }
46 |
47 | fun onFavoriteChange(favorite: Boolean) {
48 | appInfo.favorite = favorite
49 | isStar.set(favorite)
50 | }
51 |
52 | fun onCheckChange(hidden: Boolean) {
53 | appInfo.hidden = hidden
54 | isHidden.set(hidden)
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_settings.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
20 |
25 |
26 |
27 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_app.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
10 |
11 |
12 |
17 |
18 |
24 |
25 |
38 |
39 |
50 |
51 |
61 |
62 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackbbc/Evil-Hide/2ae183c5a763099a0401c4c6a176879bd1142ccc/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackbbc/Evil-Hide/2ae183c5a763099a0401c4c6a176879bd1142ccc/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackbbc/Evil-Hide/2ae183c5a763099a0401c4c6a176879bd1142ccc/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackbbc/Evil-Hide/2ae183c5a763099a0401c4c6a176879bd1142ccc/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackbbc/Evil-Hide/2ae183c5a763099a0401c4c6a176879bd1142ccc/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Evil Hide
3 |
4 | 设置
5 |
6 | 隐藏
7 |
8 | 设置
9 | 其他
10 | 启动密码
11 | 是否隐藏此App
12 | 关于
13 |
14 |
15 | - 常用应用
16 | - 被隐藏应用
17 | - 所有应用
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/app/src/test/java/me/sweetll/evilhide/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package me.sweetll.evilhide
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | class ExampleUnitTest {
11 | @Test
12 | @Throws(Exception::class)
13 | fun addition_isCorrect() {
14 | assertEquals(4, (2 + 2).toLong())
15 | }
16 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.1.4-2'
5 | ext.plugin_version = '3.0.0-beta4'
6 |
7 | repositories {
8 | jcenter()
9 | maven { url "https://dl.google.com/dl/android/maven2/"}
10 | }
11 | dependencies {
12 | classpath "com.android.tools.build:gradle:$plugin_version"
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14 |
15 | // NOTE: Do not place your application dependencies here; they belong
16 | // in the individual module build.gradle files
17 | }
18 | }
19 |
20 | allprojects {
21 | repositories {
22 | jcenter()
23 | maven { url "https://jitpack.io" }
24 | maven { url "https://dl.google.com/dl/android/maven2/"}
25 | }
26 | }
27 |
28 | task clean(type: Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackbbc/Evil-Hide/2ae183c5a763099a0401c4c6a176879bd1142ccc/demo.gif
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackbbc/Evil-Hide/2ae183c5a763099a0401c4c6a176879bd1142ccc/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Aug 28 14:46:41 CST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------