├── .gitignore ├── .idea ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── gradle.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ └── com.alcatraz.support.v4.appcompat.jar ├── proguard-rules.pro ├── release │ ├── app-release.apk │ └── output.json └── src │ ├── androidTest │ └── java │ │ └── io │ │ └── alcatraz │ │ └── afkprotect │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-playstore.png │ ├── java │ │ └── io │ │ │ └── alcatraz │ │ │ └── afkprotect │ │ │ ├── AsyncInterface.kt │ │ │ ├── Constants.kt │ │ │ ├── Easter.kt │ │ │ ├── FaceSaverApplication.kt │ │ │ ├── LogBuff.kt │ │ │ ├── activities │ │ │ ├── AboutActivity.kt │ │ │ ├── AppPickActivity.kt │ │ │ ├── HistoryActivity.kt │ │ │ ├── LogActivity.kt │ │ │ ├── MainActivity.kt │ │ │ ├── PreferenceActivity.kt │ │ │ ├── PreferenceInnerActivity.kt │ │ │ ├── ProfileConfigureActivity.kt │ │ │ ├── ProfileGeneralActivity.kt │ │ │ ├── RecordActivity.kt │ │ │ └── SetupActivity.kt │ │ │ ├── adapters │ │ │ ├── AuthorAdapter.kt │ │ │ ├── HistoryAdapter.kt │ │ │ ├── PackageAdapter.kt │ │ │ ├── PreferenceListAdapter.kt │ │ │ ├── ProfileAdapter.kt │ │ │ ├── QueryElementAdapter.kt │ │ │ └── SetupPagerAdapter.kt │ │ │ ├── beans │ │ │ ├── AuthorElement.kt │ │ │ ├── LambdaBridge.kt │ │ │ ├── PreferenceHeader.kt │ │ │ ├── ProfileParamCheckResult.kt │ │ │ ├── QueryElement.kt │ │ │ └── SetupPage.kt │ │ │ ├── core │ │ │ ├── AccessibilityEventTaskManager.kt │ │ │ ├── ApplicationProfile.kt │ │ │ ├── DeviceMgrApi.kt │ │ │ ├── History.kt │ │ │ ├── Profiles.kt │ │ │ ├── Record.kt │ │ │ └── Rectifier.kt │ │ │ ├── extended │ │ │ ├── CompatWithPipeActivity.kt │ │ │ ├── NoScrollExpandableListView.kt │ │ │ ├── NoScrollListView.kt │ │ │ ├── NoScrollViewPager.kt │ │ │ ├── RoundImageView.kt │ │ │ └── SetupWizardBaseActivity.kt │ │ │ ├── fragments │ │ │ └── TriggerPreferenceFragment.kt │ │ │ ├── receivers │ │ │ └── LockScreenAdmin.kt │ │ │ ├── services │ │ │ └── ProtectorService.kt │ │ │ └── utils │ │ │ ├── AnimateUtils.kt │ │ │ ├── DebugUtils.kt │ │ │ ├── IOUtils.kt │ │ │ ├── PackageCtlUtils.kt │ │ │ ├── Panels.kt │ │ │ ├── PermissionInterface.kt │ │ │ ├── ReportUtils.kt │ │ │ ├── SharedPreferenceUtil.kt │ │ │ ├── UpdateUtils.kt │ │ │ └── Utils.kt │ └── res │ │ ├── anim │ │ ├── layout_fall_down.xml │ │ ├── recycler_falldown.xml │ │ ├── slide_left.xml │ │ ├── slide_left_back.xml │ │ ├── slide_right.xml │ │ └── slide_right_back.xml │ │ ├── animator │ │ └── raise.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── card_boarder.xml │ │ ├── common_setup_wizard_illustration_generic_wide.jpg │ │ ├── common_setup_wizard_illustration_tile.jpg │ │ ├── ic_access_time_black_24dp.xml │ │ ├── ic_account_circle_black_24dp.xml │ │ ├── ic_add_black_24dp.xml │ │ ├── ic_add_white_24dp.xml │ │ ├── ic_alert.xml │ │ ├── ic_apps_black_24dp.xml │ │ ├── ic_attach_money_black_24dp.xml │ │ ├── ic_backspace_black_24dp.xml │ │ ├── ic_branding_watermark_gray_24dp.xml │ │ ├── ic_check_black_24dp.xml │ │ ├── ic_check_circle_black_24dp.xml │ │ ├── ic_check_green_24dp.xml │ │ ├── ic_check_white_24dp.xml │ │ ├── ic_chevron_left_black_24dp.xml │ │ ├── ic_chevron_right_black_24dp.xml │ │ ├── ic_close.xml │ │ ├── ic_close_red_24dp.xml │ │ ├── ic_code_black_24dp.xml │ │ ├── ic_cog.xml │ │ ├── ic_delete_black_24dp.xml │ │ ├── ic_delete_white_24dp.xml │ │ ├── ic_developer_mode_black_24dp.xml │ │ ├── ic_edit_black_24dp.xml │ │ ├── ic_exit_to_app_black_24dp.xml │ │ ├── ic_filter_list_black_24dp.xml │ │ ├── ic_help_outline_black_24dp.xml │ │ ├── ic_history_black_24dp.xml │ │ ├── ic_info_outline_black_24dp.xml │ │ ├── ic_keyboard_arrow_down_black_24dp.xml │ │ ├── ic_keyboard_arrow_up_black_24dp.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_launcher_foreground.xml │ │ ├── ic_lock_outline_black_24dp.xml │ │ ├── ic_multiline_chart_black_24dp.xml │ │ ├── ic_notifications_black_24dp.xml │ │ ├── ic_open_in_new_black_24dp.xml │ │ ├── ic_pause_black_24dp.xml │ │ ├── ic_perm_identity_black_24dp.xml │ │ ├── ic_play_circle_filled_black_24dp.xml │ │ ├── ic_playlist_play_black_24dp.xml │ │ ├── ic_refresh_black_24dp.xml │ │ ├── ic_refresh_white_24dp.xml │ │ ├── ic_settings_black_24dp.xml │ │ ├── ic_timelapse_black_24dp.xml │ │ ├── ic_tune_black_24dp.xml │ │ ├── ic_videocam_off_black_24dp.xml │ │ ├── ic_volume_off_black_24dp.xml │ │ ├── ic_volume_source.xml │ │ └── wechat_qr.jpg │ │ ├── layout-v21 │ │ └── activity_setup_nav.xml │ │ ├── layout │ │ ├── activity_about.xml │ │ ├── activity_history.xml │ │ ├── activity_log.xml │ │ ├── activity_main.xml │ │ ├── activity_preference.xml │ │ ├── activity_preference_inner.xml │ │ ├── activity_profile_configure.xml │ │ ├── activity_profile_general.xml │ │ ├── activity_profile_pick_app.xml │ │ ├── activity_record.xml │ │ ├── activity_setup.xml │ │ ├── activity_setup_nav.xml │ │ ├── dialog_ops.xml │ │ ├── dialog_processing.xml │ │ ├── dialog_qr.xml │ │ ├── float_toggle.xml │ │ ├── item_app_pick.xml │ │ ├── item_author_main_list.xml │ │ ├── item_history.xml │ │ ├── item_opensource_holder.xml │ │ ├── item_preference_header.xml │ │ ├── item_profile.xml │ │ ├── panel_empty_view.xml │ │ ├── setup_1.xml │ │ ├── setup_2.xml │ │ └── setup_3.xml │ │ ├── menu │ │ ├── activity_log_menu.xml │ │ ├── activity_main_menu.xml │ │ ├── activity_pick_app_menu.xml │ │ ├── activity_profile_configure_menu.xml │ │ └── activity_profile_general_menu.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── values-zh-rCN │ │ ├── arrays.xml │ │ └── strings.xml │ │ ├── values │ │ ├── arrays.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── accessibility_protect_main.xml │ │ ├── lockscreen_admin.xml │ │ └── preference_trigger.xml │ └── test │ └── java │ └── io │ └── alcatraz │ └── afkprotect │ └── ExampleUnitTest.kt ├── build.gradle ├── 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/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | xmlns:android 17 | 18 | ^$ 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 | 27 | xmlns:.* 28 | 29 | ^$ 30 | 31 | 32 | BY_NAME 33 | 34 |
35 |
36 | 37 | 38 | 39 | .*:id 40 | 41 | http://schemas.android.com/apk/res/android 42 | 43 | 44 | 45 |
46 |
47 | 48 | 49 | 50 | .*:name 51 | 52 | http://schemas.android.com/apk/res/android 53 | 54 | 55 | 56 |
57 |
58 | 59 | 60 | 61 | name 62 | 63 | ^$ 64 | 65 | 66 | 67 |
68 |
69 | 70 | 71 | 72 | style 73 | 74 | ^$ 75 | 76 | 77 | 78 |
79 |
80 | 81 | 82 | 83 | .* 84 | 85 | ^$ 86 | 87 | 88 | BY_NAME 89 | 90 |
91 |
92 | 93 | 94 | 95 | .* 96 | 97 | http://schemas.android.com/apk/res/android 98 | 99 | 100 | ANDROID_ATTRIBUTE_ORDER 101 | 102 |
103 |
104 | 105 | 106 | 107 | .* 108 | 109 | .* 110 | 111 | 112 | BY_NAME 113 | 114 |
115 |
116 |
117 |
118 | 119 | 121 |
122 |
-------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # afkprotect 2 | You may leave your phone playing vedio or sth else after you fall asleep, this is a progame to force pause player and lockscreen after a long period afk 3 | 4 | published on GooglePlay And Coolapk -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | apply plugin: 'kotlin-android' 4 | 5 | apply plugin: 'kotlin-android-extensions' 6 | 7 | android { 8 | compileSdkVersion 28 9 | defaultConfig { 10 | applicationId "io.alcatraz.afkprotect" 11 | minSdkVersion 21 12 | targetSdkVersion 28 13 | versionCode 1 14 | versionName "0.5_2020_4_30" 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | viewBinding { 24 | enabled true 25 | } 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: 'libs', include: ['*.jar']) 30 | implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 31 | implementation 'com.google.code.gson:gson:2.8.5' 32 | implementation 'androidx.appcompat:appcompat:1.1.0' 33 | implementation 'androidx.preference:preference:1.1.1' 34 | implementation 'androidx.fragment:fragment:1.2.4' 35 | implementation 'androidx.cardview:cardview:1.0.0' 36 | implementation 'com.google.android.material:material:1.1.0' 37 | implementation 'androidx.core:core-ktx:1.2.0' 38 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 39 | testImplementation 'junit:junit:4.12' 40 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 41 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 42 | implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' 43 | } 44 | -------------------------------------------------------------------------------- /app/libs/com.alcatraz.support.v4.appcompat.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alcatraz323/afkprotect/fe9bda1c69328abd180cebe58ec84c93dd16130b/app/libs/com.alcatraz.support.v4.appcompat.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/release/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alcatraz323/afkprotect/fe9bda1c69328abd180cebe58ec84c93dd16130b/app/release/app-release.apk -------------------------------------------------------------------------------- /app/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"0.5_2020_4_30","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release","dirName":""},"path":"app-release.apk","properties":{}}] -------------------------------------------------------------------------------- /app/src/androidTest/java/io/alcatraz/afkprotect/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect 2 | 3 | import androidx.test.platform.app.InstrumentationRegistry 4 | import androidx.test.ext.junit.runners.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext 22 | assertEquals("io.alcatraz.afkprotect", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | 46 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-playstore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alcatraz323/afkprotect/fe9bda1c69328abd180cebe58ec84c93dd16130b/app/src/main/ic_launcher-playstore.png -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/AsyncInterface.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect 2 | 3 | interface AsyncInterface { 4 | fun onDone(result: T) 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/Constants.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect 2 | 3 | import io.alcatraz.afkprotect.beans.QueryElement 4 | 5 | object Constants { 6 | const val DATA_HISTORY_VERSION = 1 7 | const val DATA_PROFILE_VERSION = 1 8 | 9 | const val BUILD_DONATE = true 10 | 11 | const val MY_PACKAGE_NAME = "io.alcatraz.afkprotect" 12 | const val MY_PROJECT_CODE = "afkprotect" 13 | const val MY_GITHUB = "https://github.com/Alcatraz323/" 14 | const val MY_GITHUB_PAGE = "https://alcatraz323.github.io/" 15 | const val OPEN_SOURCE_URL = MY_GITHUB + MY_PROJECT_CODE 16 | const val SUPPORT_URL = MY_GITHUB_PAGE + MY_PROJECT_CODE 17 | const val EASTER_URL = "$MY_GITHUB_PAGE$MY_PROJECT_CODE/easter" 18 | 19 | //=============================================== 20 | 21 | const val PREF_TRIGGER_IGNORE_PACKAGE = "ignore_trigger_package" 22 | 23 | //=============================================== 24 | 25 | const val BROADCAST_ACTION_UPDATE_PREFERENCES = "update_preferences" 26 | 27 | //gson 28 | val openSourceProjects: List 29 | get() { 30 | return listOf( 31 | QueryElement( 32 | "google", 33 | "gson", 34 | "https://github.com/google/gson", 35 | "Apache 2.0", 36 | "A Java serialization/deserialization library to convert Java Objects into JSON and back" 37 | ) 38 | ) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/Easter.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.net.Uri 6 | 7 | class Easter(private val context: Context) { 8 | private val target = intArrayOf(0, 1, 0, 1, 0, 0, 1, 0, 1, 0) 9 | private var current = 0 10 | 11 | fun shortClick() { 12 | val expect = target[current] 13 | if (expect == 0) { 14 | if (current == target.size - 1) { 15 | showEaster() 16 | clearCounter() 17 | } else { 18 | current++ 19 | } 20 | } else { 21 | clearCounter() 22 | } 23 | } 24 | 25 | fun longClick() { 26 | val expect = target[current] 27 | if (expect == 1) { 28 | if (current == target.size - 1) { 29 | showEaster() 30 | clearCounter() 31 | } else { 32 | current++ 33 | } 34 | } else { 35 | clearCounter() 36 | } 37 | } 38 | 39 | private fun showEaster() { 40 | context.startActivity( 41 | Intent( 42 | Intent.ACTION_VIEW, 43 | Uri.parse(Constants.EASTER_URL) 44 | ) 45 | ) 46 | } 47 | 48 | private fun clearCounter() { 49 | current = 0 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/FaceSaverApplication.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect 2 | 3 | import android.app.Application 4 | import android.content.Context 5 | import io.alcatraz.afkprotect.core.AccessibilityEventTaskManager 6 | import java.util.concurrent.atomic.AtomicReference 7 | 8 | class FaceSaverApplication : Application() { 9 | lateinit var overallContext: Context 10 | lateinit var aEventTaskMgr: AtomicReference 11 | //TODO : Check string.xml/Setup versionCode/build.gradle when release update 12 | //TODO : Set Empty View for all adapter views 13 | override fun onCreate() { 14 | overallContext = applicationContext 15 | aEventTaskMgr = AtomicReference(AccessibilityEventTaskManager(applicationContext)) 16 | super.onCreate() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/LogBuff.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect 2 | 3 | import android.annotation.SuppressLint 4 | import android.text.Html 5 | 6 | import java.text.SimpleDateFormat 7 | import java.util.Date 8 | 9 | object LogBuff { 10 | var MESSAGE_DEFAULT_MAX_AMOUNT = 256 11 | 12 | var COLOR_LEVEL_INFO = "#4caf50" 13 | var COLOR_LEVEL_WARN = "#ff9800" 14 | var COLOR_LEVEL_ERROR = "#f44336" 15 | var COLOR_LEVEL_DEBUG = "#1565C0" 16 | var HTML_BRLINE = "
" 17 | 18 | var accessibilityStatus = false 19 | 20 | private var whole_message = "" 21 | private var num = 0 22 | 23 | private val time: String 24 | get() { 25 | val currentTime = System.currentTimeMillis() 26 | @SuppressLint("SimpleDateFormat") val formatter = SimpleDateFormat("MM-dd HH:mm:ss") 27 | val date = Date(currentTime) 28 | return formatter.format(date) 29 | } 30 | 31 | val finalLog: CharSequence 32 | get() = Html.fromHtml(whole_message) 33 | 34 | fun I(infoMsg: String) { 35 | val className = Exception().stackTrace[1].className.replace(Constants.MY_PACKAGE_NAME, "") 36 | val methodName = Exception().stackTrace[1].methodName 37 | commitMessageChange( 38 | wrapFontString( 39 | time + " [INFO][" + className + "::" + methodName + "]" + 40 | infoMsg, COLOR_LEVEL_INFO 41 | ) 42 | ) 43 | } 44 | 45 | fun W(warnMsg: String) { 46 | val className = Exception().stackTrace[1].className.replace(Constants.MY_PACKAGE_NAME, "") 47 | val methodName = Exception().stackTrace[1].methodName 48 | commitMessageChange( 49 | wrapFontString( 50 | time + " [WARNING][" + className + "::" + methodName + "]" + 51 | warnMsg, COLOR_LEVEL_WARN 52 | ) 53 | ) 54 | } 55 | 56 | fun E(errMsg: String) { 57 | val className = Exception().stackTrace[1].className.replace(Constants.MY_PACKAGE_NAME, "") 58 | val methodName = Exception().stackTrace[1].methodName 59 | commitMessageChange( 60 | wrapFontString( 61 | time + " [ERROR][" + className + "::" + methodName + "]" + 62 | errMsg, COLOR_LEVEL_ERROR 63 | ) 64 | ) 65 | } 66 | 67 | fun D(dbgMsg: String) { 68 | val className = Exception().stackTrace[1].className.replace(Constants.MY_PACKAGE_NAME, "") 69 | val methodName = Exception().stackTrace[1].methodName 70 | commitMessageChange( 71 | wrapFontString( 72 | time + " [DEBUG][" + className + "::" + methodName + "]" + 73 | dbgMsg, COLOR_LEVEL_DEBUG 74 | ) 75 | ) 76 | } 77 | 78 | @JvmOverloads 79 | fun wrapFontString( 80 | raw: String, 81 | rgb_color: String, 82 | isBold: Boolean = false, 83 | isItalic: Boolean = false 84 | ): String { 85 | var rawVar = raw 86 | if (isBold) { 87 | rawVar = "$rawVar" 88 | } 89 | if (isItalic) { 90 | rawVar = "$rawVar" 91 | } 92 | 93 | return "$rawVar" 94 | } 95 | 96 | fun log(content: String) { 97 | commitMessageChange(content) 98 | } 99 | 100 | fun addDivider() { 101 | whole_message += "
============================" 102 | } 103 | 104 | fun clearLog() { 105 | whole_message = "" 106 | num = 0 107 | W("Cleared operation log") 108 | } 109 | 110 | private fun checkAndClearup() { 111 | if (num >= MESSAGE_DEFAULT_MAX_AMOUNT) { 112 | whole_message = "" 113 | num = 0 114 | W("Automatically cleared log ( reaching max :$MESSAGE_DEFAULT_MAX_AMOUNT)") 115 | } 116 | } 117 | 118 | private fun commitMessageChange(content: String) { 119 | checkAndClearup() 120 | whole_message += HTML_BRLINE + content 121 | num++ 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/activities/AppPickActivity.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.activities 2 | 3 | import android.content.pm.PackageInfo 4 | import android.graphics.Color 5 | import android.os.Bundle 6 | import android.view.* 7 | import android.view.animation.AnimationUtils 8 | import android.view.animation.LayoutAnimationController 9 | import android.widget.ProgressBar 10 | import androidx.appcompat.widget.SearchView 11 | import androidx.recyclerview.widget.LinearLayoutManager 12 | import com.alcatraz.support.v4.appcompat.StatusBarUtil 13 | import io.alcatraz.afkprotect.Constants 14 | import io.alcatraz.afkprotect.R 15 | import io.alcatraz.afkprotect.adapters.PackageAdapter 16 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 17 | import io.alcatraz.afkprotect.utils.Utils 18 | import kotlinx.android.synthetic.main.activity_profile_pick_app.* 19 | 20 | 21 | class AppPickActivity : CompatWithPipeActivity() { 22 | private val apps: MutableList = mutableListOf() 23 | private lateinit var adapter: PackageAdapter 24 | private lateinit var progressBar: ProgressBar 25 | 26 | private var loadForIgnorePackPick = false 27 | 28 | override fun onCreate(savedInstanceState: Bundle?) { 29 | super.onCreate(savedInstanceState) 30 | setContentView(R.layout.activity_profile_pick_app) 31 | initialize() 32 | } 33 | 34 | private fun initialize() { 35 | loadStarter() 36 | adapter = PackageAdapter(this, apps,loadForIgnorePackPick, getAEventTaskMgr()) 37 | initViews() 38 | pick_app_toolbar.post { 39 | initData() 40 | } 41 | } 42 | 43 | private fun initViews() { 44 | setSupportActionBar(pick_app_toolbar) 45 | supportActionBar!!.setHomeButtonEnabled(true) 46 | supportActionBar!!.setDisplayHomeAsUpEnabled(true) 47 | pick_app_recycler.layoutManager = LinearLayoutManager(this) 48 | val controller: LayoutAnimationController = 49 | AnimationUtils.loadLayoutAnimation(this, R.anim.layout_fall_down) 50 | pick_app_recycler.layoutAnimation = controller 51 | pick_app_recycler.adapter = adapter 52 | StatusBarUtil.setColor(this, Color.parseColor("#212121"), 0) 53 | } 54 | 55 | private fun initData() { 56 | showProcessing() 57 | apps.clear() 58 | Thread(Runnable { 59 | val data = packageManager.getInstalledPackages(0) 60 | for ((index, i) in data.withIndex()) { 61 | if (i.packageName == Constants.MY_PACKAGE_NAME) { 62 | data.removeAt(index) 63 | break 64 | } 65 | } 66 | apps.addAll(data) 67 | runOnUiThread { 68 | adapter.notifyDataSetChanged() 69 | pick_app_recycler.scheduleLayoutAnimation() 70 | hideProcessing() 71 | } 72 | }).start() 73 | } 74 | 75 | private fun loadStarter() { 76 | if (intent.action == ACTION_PICK_IGNORE_PACKAGE) { 77 | loadForIgnorePackPick = true 78 | } 79 | } 80 | 81 | override fun onCreateOptionsMenu(menu: Menu?): Boolean { 82 | val menuInflater = MenuInflater(this) 83 | menuInflater.inflate(R.menu.activity_pick_app_menu, menu) 84 | 85 | val searchView = menu!!.findItem(R.id.action_search).actionView as SearchView 86 | searchView.queryHint = getString(R.string.profile_search_hint) 87 | val underline: View = searchView.findViewById(R.id.search_plate) 88 | underline.setBackgroundColor(Color.TRANSPARENT) 89 | 90 | progressBar = menu.findItem(R.id.action_progress_bar).actionView as ProgressBar 91 | val dp24: Int = Utils.dp2Px(this, 24f) 92 | val params = ViewGroup.LayoutParams(dp24, dp24) 93 | progressBar.layoutParams = params 94 | 95 | searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener { 96 | override fun onQueryTextSubmit(s: String?): Boolean { 97 | return false 98 | } 99 | 100 | override fun onQueryTextChange(s: String?): Boolean { 101 | if (Utils.isStringNotEmpty(s)) { 102 | adapter.onTextChanged(s) 103 | } else { 104 | adapter.onTextChanged("") 105 | } 106 | return false 107 | } 108 | }) 109 | return super.onCreateOptionsMenu(menu) 110 | } 111 | 112 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 113 | when (item.itemId) { 114 | android.R.id.home -> finish() 115 | } 116 | return super.onOptionsItemSelected(item) 117 | } 118 | 119 | private fun showProcessing() { 120 | progressBar.post { progressBar.visibility = View.VISIBLE } 121 | } 122 | 123 | private fun hideProcessing() { 124 | progressBar.post { progressBar.visibility = View.GONE } 125 | } 126 | 127 | companion object { 128 | const val ACTION_PICK_IGNORE_PACKAGE = 129 | Constants.MY_PROJECT_CODE + "_key_pick_ignore_package" 130 | } 131 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/activities/HistoryActivity.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.activities 2 | 3 | import android.graphics.Color 4 | import android.os.Bundle 5 | import android.view.MenuItem 6 | import android.view.animation.AnimationUtils 7 | import android.view.animation.LayoutAnimationController 8 | import androidx.recyclerview.widget.LinearLayoutManager 9 | import com.alcatraz.support.v4.appcompat.StatusBarUtil 10 | import io.alcatraz.afkprotect.R 11 | import io.alcatraz.afkprotect.adapters.HistoryAdapter 12 | import io.alcatraz.afkprotect.core.Record 13 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 14 | import kotlinx.android.synthetic.main.activity_history.* 15 | 16 | 17 | class HistoryActivity : CompatWithPipeActivity() { 18 | private val history: MutableList = mutableListOf() 19 | private lateinit var adapter: HistoryAdapter 20 | 21 | override fun onCreate(savedInstanceState: Bundle?) { 22 | super.onCreate(savedInstanceState) 23 | setContentView(R.layout.activity_history) 24 | initialize() 25 | } 26 | 27 | private fun initialize() { 28 | adapter = HistoryAdapter(this, history) 29 | initViews() 30 | initData() 31 | } 32 | 33 | private fun initViews() { 34 | setSupportActionBar(history_toolbar) 35 | supportActionBar!!.setHomeButtonEnabled(true) 36 | supportActionBar!!.setDisplayHomeAsUpEnabled(true) 37 | history_recycler.layoutManager = LinearLayoutManager(this) 38 | val controller: LayoutAnimationController = 39 | AnimationUtils.loadLayoutAnimation(this, R.anim.layout_fall_down) 40 | history_recycler.layoutAnimation = controller 41 | history_recycler.adapter = adapter 42 | StatusBarUtil.setColor(this, Color.parseColor("#212121"),0) 43 | } 44 | 45 | private fun initData() { 46 | history.clear() 47 | val data = getAEventTaskMgr().records 48 | history.addAll(data) 49 | adapter.notifyDataSetChanged() 50 | history_recycler.scheduleLayoutAnimation() 51 | } 52 | 53 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 54 | when (item.itemId) { 55 | android.R.id.home -> finish() 56 | } 57 | return super.onOptionsItemSelected(item) 58 | } 59 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/activities/LogActivity.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.activities 2 | 3 | import android.os.Bundle 4 | import android.view.Menu 5 | import android.view.MenuInflater 6 | import android.view.MenuItem 7 | 8 | import io.alcatraz.afkprotect.LogBuff 9 | import io.alcatraz.afkprotect.R 10 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 11 | import kotlinx.android.synthetic.main.activity_log.* 12 | 13 | class LogActivity : CompatWithPipeActivity() { 14 | 15 | override fun onCreate(savedInstanceState: Bundle?) { 16 | super.onCreate(savedInstanceState) 17 | setContentView(R.layout.activity_log) 18 | initViews() 19 | initData() 20 | } 21 | 22 | private fun initViews() { 23 | setSupportActionBar(log_toolbar) 24 | supportActionBar!!.setHomeButtonEnabled(true) 25 | supportActionBar!!.setDisplayHomeAsUpEnabled(true) 26 | } 27 | 28 | private fun initData() { 29 | log_console_box.text = LogBuff.finalLog 30 | } 31 | 32 | override fun onCreateOptionsMenu(menu: Menu): Boolean { 33 | val menuInflater = MenuInflater(this) 34 | menuInflater.inflate(R.menu.activity_log_menu, menu) 35 | return super.onCreateOptionsMenu(menu) 36 | } 37 | 38 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 39 | when (item.itemId) { 40 | android.R.id.home -> finish() 41 | R.id.menu_log_refresh -> initData() 42 | } 43 | return super.onOptionsItemSelected(item) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/activities/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.activities 2 | 3 | import android.content.Intent 4 | import android.net.Uri 5 | import android.os.Bundle 6 | import android.view.Menu 7 | import android.view.MenuInflater 8 | import android.view.MenuItem 9 | import android.view.View 10 | import io.alcatraz.afkprotect.Constants 11 | import io.alcatraz.afkprotect.R 12 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 13 | import kotlinx.android.synthetic.main.activity_main.* 14 | 15 | 16 | class MainActivity : CompatWithPipeActivity(), View.OnClickListener { 17 | override fun onCreate(savedInstanceState: Bundle?) { 18 | super.onCreate(savedInstanceState) 19 | setContentView(R.layout.activity_main) 20 | initialize() 21 | } 22 | 23 | override fun onCreateOptionsMenu(menu: Menu?): Boolean { 24 | val menuInflater = MenuInflater(this) 25 | menuInflater.inflate(R.menu.activity_main_menu, menu) 26 | return super.onCreateOptionsMenu(menu) 27 | } 28 | 29 | override fun onOptionsItemSelected(item: MenuItem?): Boolean { 30 | when (item?.itemId) { 31 | R.id.menu_main_about -> startActivity( 32 | Intent( 33 | this@MainActivity, 34 | AboutActivity::class.java 35 | ) 36 | ) 37 | R.id.menu_main_refresh -> initData() 38 | R.id.menu_main_log -> startActivity(Intent(this@MainActivity, LogActivity::class.java)) 39 | } 40 | return super.onOptionsItemSelected(item) 41 | } 42 | 43 | override fun onClick(p0: View?) { 44 | when (p0?.id) { 45 | R.id.main_card_help -> startActivity( 46 | Intent( 47 | Intent.ACTION_VIEW, 48 | Uri.parse(Constants.SUPPORT_URL) 49 | ) 50 | ) 51 | R.id.main_card_history -> startActivity( 52 | Intent( 53 | this@MainActivity, 54 | HistoryActivity::class.java 55 | ) 56 | ) 57 | R.id.main_card_profile_mgr, R.id.main_profile_mgr_modify -> { 58 | val transIntent = Intent( 59 | this@MainActivity, 60 | ProfileGeneralActivity::class.java 61 | ) 62 | startTransition( 63 | transIntent, 64 | main_card_profile_mgr_image, 65 | main_card_profile_mgr_indicator, 66 | main_profile_mgr_modify 67 | ) 68 | } 69 | R.id.main_card_setting -> startActivity( 70 | Intent( 71 | this@MainActivity, 72 | PreferenceActivity::class.java 73 | ) 74 | ) 75 | } 76 | } 77 | 78 | private fun initialize() { 79 | initData() 80 | initViews() 81 | } 82 | 83 | private fun initViews() { 84 | setSupportActionBar(main_toolbar) 85 | main_card_history.setOnClickListener(this) 86 | main_card_profile_mgr.setOnClickListener(this) 87 | main_profile_mgr_modify.setOnClickListener(this) 88 | main_card_setting.setOnClickListener(this) 89 | main_card_help.setOnClickListener(this) 90 | } 91 | 92 | private fun initData() { 93 | val manager = getAEventTaskMgr() 94 | main_card_status_indicator.text = 95 | String.format(getString(R.string.main_card_statistic_indicator), manager.records.size) 96 | main_card_profile_mgr_indicator.text = 97 | String.format(getString(R.string.main_card_profile_indicator), manager.profiles.size) 98 | } 99 | 100 | override fun onResume() { 101 | if (doneFirstInitialize) { 102 | initData() 103 | } 104 | super.onResume() 105 | } 106 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/activities/PreferenceActivity.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.activities 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import android.view.MenuItem 6 | import android.widget.AdapterView 7 | import io.alcatraz.afkprotect.Constants 8 | import io.alcatraz.afkprotect.R 9 | import io.alcatraz.afkprotect.adapters.PreferenceListAdapter 10 | import io.alcatraz.afkprotect.beans.PreferenceHeader 11 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 12 | import kotlinx.android.synthetic.main.activity_preference.* 13 | 14 | 15 | class PreferenceActivity : CompatWithPipeActivity() { 16 | private val headers: MutableList = mutableListOf() 17 | private lateinit var adapter: PreferenceListAdapter 18 | 19 | override fun onCreate(savedInstanceState: Bundle?) { 20 | super.onCreate(savedInstanceState) 21 | setContentView(R.layout.activity_preference) 22 | prepareHeader() 23 | initViews() 24 | } 25 | 26 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 27 | when (item.itemId) { 28 | android.R.id.home -> finish() 29 | } 30 | return super.onOptionsItemSelected(item) 31 | } 32 | 33 | override fun onDestroy() { 34 | super.onDestroy() 35 | sendBroadcast(Intent().setAction(Constants.BROADCAST_ACTION_UPDATE_PREFERENCES)) 36 | } 37 | 38 | private fun initViews() { 39 | setSupportActionBar(preference_act_toolbar) 40 | supportActionBar!!.setHomeButtonEnabled(true) 41 | supportActionBar!!.setDisplayHomeAsUpEnabled(true) 42 | adapter = PreferenceListAdapter(this, headers) 43 | preference_act_list.adapter = adapter 44 | 45 | preference_act_list.onItemClickListener = AdapterView.OnItemClickListener { adapterView, _, i, _ -> 46 | val intent = Intent(this@PreferenceActivity, PreferenceInnerActivity::class.java) 47 | intent.putExtra( 48 | PreferenceInnerActivity.PREFERENCE_TRANSFER_HEADER, 49 | adapterView.getItemAtPosition(i) as PreferenceHeader 50 | ) 51 | this@PreferenceActivity.startActivity(intent) 52 | } 53 | } 54 | 55 | private fun prepareHeader() { 56 | val headerTriggers = PreferenceHeader( 57 | getString(R.string.pref_trigger_category), 58 | getString(R.string.pref_trigger_summary), 59 | R.drawable.ic_settings_black_24dp 60 | ) 61 | headers.add(headerTriggers) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/activities/PreferenceInnerActivity.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.activities 2 | 3 | import android.os.Bundle 4 | import android.view.MenuItem 5 | import io.alcatraz.afkprotect.R 6 | import io.alcatraz.afkprotect.beans.PreferenceHeader 7 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 8 | import io.alcatraz.afkprotect.fragments.TriggerPreferenceFragment 9 | import kotlinx.android.synthetic.main.activity_preference_inner.* 10 | 11 | 12 | class PreferenceInnerActivity : CompatWithPipeActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_preference_inner) 17 | 18 | val intent = intent 19 | val header = intent.getParcelableExtra(PREFERENCE_TRANSFER_HEADER) 20 | preference_act_toolbar.title = header.title 21 | setSupportActionBar(preference_act_toolbar) 22 | supportActionBar!!.setHomeButtonEnabled(true) 23 | supportActionBar!!.setDisplayHomeAsUpEnabled(true) 24 | 25 | when (header.icon_res) { 26 | R.drawable.ic_settings_black_24dp->{ 27 | supportFragmentManager 28 | .beginTransaction() 29 | .replace(R.id.preference_act_fragment_container, TriggerPreferenceFragment()) 30 | .commit() 31 | } 32 | } 33 | } 34 | 35 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 36 | when (item.itemId) { 37 | android.R.id.home -> finish() 38 | } 39 | return super.onOptionsItemSelected(item) 40 | } 41 | 42 | companion object { 43 | const val PREFERENCE_TRANSFER_HEADER = "PREFERENCE_HEADER" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/activities/ProfileGeneralActivity.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.activities 2 | 3 | import android.content.Intent 4 | import android.graphics.Color 5 | import android.os.Bundle 6 | import android.view.Menu 7 | import android.view.MenuInflater 8 | import android.view.MenuItem 9 | import android.view.animation.AnimationUtils 10 | import android.view.animation.LayoutAnimationController 11 | import androidx.recyclerview.widget.LinearLayoutManager 12 | import com.alcatraz.support.v4.appcompat.StatusBarUtil 13 | import io.alcatraz.afkprotect.R 14 | import io.alcatraz.afkprotect.adapters.ProfileAdapter 15 | import io.alcatraz.afkprotect.core.ApplicationProfile 16 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 17 | import kotlinx.android.synthetic.main.activity_profile_general.* 18 | 19 | class ProfileGeneralActivity : CompatWithPipeActivity() { 20 | private val profiles: MutableList = mutableListOf() 21 | private lateinit var adapter: ProfileAdapter 22 | 23 | override fun onCreate(savedInstanceState: Bundle?) { 24 | super.onCreate(savedInstanceState) 25 | setContentView(R.layout.activity_profile_general) 26 | initialize() 27 | } 28 | 29 | private fun initialize() { 30 | adapter = ProfileAdapter(this, profiles) 31 | initViews() 32 | initData() 33 | } 34 | 35 | private fun initViews() { 36 | setSupportActionBar(profile_general_toolbar) 37 | supportActionBar!!.setHomeButtonEnabled(true) 38 | supportActionBar!!.setDisplayHomeAsUpEnabled(true) 39 | StatusBarUtil.setColor(this, Color.parseColor("#212121"), 0) 40 | profile_general_recycler.layoutManager = LinearLayoutManager(this) 41 | val controller: LayoutAnimationController = 42 | AnimationUtils.loadLayoutAnimation(this, R.anim.layout_fall_down) 43 | profile_general_recycler.layoutAnimation = controller 44 | profile_general_recycler.adapter = adapter 45 | profile_general_add.setOnClickListener { 46 | val newIntent = Intent(this@ProfileGeneralActivity, ProfileConfigureActivity::class.java) 47 | newIntent.action = ProfileConfigureActivity.ACTION_NEW 48 | startActivity(newIntent) 49 | } 50 | } 51 | 52 | private fun initData() { 53 | profiles.clear() 54 | profile_general_counter.text = String.format( 55 | getString(R.string.main_card_profile_indicator), 56 | getAEventTaskMgr().profiles.size 57 | ) 58 | val data = getAEventTaskMgr().profiles.values.toList() 59 | profiles.addAll(data) 60 | adapter.notifyDataSetChanged() 61 | profile_general_recycler.scheduleLayoutAnimation() 62 | } 63 | 64 | override fun onResume() { 65 | if (doneFirstInitialize) { 66 | initData() 67 | } 68 | super.onResume() 69 | } 70 | 71 | override fun onCreateOptionsMenu(menu: Menu?): Boolean { 72 | val menuInflater = MenuInflater(this) 73 | menuInflater.inflate(R.menu.activity_profile_general_menu, menu) 74 | return super.onCreateOptionsMenu(menu) 75 | } 76 | 77 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 78 | when (item.itemId) { 79 | android.R.id.home -> finishAfterTransition() 80 | R.id.menu_profile_general_refresh -> initData() 81 | } 82 | return super.onOptionsItemSelected(item) 83 | } 84 | 85 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/activities/RecordActivity.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.activities 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Bundle 5 | import android.view.MenuItem 6 | import io.alcatraz.afkprotect.Constants 7 | import io.alcatraz.afkprotect.R 8 | import io.alcatraz.afkprotect.core.Record 9 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 10 | import kotlinx.android.synthetic.main.activity_record.* 11 | 12 | class RecordActivity : CompatWithPipeActivity() { 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setContentView(R.layout.activity_record) 16 | initialize() 17 | } 18 | 19 | @SuppressLint("SetTextI18n") 20 | private fun initialize(){ 21 | setSupportActionBar(record_toolbar) 22 | supportActionBar!!.setHomeButtonEnabled(true) 23 | supportActionBar!!.setDisplayHomeAsUpEnabled(true) 24 | 25 | val intent = intent 26 | val data = intent.getParcelableExtra(KEY_RECORD_DATA) 27 | record_start.text = Record.convertTime(data.startTime) 28 | record_end.text = Record.convertTime(data.endTime) 29 | record_period.text = ((data.endTime-data.startTime)/1000/3600).toString()+"h" 30 | record_screen_times.text = data.screenOnTimes.toString() 31 | } 32 | 33 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 34 | when (item.itemId) { 35 | android.R.id.home -> finish() 36 | } 37 | return super.onOptionsItemSelected(item) 38 | } 39 | 40 | companion object{ 41 | const val KEY_RECORD_DATA = Constants.MY_PROJECT_CODE+"_key_record_data" 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/adapters/AuthorAdapter.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.adapters 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.BaseAdapter 9 | import io.alcatraz.afkprotect.beans.AuthorElement 10 | import io.alcatraz.afkprotect.databinding.ItemAuthorMainListBinding 11 | 12 | class AuthorAdapter( 13 | private val context: Context, 14 | private val data: List, 15 | private val imgData: List 16 | ) : BaseAdapter() { 17 | private val lf: LayoutInflater = 18 | context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater 19 | 20 | override fun getCount(): Int { 21 | return data.size 22 | } 23 | 24 | override fun getItem(p1: Int): Any { 25 | return data[p1] 26 | } 27 | 28 | override fun getItemId(p1: Int): Long { 29 | return p1.toLong() 30 | } 31 | 32 | @SuppressLint("ViewHolder") 33 | override fun getView(p1: Int, p2: View?, p3: ViewGroup): View { 34 | val itemBinding : ItemAuthorMainListBinding = ItemAuthorMainListBinding.inflate(lf) 35 | val element = data[p1] 36 | itemBinding.authorItemTitle.text = element.title 37 | itemBinding.authorItemDesc.text = element.desc 38 | itemBinding.authorItemIcon.setImageResource(imgData[p1]) 39 | if (p1 == 2) 40 | itemBinding.authorItemDesc.visibility = View.GONE 41 | else 42 | itemBinding.authorItemDesc.visibility = View.VISIBLE 43 | return itemBinding.root 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/adapters/HistoryAdapter.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.adapters 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import android.widget.TextView 10 | import androidx.recyclerview.widget.RecyclerView 11 | import io.alcatraz.afkprotect.R 12 | import io.alcatraz.afkprotect.activities.RecordActivity 13 | import io.alcatraz.afkprotect.core.Record 14 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 15 | 16 | class HistoryAdapter( 17 | private val activity: CompatWithPipeActivity, 18 | private val data: List 19 | ) : RecyclerView.Adapter() { 20 | private val inflater: LayoutInflater = 21 | activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater 22 | 23 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HistoryHolder { 24 | val root = inflater.inflate(R.layout.item_history, parent, false) 25 | return HistoryHolder(root) 26 | } 27 | 28 | @SuppressLint("SetTextI18n") 29 | override fun onBindViewHolder(holder: HistoryHolder, position: Int) { 30 | val record = data[position] 31 | holder.txvStartTime.text = Record.convertTime(record.startTime) 32 | holder.txvElapsedTime.text = 33 | ((record.endTime - record.startTime) / 1000 / 3600).toString() + "h" 34 | holder.txvScreenOnTimes.text = record.screenOnTimes.toString() 35 | holder.itemView.setOnClickListener { 36 | val intent = Intent(activity, RecordActivity::class.java) 37 | intent.putExtra(RecordActivity.KEY_RECORD_DATA, record) 38 | activity.startActivity(intent) 39 | } 40 | } 41 | 42 | override fun getItemCount(): Int { 43 | return data.size 44 | } 45 | } 46 | 47 | class HistoryHolder(itemView: View) : 48 | RecyclerView.ViewHolder(itemView) { 49 | var txvStartTime: TextView = itemView.findViewById(R.id.item_history_start_time) 50 | var txvElapsedTime: TextView = itemView.findViewById(R.id.item_history_elapsed_time) 51 | var txvScreenOnTimes: TextView = itemView.findViewById(R.id.item_history_screen_on_times) 52 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/adapters/PackageAdapter.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.adapters 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.content.pm.PackageInfo 7 | import android.view.LayoutInflater 8 | import android.view.View 9 | import android.view.ViewGroup 10 | import android.widget.CheckBox 11 | import android.widget.Filter 12 | import android.widget.ImageView 13 | import android.widget.TextView 14 | import androidx.recyclerview.widget.RecyclerView 15 | import io.alcatraz.afkprotect.R 16 | import io.alcatraz.afkprotect.activities.ProfileConfigureActivity 17 | import io.alcatraz.afkprotect.core.AccessibilityEventTaskManager 18 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 19 | import io.alcatraz.afkprotect.utils.PackageCtlUtils 20 | import java.util.* 21 | 22 | 23 | class PackageAdapter( 24 | private val activity: CompatWithPipeActivity, 25 | private val data: MutableList, 26 | private val isForIgnorePick: Boolean, 27 | private val manager: AccessibilityEventTaskManager 28 | ) : RecyclerView.Adapter() { 29 | private val inflater: LayoutInflater = 30 | activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater 31 | private var filter: PackageFilter? = null 32 | 33 | 34 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PackHolder { 35 | val root = inflater.inflate(R.layout.item_app_pick, parent, false) 36 | return PackHolder(root) 37 | } 38 | 39 | override fun getItemCount(): Int { 40 | return data.size 41 | } 42 | 43 | override fun onBindViewHolder(holder: PackHolder, position: Int) { 44 | val profile = data[position] 45 | val iconDrawable = PackageCtlUtils.getIcon(activity, profile.applicationInfo) 46 | if (iconDrawable != null) { 47 | holder.packIcon.setImageDrawable(iconDrawable) 48 | } 49 | 50 | holder.txvPack.text = profile.packageName 51 | holder.txvLabel.text = PackageCtlUtils.getLabel(activity, profile.applicationInfo) 52 | if (isForIgnorePick) { 53 | holder.checkBox.visibility = View.VISIBLE 54 | if (manager.ignoreContains(profile.packageName)) { 55 | holder.checkBox.isChecked = true 56 | } 57 | holder.itemView.setOnClickListener { 58 | if (holder.checkBox.isChecked) { 59 | manager.ignoreRemove(profile.packageName) 60 | } else { 61 | manager.ignoreAdd(profile.packageName) 62 | } 63 | holder.checkBox.isChecked = !holder.checkBox.isChecked 64 | } 65 | } else { 66 | holder.itemView.setOnClickListener { 67 | val data = Intent() 68 | data.putExtra( 69 | ProfileConfigureActivity.ACTION_PACK_PICK, 70 | profile.packageName 71 | ) 72 | activity.setResult(Activity.RESULT_OK, data) 73 | activity.finish() 74 | } 75 | } 76 | } 77 | 78 | private fun getFilter(): PackageFilter { 79 | if(filter == null){ 80 | filter = PackageFilter(data) 81 | } 82 | return filter!! 83 | } 84 | 85 | fun onTextChanged(newText: String?) { 86 | getFilter().filter(newText) 87 | } 88 | 89 | private inner class PackageFilter(val original: MutableList) : 90 | Filter() { 91 | val copyList = mutableListOf() 92 | init { 93 | copyList.addAll(original) 94 | } 95 | override fun performFiltering(p0: CharSequence?): FilterResults { 96 | val results = FilterResults() 97 | if (p0 == null || p0.isEmpty()) { 98 | results.values = copyList 99 | results.count = copyList.size 100 | } else { 101 | val mList: MutableList = mutableListOf() 102 | for (info in copyList) { 103 | if (PackageCtlUtils.getLabel(activity, info.applicationInfo) 104 | .toLowerCase(Locale.getDefault()) 105 | .contains(p0.toString().toLowerCase(Locale.getDefault())) 106 | || info.packageName.toLowerCase(Locale.getDefault()) 107 | .contains(p0.toString().toLowerCase(Locale.getDefault())) 108 | ) { 109 | mList.add(info) 110 | } 111 | } 112 | results.values = mList 113 | results.count = mList.size 114 | } 115 | return results 116 | } 117 | 118 | override fun publishResults(p0: CharSequence?, p1: FilterResults?) { 119 | data.clear() 120 | data.addAll(p1?.values as MutableList) 121 | notifyDataSetChanged() 122 | } 123 | } 124 | } 125 | 126 | class PackHolder(itemView: View) : 127 | RecyclerView.ViewHolder(itemView) { 128 | val packIcon: ImageView = itemView.findViewById(R.id.app_pick_pack_icon) 129 | val txvLabel: TextView = itemView.findViewById(R.id.app_pick_pack_label) 130 | val txvPack: TextView = itemView.findViewById(R.id.app_pick_pack_name) 131 | val checkBox: CheckBox = itemView.findViewById(R.id.app_pick_pack_checkbox) 132 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/adapters/PreferenceListAdapter.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.adapters 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.BaseAdapter 9 | import io.alcatraz.afkprotect.beans.PreferenceHeader 10 | import io.alcatraz.afkprotect.databinding.ItemPreferenceHeaderBinding 11 | 12 | class PreferenceListAdapter( 13 | private val context: Context, 14 | private val data: List 15 | ) : BaseAdapter() { 16 | private val layoutInflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater 17 | 18 | override fun getCount(): Int { 19 | return data.size 20 | } 21 | 22 | override fun getItem(i: Int): Any { 23 | return data[i] 24 | } 25 | 26 | override fun getItemId(i: Int): Long { 27 | return i.toLong() 28 | } 29 | 30 | @SuppressLint("ViewHolder") 31 | override fun getView(i: Int, view: View?, viewGroup: ViewGroup): View { 32 | val itemBinding = ItemPreferenceHeaderBinding.inflate(layoutInflater) 33 | val header = data[i] 34 | itemBinding.itemPrefHeaderTitle.text = header.title 35 | itemBinding.itemPrefHeaderSummary.text = header.summary 36 | itemBinding.itemPrefHeaderImage.setImageResource(header.icon_res) 37 | return itemBinding.root 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/adapters/ProfileAdapter.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.adapters 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.ImageView 9 | import android.widget.TextView 10 | import androidx.recyclerview.widget.RecyclerView 11 | import io.alcatraz.afkprotect.R 12 | import io.alcatraz.afkprotect.activities.ProfileConfigureActivity 13 | import io.alcatraz.afkprotect.core.ApplicationProfile 14 | import io.alcatraz.afkprotect.utils.PackageCtlUtils 15 | 16 | class ProfileAdapter( 17 | private val context: Context, 18 | private val data: MutableList 19 | ) : RecyclerView.Adapter(){ 20 | private val inflater: LayoutInflater = 21 | context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater 22 | 23 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProfileHolder { 24 | val root = inflater.inflate(R.layout.item_profile, parent, false) 25 | return ProfileHolder(root) 26 | } 27 | 28 | override fun getItemCount(): Int { 29 | return data.size 30 | } 31 | 32 | override fun onBindViewHolder(holder: ProfileHolder, position: Int) { 33 | val profile = data[position] 34 | val packIcon = PackageCtlUtils.getIcon(context,profile.pack) 35 | if(packIcon!=null){ 36 | holder.packIcon.setImageDrawable(packIcon) 37 | } 38 | 39 | holder.txvLabel.text = PackageCtlUtils.getLabel(context,profile.pack) 40 | if (profile.doPauseMusicBroadcast || profile.doSetStreamVolumeZero){ 41 | holder.txvMute.text = context.getString(R.string.ad_pb2) 42 | }else{ 43 | holder.txvMute.text = context.getString(R.string.ad_nb2) 44 | } 45 | 46 | if(profile.backClickTimes > 0){ 47 | holder.txvExit.text = context.getString(R.string.ad_pb2) 48 | }else{ 49 | holder.txvExit.text = context.getString(R.string.ad_nb2) 50 | } 51 | 52 | holder.txvBackTimes.text = profile.backClickTimes.toString() 53 | 54 | holder.itemView.setOnClickListener { 55 | val intent = Intent(context,ProfileConfigureActivity::class.java) 56 | intent.action = ProfileConfigureActivity.ACTION_LOAD_FORMER 57 | intent.putExtra( 58 | ProfileConfigureActivity.ACTION_LOAD_FORMER, 59 | profile.pack 60 | ) 61 | context.startActivity(intent) 62 | } 63 | } 64 | 65 | } 66 | 67 | class ProfileHolder(itemView: View) : 68 | RecyclerView.ViewHolder(itemView) { 69 | var packIcon: ImageView = itemView.findViewById(R.id.item_profile_app_icon) 70 | var txvLabel: TextView = itemView.findViewById(R.id.item_profile_app_name) 71 | var txvMute: TextView = itemView.findViewById(R.id.item_profile_mute) 72 | var txvExit: TextView = itemView.findViewById(R.id.item_profile_try_exit) 73 | var txvBackTimes: TextView = itemView.findViewById(R.id.item_profile_back_times) 74 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/adapters/QueryElementAdapter.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.adapters 2 | 3 | import android.content.Context 4 | import android.content.Intent 5 | import android.net.Uri 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import android.widget.TextView 10 | 11 | import androidx.cardview.widget.CardView 12 | import androidx.recyclerview.widget.RecyclerView 13 | 14 | import io.alcatraz.afkprotect.R 15 | import io.alcatraz.afkprotect.beans.QueryElement 16 | 17 | class QueryElementAdapter(private val context: Context, 18 | private val data: List) : 19 | RecyclerView.Adapter() { 20 | private var layoutInflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater 21 | 22 | override fun onCreateViewHolder(p1: ViewGroup, p2: Int): QueryElementContainer { 23 | val viewHolder = layoutInflater.inflate(R.layout.item_opensource_holder, p1, false) 24 | return QueryElementContainer(viewHolder) 25 | } 26 | 27 | override fun onBindViewHolder(p1: QueryElementContainer, p2: Int) { 28 | val element = data[p2] 29 | p1.cardRoot.setOnClickListener { 30 | val localIntent = Intent("android.intent.action.VIEW") 31 | localIntent.data = Uri.parse(element.url) 32 | context.startActivity(localIntent) 33 | } 34 | p1.txvName.text = element.name 35 | p1.txvAuthor.text = element.author 36 | p1.txvIntro.text = element.intro 37 | p1.txvLicense.text = element.license 38 | } 39 | 40 | override fun getItemCount(): Int { 41 | return data.size 42 | } 43 | } 44 | 45 | class QueryElementContainer(val view: View) : RecyclerView.ViewHolder(view){ 46 | internal val txvName : TextView = view.findViewById(R.id.open_source_name) 47 | internal val txvLicense : TextView = view.findViewById(R.id.open_source_license) 48 | internal val txvIntro : TextView = view.findViewById(R.id.open_source_intro) 49 | internal val txvAuthor : TextView = view.findViewById(R.id.open_source_author) 50 | internal val cardRoot : CardView = view.findViewById(R.id.open_source_item_card) 51 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/adapters/SetupPagerAdapter.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.adapters 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.viewpager.widget.PagerAdapter 8 | import io.alcatraz.afkprotect.beans.SetupPage 9 | 10 | class SetupPagerAdapter( 11 | private val pages: List, 12 | val context: Context 13 | ) : PagerAdapter() { 14 | private val layoutInflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater 15 | override fun getCount(): Int { 16 | return pages.size 17 | } 18 | 19 | override fun isViewFromObject(view: View, o: Any): Boolean { 20 | return view === o 21 | } 22 | 23 | override fun destroyItem( 24 | container: ViewGroup, 25 | position: Int, 26 | obj: Any 27 | ) { 28 | container.removeView(obj as View) 29 | } 30 | 31 | override fun instantiateItem(container: ViewGroup, position: Int): Any { 32 | val element = pages[position] 33 | var root = element.rootView 34 | if (root == null) { 35 | root = layoutInflater.inflate(element.layout_id, null) 36 | element.rootView = root 37 | } 38 | container.addView(root) 39 | return root!! 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/beans/AuthorElement.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.beans 2 | 3 | data class AuthorElement(val title: String, var desc: String) -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/beans/LambdaBridge.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.beans 2 | 3 | class LambdaBridge { 4 | var target: T? = null 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/beans/PreferenceHeader.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.beans 2 | 3 | import android.os.Parcel 4 | import android.os.Parcelable 5 | 6 | data class PreferenceHeader(val title: String?, val summary: String?,val icon_res: Int) : Parcelable { 7 | constructor(parcel: Parcel) : this( 8 | parcel.readString(), 9 | parcel.readString(), 10 | parcel.readInt() 11 | ) 12 | 13 | override fun writeToParcel(parcel: Parcel, flags: Int) { 14 | parcel.writeString(title) 15 | parcel.writeString(summary) 16 | parcel.writeInt(icon_res) 17 | } 18 | 19 | override fun describeContents(): Int { 20 | return 0 21 | } 22 | 23 | companion object CREATOR : Parcelable.Creator { 24 | override fun createFromParcel(parcel: Parcel): PreferenceHeader { 25 | return PreferenceHeader(parcel) 26 | } 27 | 28 | override fun newArray(size: Int): Array { 29 | return arrayOfNulls(size) 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/beans/ProfileParamCheckResult.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.beans 2 | 3 | class ProfileParamCheckResult(var success: Boolean, var timeToElapse: Int, var backTimes: Int) { 4 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/beans/QueryElement.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.beans 2 | 3 | data class QueryElement(val author: String, val name: String, val url: String, val license: String, val intro: String) -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/beans/SetupPage.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.beans 2 | 3 | import android.view.View 4 | 5 | class SetupPage(var title: String, var layout_id: Int) { 6 | var rootView: View? = null 7 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/core/ApplicationProfile.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.core 2 | 3 | class ApplicationProfile( 4 | var pack: String, 5 | var afkTime: Int 6 | ) { 7 | var intendedActs: MutableList = mutableListOf("") 8 | var useActIndividualCtl: Boolean = false 9 | var backClickTimes: Int = 1 10 | var doPauseMusicBroadcast = true 11 | var doRequestAudioFocus = true 12 | var doSetStreamVolumeZero = true 13 | var extendedOptions = "" 14 | 15 | constructor( 16 | pack: String, 17 | afkTime: Int, 18 | intendedActs: MutableList, 19 | useActIndividualCtl: Boolean, 20 | backClickTimes: Int 21 | ) : this(pack, afkTime) { 22 | this.intendedActs = intendedActs 23 | this.useActIndividualCtl = useActIndividualCtl 24 | this.backClickTimes = backClickTimes 25 | } 26 | 27 | constructor( 28 | pack: String, 29 | afkTime: Int, 30 | intendedActs: MutableList, 31 | useActIndividualCtl: Boolean, 32 | backClickTimes: Int, 33 | doPauseMusicBroadcast: Boolean, 34 | doRequestAudioFocus: Boolean, 35 | doSetStreamVolumeZero: Boolean 36 | ) : this(pack, afkTime, intendedActs, useActIndividualCtl, backClickTimes) { 37 | this.doPauseMusicBroadcast = doPauseMusicBroadcast 38 | this.doRequestAudioFocus = doRequestAudioFocus 39 | this.doSetStreamVolumeZero = doSetStreamVolumeZero 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/core/DeviceMgrApi.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.core 2 | 3 | import android.app.admin.DevicePolicyManager 4 | import android.content.ComponentName 5 | import android.content.Context 6 | import android.content.Intent 7 | import io.alcatraz.afkprotect.extended.CompatWithPipeActivity 8 | import io.alcatraz.afkprotect.receivers.LockScreenAdmin 9 | 10 | class DeviceMgrApi(val context: Context) { 11 | private val deviceMgr = 12 | context.getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager 13 | private val componentName = ComponentName(context, LockScreenAdmin::class.java) 14 | fun isAdminActive(): Boolean { 15 | return deviceMgr.isAdminActive(componentName) 16 | } 17 | 18 | fun lockScreen() : Boolean{ 19 | if (isAdminActive()) { 20 | deviceMgr.lockNow() 21 | return true 22 | } 23 | return false 24 | } 25 | 26 | companion object { 27 | fun startDeviceAdminAuth(activity: CompatWithPipeActivity) { 28 | val component = ComponentName(activity, LockScreenAdmin::class.java) 29 | val deviceMgrIntent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN) 30 | deviceMgrIntent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, component) 31 | activity.startActivity(deviceMgrIntent) 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/core/History.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.core 2 | 3 | class History { 4 | var historyList:MutableList = mutableListOf() 5 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/core/Profiles.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.core 2 | 3 | class Profiles { 4 | var profileMap:MutableMap = mutableMapOf() 5 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/core/Record.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.core 2 | 3 | import android.annotation.SuppressLint 4 | import android.os.Parcel 5 | import android.os.Parcelable 6 | import java.text.SimpleDateFormat 7 | import java.util.* 8 | 9 | class Record(var startTime: Long) : Parcelable { 10 | var endTime: Long = 0 11 | var screenOnTimes = 0 12 | var packName = "" 13 | 14 | constructor(parcel: Parcel) : this(parcel.readLong()) { 15 | endTime = parcel.readLong() 16 | screenOnTimes = parcel.readInt() 17 | } 18 | 19 | fun addScreenOnT() { 20 | screenOnTimes++ 21 | } 22 | 23 | override fun writeToParcel(parcel: Parcel, flags: Int) { 24 | parcel.writeLong(startTime) 25 | parcel.writeLong(endTime) 26 | parcel.writeInt(screenOnTimes) 27 | } 28 | 29 | override fun describeContents(): Int { 30 | return 0 31 | } 32 | 33 | companion object CREATOR : Parcelable.Creator { 34 | override fun createFromParcel(parcel: Parcel): Record { 35 | return Record(parcel) 36 | } 37 | 38 | override fun newArray(size: Int): Array { 39 | return arrayOfNulls(size) 40 | } 41 | 42 | fun convertTime(millis: Long): String { 43 | @SuppressLint("SimpleDateFormat") val formatter = SimpleDateFormat("MM-dd HH:mm:ss") 44 | val date = Date(millis) 45 | return formatter.format(date) 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/core/Rectifier.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.core 2 | 3 | object Rectifier { 4 | fun isPackageIgnored(list: MutableList,pack: String): Boolean{ 5 | for (i in list){ 6 | if(pack == i){ 7 | return true 8 | } 9 | } 10 | return false 11 | } 12 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/extended/CompatWithPipeActivity.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.extended 2 | 3 | import android.R 4 | import android.annotation.SuppressLint 5 | import android.annotation.TargetApi 6 | import android.content.BroadcastReceiver 7 | import android.content.Context 8 | import android.content.Intent 9 | import android.content.IntentFilter 10 | import android.os.Build 11 | import android.os.Bundle 12 | import android.transition.Transition 13 | import android.transition.TransitionInflater 14 | import android.view.View 15 | import android.widget.Toast 16 | import androidx.appcompat.app.AppCompatActivity 17 | import androidx.core.app.ActivityOptionsCompat 18 | import io.alcatraz.afkprotect.Constants 19 | import io.alcatraz.afkprotect.FaceSaverApplication 20 | import io.alcatraz.afkprotect.core.AccessibilityEventTaskManager 21 | import io.alcatraz.afkprotect.utils.PermissionInterface 22 | 23 | 24 | @SuppressLint("Registered") 25 | open class CompatWithPipeActivity : AppCompatActivity() { 26 | private var permissionInterface: PermissionInterface? = null 27 | private lateinit var updatePreferenceReceiver: UpdatePreferenceReceiver 28 | 29 | private var requestQueue = 0 30 | 31 | var doneFirstInitialize = false 32 | 33 | //=========PREFERENCES============== 34 | 35 | override fun onRequestPermissionsResult( 36 | requestCode: Int, 37 | permissions: Array, 38 | grantResults: IntArray 39 | ) { 40 | super.onRequestPermissionsResult(requestCode, permissions, grantResults) 41 | if (permissionInterface != null && requestCode == requestQueue - 1) { 42 | permissionInterface!!.onResult(requestCode, permissions, grantResults) 43 | } 44 | } 45 | 46 | override fun onCreate(savedInstanceState: Bundle?) { 47 | super.onCreate(savedInstanceState) 48 | loadPreference() 49 | setupTransition() 50 | registerReceivers() 51 | } 52 | 53 | override fun onResume() { 54 | super.onResume() 55 | doneFirstInitialize = true 56 | } 57 | 58 | @TargetApi(Build.VERSION_CODES.M) 59 | fun requestPermissionWithCallback( 60 | pi: PermissionInterface, 61 | requestCode: Int, 62 | vararg permissions: String 63 | ) { 64 | this.permissionInterface = pi 65 | requestPermissions(permissions, requestCode) 66 | } 67 | 68 | fun requestPermissionWithCallback(pi: PermissionInterface, vararg permissions: String) { 69 | requestPermissionWithCallback(pi, requestQueue, *permissions) 70 | requestQueue++ 71 | } 72 | 73 | fun onReloadPreferenceDone() {} 74 | 75 | fun loadPreference() { 76 | 77 | } 78 | 79 | private fun registerReceivers() { 80 | val intentFilter = IntentFilter() 81 | intentFilter.addAction(Constants.BROADCAST_ACTION_UPDATE_PREFERENCES) 82 | updatePreferenceReceiver = UpdatePreferenceReceiver() 83 | registerReceiver(updatePreferenceReceiver, intentFilter) 84 | } 85 | 86 | fun getAEventTaskMgr(): AccessibilityEventTaskManager { 87 | val application: FaceSaverApplication = application as FaceSaverApplication 88 | return application.aEventTaskMgr.get() 89 | } 90 | 91 | override fun onDestroy() { 92 | unregisterReceiver(updatePreferenceReceiver) 93 | super.onDestroy() 94 | } 95 | 96 | fun toast(str: String) { 97 | Toast.makeText(this, str, Toast.LENGTH_SHORT).show() 98 | } 99 | 100 | fun toast(resId: Int) { 101 | Toast.makeText(this, resId, Toast.LENGTH_SHORT).show() 102 | } 103 | 104 | fun startTransition(intent: Intent?, vararg elements: View) { 105 | val pairs: Array?> = arrayOfNulls?>(elements.size) 106 | for (i in elements.indices) { 107 | val pair: androidx.core.util.Pair = 108 | androidx.core.util.Pair(elements[i], elements[i].transitionName) 109 | pairs[i] = pair 110 | } 111 | val optionsCompat = 112 | ActivityOptionsCompat.makeSceneTransitionAnimation(this, *pairs) 113 | startActivity(intent, optionsCompat.toBundle()) 114 | } 115 | 116 | open fun setupTransition() { 117 | val slideRight: Transition = 118 | TransitionInflater.from(this).inflateTransition(R.transition.slide_right) 119 | val slideLeft: Transition = 120 | TransitionInflater.from(this).inflateTransition(R.transition.slide_right) 121 | window.enterTransition = slideRight 122 | window.exitTransition = slideLeft 123 | window.returnTransition = slideRight 124 | } 125 | 126 | open fun setupExplodeTransition() { 127 | val explode: Transition = 128 | TransitionInflater.from(this).inflateTransition(R.transition.explode) 129 | window.enterTransition = explode 130 | window.exitTransition = explode 131 | window.returnTransition = explode 132 | } 133 | 134 | internal inner class UpdatePreferenceReceiver : BroadcastReceiver() { 135 | 136 | override fun onReceive(context: Context, intent: Intent) { 137 | loadPreference() 138 | onReloadPreferenceDone() 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/extended/NoScrollExpandableListView.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.extended 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.widget.ExpandableListView 6 | 7 | class NoScrollExpandableListView : ExpandableListView { 8 | constructor(context: Context) : super(context) 9 | 10 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) 11 | 12 | constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super( 13 | context, 14 | attrs, 15 | defStyle 16 | ) 17 | 18 | override fun onMeasure(widthSpec: Int, heightSpec: Int) { 19 | val expandSpec = 20 | MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE shr 2, MeasureSpec.AT_MOST) 21 | super.onMeasure(widthSpec, expandSpec) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/extended/NoScrollListView.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.extended 2 | 3 | import android.content.Context 4 | import android.util.AttributeSet 5 | import android.widget.ListView 6 | 7 | class NoScrollListView : ListView { 8 | constructor(context: Context) : super(context) 9 | 10 | constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) 11 | 12 | constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super( 13 | context, 14 | attrs, 15 | defStyle 16 | ) 17 | 18 | override fun onMeasure(widthSpec: Int, heightSpec: Int) { 19 | val expandSpec = 20 | MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE shr 2, MeasureSpec.AT_MOST) 21 | super.onMeasure(widthSpec, expandSpec) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/extended/NoScrollViewPager.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.extended 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import android.util.AttributeSet 6 | import android.view.MotionEvent 7 | 8 | import androidx.viewpager.widget.ViewPager 9 | 10 | class NoScrollViewPager : ViewPager { 11 | private var isScroll = false 12 | 13 | constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} 14 | 15 | constructor(context: Context) : super(context) {} 16 | 17 | override fun onInterceptTouchEvent(ev: MotionEvent): Boolean { 18 | return if (isScroll) { 19 | super.onInterceptTouchEvent(ev) 20 | } else { 21 | false 22 | } 23 | } 24 | 25 | @SuppressLint("ClickableViewAccessibility") 26 | override fun onTouchEvent(ev: MotionEvent): Boolean { 27 | return if (isScroll) { 28 | super.onTouchEvent(ev) 29 | } else { 30 | true 31 | } 32 | } 33 | 34 | fun setScroll(scroll: Boolean) { 35 | isScroll = scroll 36 | } 37 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/extended/RoundImageView.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.extended 2 | 3 | import android.content.Context 4 | import android.graphics.* 5 | import android.graphics.drawable.BitmapDrawable 6 | import android.util.AttributeSet 7 | 8 | class RoundImageView @JvmOverloads constructor( 9 | context: Context, 10 | attrs: AttributeSet? = null, 11 | defStyle: Int = 0 12 | ) : androidx.appcompat.widget.AppCompatImageView(context, attrs, defStyle) { 13 | private val paint: Paint = Paint() 14 | 15 | /** 16 | * 绘制圆形图片 17 | * @author caizhiming 18 | */ 19 | override fun onDraw(canvas: Canvas) { 20 | 21 | val drawable = drawable 22 | if (null != drawable) { 23 | val bitmap = (drawable as BitmapDrawable).bitmap 24 | val b = getCircleBitmap(bitmap, 14) 25 | val rectSrc = Rect(0, 0, b.width, b.height) 26 | val rectDest = Rect(0, 0, width, height) 27 | paint.reset() 28 | canvas.drawBitmap(b, rectSrc, rectDest, paint) 29 | 30 | } else { 31 | super.onDraw(canvas) 32 | } 33 | } 34 | 35 | /** 36 | * 获取圆形图片方法 37 | * @param bitmap 38 | * @param pixels 39 | * @return Bitmap 40 | * @author caizhiming 41 | */ 42 | private fun getCircleBitmap(bitmap: Bitmap, pixels: Int): Bitmap { 43 | val output = Bitmap.createBitmap( 44 | bitmap.width, 45 | bitmap.height, Bitmap.Config.ARGB_8888 46 | ) 47 | val canvas = Canvas(output) 48 | 49 | val color = -0xbdbdbe 50 | 51 | val rect = Rect(0, 0, bitmap.width, bitmap.height) 52 | paint.isAntiAlias = true 53 | canvas.drawARGB(0, 0, 0, 0) 54 | paint.color = color 55 | val x = bitmap.width 56 | 57 | canvas.drawCircle((x / 2).toFloat(), (x / 2).toFloat(), (x / 2).toFloat(), paint) 58 | paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN) 59 | canvas.drawBitmap(bitmap, rect, rect, paint) 60 | return output 61 | } 62 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/fragments/TriggerPreferenceFragment.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.fragments 2 | 3 | import android.content.Intent 4 | import android.os.Bundle 5 | import androidx.preference.Preference 6 | import androidx.preference.PreferenceFragmentCompat 7 | import androidx.preference.PreferenceScreen 8 | import io.alcatraz.afkprotect.Constants 9 | import io.alcatraz.afkprotect.R 10 | import io.alcatraz.afkprotect.activities.AppPickActivity 11 | 12 | class TriggerPreferenceFragment : PreferenceFragmentCompat() { 13 | private lateinit var ignorePackage: PreferenceScreen 14 | 15 | private fun bindListeners() { 16 | ignorePackage.onPreferenceClickListener = object : Preference.OnPreferenceClickListener{ 17 | override fun onPreferenceClick(preference: Preference?): Boolean { 18 | val intent = Intent(context,AppPickActivity::class.java) 19 | intent.action = AppPickActivity.ACTION_PICK_IGNORE_PACKAGE 20 | startActivity(intent) 21 | return true 22 | } 23 | } 24 | } 25 | 26 | private fun findPreferences() { 27 | ignorePackage = findPreference(Constants.PREF_TRIGGER_IGNORE_PACKAGE)!! 28 | } 29 | 30 | private fun updateEditTextSummay() { 31 | 32 | } 33 | 34 | override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { 35 | setPreferencesFromResource(R.xml.preference_trigger, rootKey) 36 | findPreferences() 37 | bindListeners() 38 | updateEditTextSummay() 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/receivers/LockScreenAdmin.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.receivers 2 | 3 | import android.app.admin.DeviceAdminReceiver 4 | 5 | class LockScreenAdmin : DeviceAdminReceiver() -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/services/ProtectorService.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.services 2 | 3 | import android.accessibilityservice.AccessibilityService 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.provider.Settings 7 | import android.view.accessibility.AccessibilityEvent 8 | import io.alcatraz.afkprotect.FaceSaverApplication 9 | import io.alcatraz.afkprotect.LogBuff 10 | import io.alcatraz.afkprotect.core.AccessibilityEventTaskManager 11 | 12 | class ProtectorService : AccessibilityService() { 13 | private var targetEventPackage: CharSequence = "" 14 | private var targetActivity: CharSequence = "" 15 | 16 | override fun onInterrupt() { 17 | getAEventTaskMgr().clearOnInterrupt() 18 | getAEventTaskMgr().initService(null) 19 | } 20 | 21 | override fun onServiceConnected() { 22 | super.onServiceConnected() 23 | getAEventTaskMgr().initService(this) 24 | LogBuff.accessibilityStatus = true 25 | } 26 | 27 | override fun onAccessibilityEvent(p0: AccessibilityEvent?) { 28 | when (p0?.eventType) { 29 | AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED -> { 30 | val currentEventPackage = p0.packageName ?: return 31 | val currentActivity = p0.className ?: return 32 | if (targetEventPackage != currentEventPackage) { 33 | targetEventPackage = currentEventPackage 34 | targetActivity = currentActivity 35 | doUpdate() 36 | } else { 37 | if (targetActivity != currentActivity) { 38 | targetActivity = currentActivity 39 | doUpdate() 40 | } 41 | } 42 | } 43 | AccessibilityEvent.TYPE_VIEW_CLICKED, AccessibilityEvent.TYPE_VIEW_LONG_CLICKED, 44 | AccessibilityEvent.TYPE_VIEW_SELECTED, AccessibilityEvent.TYPE_VIEW_SCROLLED -> { 45 | //This is complicated, may be implemented in future version 46 | } 47 | } 48 | } 49 | 50 | private fun doUpdate() { 51 | getAEventTaskMgr().accessibilityUpdate( 52 | targetEventPackage.toString(), 53 | targetActivity.toString() 54 | ) 55 | } 56 | 57 | private fun getAEventTaskMgr(): AccessibilityEventTaskManager { 58 | val application: FaceSaverApplication = application as FaceSaverApplication 59 | return application.aEventTaskMgr.get() 60 | } 61 | 62 | companion object { 63 | fun startAccessibilityAuthorize(context: Context) { 64 | val accessibilityIntent = Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS) 65 | context.startActivity(accessibilityIntent) 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/utils/AnimateUtils.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.utils 2 | 3 | import android.view.View 4 | import android.view.animation.AlphaAnimation 5 | import android.view.animation.Animation 6 | import android.view.animation.AnimationSet 7 | import android.widget.TextView 8 | 9 | object AnimateUtils { 10 | fun textChange(textView: TextView, text: CharSequence) { 11 | val animationSet = AnimationSet(true) 12 | val alphaAnimation = AlphaAnimation(1f, 0f) 13 | alphaAnimation.duration = 200 14 | animationSet.addAnimation(alphaAnimation) 15 | textView.startAnimation(animationSet) 16 | animationSet.setAnimationListener(object : Animation.AnimationListener { 17 | 18 | override fun onAnimationStart(p1: Animation) { 19 | 20 | } 21 | 22 | override fun onAnimationEnd(p1: Animation) { 23 | textView.visibility = View.GONE 24 | textView.text = text 25 | val animationSet1 = AnimationSet(true) 26 | val alphaAnimation1 = AlphaAnimation(0f, 1f) 27 | alphaAnimation1.duration = 200 28 | animationSet1.addAnimation(alphaAnimation1) 29 | textView.startAnimation(animationSet1) 30 | animationSet1.setAnimationListener(object : Animation.AnimationListener { 31 | 32 | override fun onAnimationStart(p1: Animation) { 33 | 34 | } 35 | 36 | override fun onAnimationEnd(p1: Animation) { 37 | textView.visibility = View.VISIBLE 38 | 39 | } 40 | 41 | override fun onAnimationRepeat(p1: Animation) { 42 | 43 | } 44 | }) 45 | } 46 | 47 | override fun onAnimationRepeat(p1: Animation) { 48 | 49 | } 50 | }) 51 | 52 | } 53 | 54 | fun fadeIn(target: View, animateInterface: SimpleAnimateInterface) { 55 | val animationSet = AnimationSet(true) 56 | val alphaAnimation = AlphaAnimation(0f, 1f) 57 | alphaAnimation.duration = 1200 58 | animationSet.addAnimation(alphaAnimation) 59 | target.startAnimation(animationSet) 60 | animationSet.setAnimationListener(object : Animation.AnimationListener { 61 | 62 | override fun onAnimationStart(p1: Animation) {} 63 | 64 | override fun onAnimationEnd(p1: Animation) { 65 | target.visibility = View.VISIBLE 66 | animateInterface.onEnd() 67 | } 68 | 69 | override fun onAnimationRepeat(p1: Animation) { 70 | 71 | } 72 | }) 73 | } 74 | 75 | fun fadeOut(target: View, animateInterface: SimpleAnimateInterface) { 76 | val animationSet = AnimationSet(true) 77 | val alphaAnimation = AlphaAnimation(1f, 0f) 78 | alphaAnimation.duration = 300 79 | animationSet.addAnimation(alphaAnimation) 80 | target.startAnimation(animationSet) 81 | animationSet.setAnimationListener(object : Animation.AnimationListener { 82 | 83 | override fun onAnimationStart(p1: Animation) {} 84 | 85 | override fun onAnimationEnd(p1: Animation) { 86 | target.visibility = View.GONE 87 | animateInterface.onEnd() 88 | } 89 | 90 | override fun onAnimationRepeat(p1: Animation) { 91 | 92 | } 93 | }) 94 | } 95 | 96 | interface SimpleAnimateInterface { 97 | fun onEnd() 98 | } 99 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/utils/DebugUtils.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.utils 2 | 3 | object DebugUtils 4 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/utils/IOUtils.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.utils 2 | 3 | import android.content.Context 4 | import io.alcatraz.afkprotect.Constants 5 | import io.alcatraz.afkprotect.LogBuff 6 | import java.io.File 7 | 8 | object IOUtils { 9 | fun getHistoryPath(context: Context): String { 10 | val root = context.filesDir 11 | return root.absolutePath + "/history_v" + Constants.DATA_HISTORY_VERSION + ".json" 12 | } 13 | 14 | fun getProfilesPath(context: Context): String { 15 | val root = context.filesDir 16 | return root.absolutePath + "/profiles_v" + Constants.DATA_PROFILE_VERSION + ".json" 17 | } 18 | 19 | fun write(dir: String, content: String) { 20 | val file = File(dir) 21 | if (!file.exists()) { 22 | try { 23 | file.parentFile.mkdirs() 24 | file.createNewFile() 25 | } catch (ignored: Exception) { 26 | } 27 | } 28 | file.writeText(content) 29 | } 30 | 31 | fun read(dir: String, rm: ReadMonitor?): String { 32 | var content = "" 33 | val file = File(dir) 34 | if (!file.exists()) { 35 | try { 36 | file.parentFile.mkdirs() 37 | file.createNewFile() 38 | return content 39 | } catch (e: Exception) { 40 | LogBuff.E(e.message?:"") 41 | } 42 | } 43 | file.forEachLine { 44 | content += "\n" 45 | content += it 46 | rm?.onLine(it) 47 | } 48 | return content 49 | } 50 | 51 | fun renameFile(oldPath: String, newPath: String) { 52 | val oleFile = File(oldPath) 53 | val newFile = File(newPath) 54 | oleFile.renameTo(newFile) 55 | } 56 | 57 | fun delete(path: String): Boolean { 58 | val file = File(path) 59 | if (!file.exists()) { 60 | return false 61 | } 62 | if (file.isFile) { 63 | return file.delete() 64 | } 65 | val files = file.listFiles() 66 | for (f in files) { 67 | if (f.isFile) { 68 | if (!f.delete()) { 69 | return false 70 | } 71 | } else { 72 | if (!delete(f.absolutePath)) { 73 | return false 74 | } 75 | } 76 | } 77 | return file.delete() 78 | } 79 | 80 | interface ReadMonitor { 81 | fun onLine(line: String) 82 | 83 | fun callFinish() 84 | } 85 | } -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/utils/PackageCtlUtils.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.utils 2 | 3 | import android.content.Context 4 | import android.content.pm.ApplicationInfo 5 | import android.content.pm.PackageManager 6 | import android.graphics.drawable.Drawable 7 | 8 | object PackageCtlUtils { 9 | fun getIcon(ctx: Context, pkg: String): Drawable? { 10 | val packageManager = ctx.packageManager 11 | val applicationInfo = packageManager.getApplicationInfo(pkg, PackageManager.GET_META_DATA) 12 | return packageManager.getApplicationIcon(applicationInfo) 13 | } 14 | 15 | fun getLabel(ctx: Context, pkg: String): String { 16 | val pm = ctx.packageManager 17 | return try { 18 | val ai = pm.getApplicationInfo(pkg, PackageManager.GET_META_DATA) 19 | pm.getApplicationLabel(ai).toString() 20 | } catch (e: PackageManager.NameNotFoundException) { 21 | pkg 22 | } 23 | } 24 | 25 | fun getLabel(context: Context, applicationInfo: ApplicationInfo) : String{ 26 | val pm = context.packageManager 27 | return pm.getApplicationLabel(applicationInfo).toString() 28 | } 29 | 30 | fun getIcon(context: Context, applicationInfo: ApplicationInfo) : Drawable?{ 31 | val pm = context.packageManager 32 | return pm.getApplicationIcon(applicationInfo) 33 | } 34 | 35 | @Synchronized 36 | fun getVersionName(context: Context): String? { 37 | try { 38 | val packageManager = context.packageManager 39 | val packageInfo = packageManager.getPackageInfo( 40 | context.packageName, 0 41 | ) 42 | return packageInfo.versionName 43 | } catch (e: Exception) { 44 | e.printStackTrace() 45 | } 46 | 47 | return null 48 | } 49 | 50 | @Deprecated("Deprecated in Java") 51 | @Synchronized 52 | fun getVersionCode(context: Context): Int { 53 | try { 54 | val packageManager = context.packageManager 55 | val packageInfo = packageManager.getPackageInfo( 56 | context.packageName, 0 57 | ) 58 | return packageInfo.versionCode 59 | } catch (e: Exception) { 60 | e.printStackTrace() 61 | } 62 | return 0 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/utils/Panels.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.utils 2 | 3 | object Panels 4 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/utils/PermissionInterface.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.utils 2 | 3 | interface PermissionInterface { 4 | fun onResult(requestCode: Int, permissions: Array, granted: IntArray) 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/utils/ReportUtils.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.utils 2 | 3 | object ReportUtils { 4 | fun report() { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/utils/SharedPreferenceUtil.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.utils 2 | 3 | import android.content.Context 4 | import io.alcatraz.afkprotect.Constants 5 | 6 | object SharedPreferenceUtil { 7 | private const val FILE_NAME = Constants.MY_PACKAGE_NAME + "_preferences" 8 | fun put(context: Context, key: String, value: Any) { 9 | val sharedPreferences = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE) 10 | val editor = sharedPreferences.edit() 11 | when (value) { 12 | is Int -> editor.putInt(key, value) 13 | is Boolean -> editor.putBoolean(key, value) 14 | is Float -> editor.putFloat(key, value) 15 | is Long -> editor.putLong(key, value) 16 | is String -> editor.putString(key, value) 17 | } 18 | editor.apply() 19 | } 20 | 21 | @Suppress("UNCHECKED_CAST") 22 | fun getPref(context: Context, key: String, defValue: T): T? { 23 | val sharedPreferences = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE) 24 | var value: Any? = null 25 | when (defValue) { 26 | is Int -> value = sharedPreferences.getInt(key, defValue) 27 | is Boolean -> value = sharedPreferences.getBoolean(key, defValue) 28 | is Float -> value = sharedPreferences.getFloat(key, defValue) 29 | is Long -> value = sharedPreferences.getLong(key, defValue) 30 | is String -> value = sharedPreferences.getString(key, defValue) 31 | } 32 | return value as T 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/io/alcatraz/afkprotect/utils/UpdateUtils.kt: -------------------------------------------------------------------------------- 1 | package io.alcatraz.afkprotect.utils 2 | 3 | import java.io.File 4 | 5 | object UpdateUtils { 6 | const val FILE_DEFAULT_EXPIRATION_MILLS = 24 * 3600 * 1000 7 | const val WEATHER_FILE_DEFAULT_EXPIRATION_MILLS = 5 * 60 * 1000 8 | 9 | @JvmOverloads 10 | fun checkFileNeedsUpdate( 11 | dir: String, 12 | mills_to_expire: Long = FILE_DEFAULT_EXPIRATION_MILLS.toLong() 13 | ): Boolean { 14 | val toCheck = File(dir) 15 | return toCheck.lastModified() + mills_to_expire < System.currentTimeMillis() 16 | } 17 | 18 | fun checkUpdate(): Boolean { 19 | return false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/res/anim/layout_fall_down.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/recycler_falldown.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 11 | 16 | 17 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 10 | 11 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_left_back.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 9 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_right_back.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/animator/raise.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/card_boarder.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/common_setup_wizard_illustration_generic_wide.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alcatraz323/afkprotect/fe9bda1c69328abd180cebe58ec84c93dd16130b/app/src/main/res/drawable/common_setup_wizard_illustration_generic_wide.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/common_setup_wizard_illustration_tile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alcatraz323/afkprotect/fe9bda1c69328abd180cebe58ec84c93dd16130b/app/src/main/res/drawable/common_setup_wizard_illustration_tile.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_access_time_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_account_circle_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_alert.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_apps_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_attach_money_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_backspace_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_branding_watermark_gray_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_circle_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_green_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_chevron_left_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_chevron_right_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_close.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_close_red_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_code_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_cog.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_developer_mode_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_edit_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_exit_to_app_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_list_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_help_outline_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_history_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info_outline_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyboard_arrow_down_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyboard_arrow_up_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /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_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 9 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_lock_outline_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_multiline_chart_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_open_in_new_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pause_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_perm_identity_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_play_circle_filled_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_playlist_play_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_refresh_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_refresh_white_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_timelapse_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_tune_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_videocam_off_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_volume_off_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_volume_source.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/wechat_qr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Alcatraz323/afkprotect/fe9bda1c69328abd180cebe58ec84c93dd16130b/app/src/main/res/drawable/wechat_qr.jpg -------------------------------------------------------------------------------- /app/src/main/res/layout-v21/activity_setup_nav.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 19 | 20 | 27 | 28 | 33 | 34 |