init
47
.gitignore
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/navEditor.xml
|
||||||
|
/.idea/assetWizardSettings.xml
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx
|
||||||
|
local.properties
|
||||||
|
/.safedk/dex/android-support-multidex.dex
|
||||||
|
/app/release/baselineProfiles/0/app-release.dm
|
||||||
|
/app/release/baselineProfiles/1/app-release.dm
|
||||||
|
/app/release/AppLock Defender1.0(1).aab
|
||||||
|
/.safedk/list.enc
|
||||||
|
/app/release/output-metadata.json
|
||||||
|
/.safedk/proguard-safedk.pro
|
||||||
|
/.safedk/dex/SafeDKAndroid-6.2.5.dex
|
||||||
|
/.safedk/api/SafeDKAndroid-6.2.5.jar
|
||||||
|
gradle.properties
|
||||||
|
gradlew
|
||||||
|
gradlew.bat
|
||||||
|
.idea/.gitignore
|
||||||
|
.idea/.name
|
||||||
|
.idea/appInsightsSettings.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/dbnavigator.xml
|
||||||
|
.idea/deploymentTargetDropDown.xml
|
||||||
|
.idea/deploymentTargetSelector.xml
|
||||||
|
.idea/gradle.xml
|
||||||
|
.idea/kotlinc.xml
|
||||||
|
.idea/migrations.xml
|
||||||
|
.idea/misc.xml
|
||||||
|
.idea/vcs.xml
|
||||||
|
.safedk/app_sdks.lst
|
||||||
|
.safedk/hashes.safedk
|
||||||
|
.safedk/plugin.properties
|
||||||
|
.safedk/api/SafeDKAndroid-6.2.6.jar
|
||||||
|
.safedk/api/SafeDKAndroid-6.3.1.jar
|
||||||
|
.safedk/dex/SafeDKAndroid-6.3.1.dex
|
||||||
|
app/release/AppLock Defender1.1(2).aab
|
||||||
|
app/release/app-release.apk
|
||||||
1
app/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/build
|
||||||
74
app/build.gradle
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
plugins {
|
||||||
|
alias(libs.plugins.androidApplication)
|
||||||
|
alias(libs.plugins.jetbrainsKotlinAndroid)
|
||||||
|
id("kotlin-kapt")
|
||||||
|
id("com.google.gms.google-services")
|
||||||
|
id("com.google.firebase.crashlytics")
|
||||||
|
id("applovin-quality-service")
|
||||||
|
}
|
||||||
|
|
||||||
|
applovin {
|
||||||
|
apiKey "gaubl3w6OhMaWqmJb15zVNMO8W91OOSTe2fnoftZMmDkQFTnwMdQVdOdPOMwLRbglPnJsKHfqoPl079qleMk96"
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace 'com.kitobochi.softapp.timberlock'
|
||||||
|
compileSdk 34
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.applock.privacy.defender"
|
||||||
|
minSdk 22
|
||||||
|
targetSdk 34
|
||||||
|
versionCode 2
|
||||||
|
versionName "1.1"
|
||||||
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
}
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled true
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
|
||||||
|
debug {
|
||||||
|
minifyEnabled true
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '1.8'
|
||||||
|
}
|
||||||
|
buildFeatures {
|
||||||
|
viewBinding = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
implementation libs.androidx.core.ktx
|
||||||
|
implementation libs.androidx.appcompat
|
||||||
|
implementation libs.material
|
||||||
|
implementation libs.androidx.activity
|
||||||
|
implementation libs.androidx.constraintlayout
|
||||||
|
testImplementation libs.junit
|
||||||
|
androidTestImplementation libs.androidx.junit
|
||||||
|
androidTestImplementation libs.androidx.espresso.core
|
||||||
|
|
||||||
|
kapt 'androidx.room:room-compiler:2.6.1'
|
||||||
|
implementation 'androidx.room:room-runtime:2.6.1'
|
||||||
|
implementation("androidx.room:room-ktx:2.6.1")
|
||||||
|
|
||||||
|
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
|
||||||
|
implementation("com.google.firebase:firebase-analytics-ktx")
|
||||||
|
implementation("com.google.firebase:firebase-crashlytics-ktx")
|
||||||
|
|
||||||
|
implementation("com.applovin:applovin-sdk:+")
|
||||||
|
implementation("com.applovin.mediation:vungle-adapter:+")
|
||||||
|
implementation("com.applovin.mediation:bytedance-adapter:+")
|
||||||
|
implementation("com.applovin.mediation:mintegral-adapter:+")
|
||||||
|
|
||||||
|
}
|
||||||
29
app/google-services.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "36819996956",
|
||||||
|
"project_id": "applock-defender---security",
|
||||||
|
"storage_bucket": "applock-defender---security.appspot.com"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:36819996956:android:63137f1a9ab4d34a37ead9",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "com.applock.privacy.defender"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyBGf4ZJn19sNlDd8U1Qt9L9vOUfyNTlF8I"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
||||||
6
app/info/info.txt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
包名:com.applock.privacy.defender
|
||||||
|
应用名:AppLock Defender
|
||||||
|
|
||||||
|
别名:key_applock_defender
|
||||||
|
key:key_applock_defender
|
||||||
|
password:key123456
|
||||||
BIN
app/info/key_applock_defender.jks
Normal file
BIN
app/info/key_applock_defender_test.jks
Normal file
35
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
# room base
|
||||||
|
-keepclassmembers class * {
|
||||||
|
@androidx.room.Query <methods>;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keepclassmembers class com.kitobochi.softapp.timberlock.db.AppDatabaseManager{
|
||||||
|
public static final java.lang.String DB_NAME;
|
||||||
|
public static final int DB_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
-keep class com.kitobochi.softapp.timberlock.db.AppDatabase { *; }
|
||||||
|
-keep class com.kitobochi.softapp.timberlock.db.AppDao { *; }
|
||||||
|
-keep class com.kitobochi.softapp.timberlock.db.AppEntity { *; }
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock
|
||||||
|
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
fun useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
|
assertEquals("com.kitobochi.softapp.timberlock", appContext.packageName)
|
||||||
|
}
|
||||||
|
}
|
||||||
44
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.PACKAGE_USAGE_STATS"
|
||||||
|
tools:ignore="ProtectedPermissions" />
|
||||||
|
|
||||||
|
<queries>
|
||||||
|
<intent>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent>
|
||||||
|
</queries>
|
||||||
|
|
||||||
|
<application
|
||||||
|
android:name=".App"
|
||||||
|
android:allowBackup="true"
|
||||||
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
|
android:icon="@mipmap/icon_logo"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/icon_logo"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/Theme.TimberLock"
|
||||||
|
tools:targetApi="31">
|
||||||
|
<activity
|
||||||
|
android:name=".ui.activity.StartPageActivity"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name=".ui.activity.MainActivity" />
|
||||||
|
<activity android:name=".ui.activity.SetPwdActivity" />
|
||||||
|
|
||||||
|
<service android:name=".service.AppLockService" />
|
||||||
|
</application>
|
||||||
|
|
||||||
|
|
||||||
|
</manifest>
|
||||||
88
app/src/main/java/com/kitobochi/softapp/timberlock/App.kt
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||||
|
import com.applovin.sdk.AppLovinMediationProvider
|
||||||
|
import com.applovin.sdk.AppLovinSdk
|
||||||
|
import com.applovin.sdk.AppLovinSdkInitializationConfiguration
|
||||||
|
import com.kitobochi.softapp.timberlock.db.AppDatabase
|
||||||
|
import com.kitobochi.softapp.timberlock.db.AppEntity
|
||||||
|
import com.kitobochi.softapp.timberlock.tools.AppListManager
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
|
class App : Application() {
|
||||||
|
private val spName = "share_name"
|
||||||
|
private val PWD_KEY = "locker_pwd"
|
||||||
|
val reqCodeUsage = 1
|
||||||
|
val reqCodeOverlays = 2
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
lateinit var appContext: Context
|
||||||
|
lateinit var sp: SharedPreferences
|
||||||
|
lateinit var SpEditor: SharedPreferences.Editor
|
||||||
|
|
||||||
|
const val ADSDK = "2qIXFPBROAqtuAoW4uQ78MTqJTfXWGurGLpQvE0iae3vmVXLa8SMxnxgdtq9O1GU3qQVRR1EcHhpS74qiyL8CK"
|
||||||
|
const val AD_INIT = "on_success_action"
|
||||||
|
var initOK = false
|
||||||
|
var count = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
appContext = this
|
||||||
|
|
||||||
|
initSp()
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
for (appEntity: AppEntity in AppDatabase.database.getAppDao().findApp()!!) {
|
||||||
|
val isNeedDelete = AppListManager().delUnInstallApp(appContext, appEntity.packageName)
|
||||||
|
if (isNeedDelete) {
|
||||||
|
AppDatabase.database.getAppDao().deleteData(appEntity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val pwd = getPwd()
|
||||||
|
if (pwd.isEmpty()) {
|
||||||
|
AppListManager().getAppList(appContext, false)
|
||||||
|
} else {
|
||||||
|
AppListManager().getAppList(appContext, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
initSDK()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initSDK() {
|
||||||
|
|
||||||
|
val initConfig = AppLovinSdkInitializationConfiguration.builder(ADSDK, this)
|
||||||
|
.setMediationProvider(AppLovinMediationProvider.MAX)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
AppLovinSdk.getInstance(this).initialize(initConfig){
|
||||||
|
initOK = true
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(Intent(AD_INIT))
|
||||||
|
}
|
||||||
|
AppLovinSdk.getInstance(this).settings.setVerboseLogging(true)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun updatePwd(pwd: String) {
|
||||||
|
SpEditor.putString(PWD_KEY, pwd)
|
||||||
|
SpEditor.apply()
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun getPwd(): String {
|
||||||
|
return sp.getString(PWD_KEY, "")!!
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initSp() {
|
||||||
|
sp = App.appContext.getSharedPreferences(spName, Context.MODE_PRIVATE)
|
||||||
|
SpEditor = sp.edit()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ad
|
||||||
|
|
||||||
|
import com.applovin.mediation.MaxAd
|
||||||
|
|
||||||
|
interface AdListener {
|
||||||
|
fun onFail(ad: MaxAd)
|
||||||
|
fun onSuccess()
|
||||||
|
fun onHidden()
|
||||||
|
}
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ad
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import com.applovin.mediation.MaxAd
|
||||||
|
import com.applovin.mediation.MaxAdListener
|
||||||
|
import com.applovin.mediation.MaxError
|
||||||
|
import com.applovin.mediation.ads.MaxInterstitialAd
|
||||||
|
import com.kitobochi.softapp.timberlock.App
|
||||||
|
|
||||||
|
object AdManager {
|
||||||
|
|
||||||
|
private val one_AD = "02d8ee636a579373"
|
||||||
|
private val two_Ad = "02d8ee636a579373"
|
||||||
|
private val three_ad = "0b004d33e636f7f8"
|
||||||
|
|
||||||
|
private val list: MutableList<MaxInterstitialAd> = mutableListOf()
|
||||||
|
|
||||||
|
fun onCache(list: List<MaxInterstitialAd>): MaxInterstitialAd? {
|
||||||
|
list.shuffled()
|
||||||
|
for (ad in list) {
|
||||||
|
if (ad.isReady) {
|
||||||
|
return ad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun adLoad(): List<MaxInterstitialAd> {
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
val ad_two = MaxInterstitialAd(two_Ad, App.appContext)
|
||||||
|
val ad_one = MaxInterstitialAd(one_AD, App.appContext)
|
||||||
|
val ad_three = MaxInterstitialAd(three_ad, App.appContext)
|
||||||
|
ad_two.loadAd()
|
||||||
|
ad_one.loadAd()
|
||||||
|
ad_three.loadAd()
|
||||||
|
|
||||||
|
list.add(ad_one)
|
||||||
|
list.add(ad_two)
|
||||||
|
list.add(ad_three)
|
||||||
|
}
|
||||||
|
for (ad: MaxInterstitialAd in list) {
|
||||||
|
if (!ad.isReady) {
|
||||||
|
ad.loadAd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setAdListener(ad: MaxInterstitialAd, listener: AdListener) {
|
||||||
|
ad.setListener(object : MaxAdListener {
|
||||||
|
override fun onAdLoaded(p0: MaxAd) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAdDisplayed(p0: MaxAd) {
|
||||||
|
listener.onSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAdHidden(p0: MaxAd) {
|
||||||
|
listener.onHidden()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAdClicked(p0: MaxAd) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAdLoadFailed(p0: String, p1: MaxError) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onAdDisplayFailed(p0: MaxAd, p1: MaxError) {
|
||||||
|
listener.onFail(p0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ad
|
||||||
|
|
||||||
|
interface AdMsgListener {
|
||||||
|
fun msg(msg: String)
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.db
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
|
import androidx.room.Delete
|
||||||
|
import androidx.room.Insert
|
||||||
|
import androidx.room.OnConflictStrategy
|
||||||
|
import androidx.room.Query
|
||||||
|
import androidx.room.Update
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
interface AppDao {
|
||||||
|
@Delete
|
||||||
|
fun deleteData(dataApp: AppEntity)
|
||||||
|
|
||||||
|
@Query("select * from t_data_app where packageName=:packName")
|
||||||
|
fun findByPackName(packName: String): AppEntity?
|
||||||
|
|
||||||
|
@Query("select * from t_data_app where isSyStem=:system AND isRecommend = :recommend")
|
||||||
|
fun findByType(system: Boolean, recommend: Boolean): List<AppEntity>?
|
||||||
|
|
||||||
|
@Update
|
||||||
|
fun updateData(dataApp: AppEntity)
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
||||||
|
fun insertData(dataApp: AppEntity)
|
||||||
|
|
||||||
|
@Query("select * from t_data_app")
|
||||||
|
fun findApp(): List<AppEntity>?
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.db
|
||||||
|
|
||||||
|
import androidx.room.Database
|
||||||
|
import androidx.room.Room
|
||||||
|
import androidx.room.RoomDatabase
|
||||||
|
import com.kitobochi.softapp.timberlock.App
|
||||||
|
|
||||||
|
@Database(
|
||||||
|
entities = [AppEntity::class],
|
||||||
|
version = AppDatabaseManager.DB_VERSION,
|
||||||
|
exportSchema = false
|
||||||
|
)
|
||||||
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
companion object {
|
||||||
|
val database: AppDatabase by lazy {
|
||||||
|
getInstance()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getInstance(): AppDatabase {
|
||||||
|
return Room.databaseBuilder(
|
||||||
|
App.appContext, AppDatabase::class.java, AppDatabaseManager.DB_NAME
|
||||||
|
).build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun getAppDao(): AppDao
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.db
|
||||||
|
|
||||||
|
object AppDatabaseManager {
|
||||||
|
const val TABLE_NAME = "t_data_app"
|
||||||
|
const val DB_VERSION = 1
|
||||||
|
const val DB_NAME = "app_db"
|
||||||
|
}
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.db
|
||||||
|
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.Index
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
|
||||||
|
@Entity(tableName = AppDatabaseManager.TABLE_NAME, indices = [Index(value = ["packageName"], unique = true)])
|
||||||
|
data class AppEntity(
|
||||||
|
@PrimaryKey(autoGenerate = true) var id: Int = 0,
|
||||||
|
var packageName: String = "",
|
||||||
|
var appName: String = "",
|
||||||
|
var isLock: Boolean = false,
|
||||||
|
var isSyStem: Boolean = true,
|
||||||
|
var isRecommend: Boolean = false
|
||||||
|
)
|
||||||
@ -0,0 +1,75 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.service
|
||||||
|
|
||||||
|
import android.app.IntentService
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import android.util.Log
|
||||||
|
import com.kitobochi.softapp.timberlock.db.AppDatabase
|
||||||
|
import com.kitobochi.softapp.timberlock.tools.LockManager
|
||||||
|
import com.kitobochi.softapp.timberlock.tools.LockServiceManager
|
||||||
|
import java.util.Objects
|
||||||
|
|
||||||
|
|
||||||
|
class AppLockService(name: String? = "") : IntentService(name) {
|
||||||
|
|
||||||
|
|
||||||
|
private lateinit var instance: LockManager
|
||||||
|
|
||||||
|
private var lastLockPackName = ""
|
||||||
|
|
||||||
|
override fun onHandleIntent(intent: Intent?) {
|
||||||
|
instance = LockManager(this)
|
||||||
|
val isCheckTop: Boolean = true
|
||||||
|
while (isCheckTop) {
|
||||||
|
|
||||||
|
val packageName = LockServiceManager().checkUsageStats(this)
|
||||||
|
|
||||||
|
if (Objects.equals(packageName, "")) {
|
||||||
|
// Log.d("-------", "continue1")
|
||||||
|
// Log.d("-------", packageName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val appEntity = AppDatabase.database.getAppDao().findByPackName(packageName)
|
||||||
|
if (appEntity == null) {
|
||||||
|
val mainHandler = Handler(Looper.getMainLooper())
|
||||||
|
mainHandler.post(Runnable {
|
||||||
|
instance.unLock()
|
||||||
|
})
|
||||||
|
lastLockPackName = packageName
|
||||||
|
// Log.d("-------", "continue2")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Objects.equals(packageName, lastLockPackName)) {
|
||||||
|
// Log.d("-------", "continue3")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (appEntity.isLock) {
|
||||||
|
if (!Objects.equals(packageName, lastLockPackName)) {
|
||||||
|
|
||||||
|
val mainHandler = Handler(Looper.getMainLooper())
|
||||||
|
mainHandler.post(Runnable {
|
||||||
|
instance.showLockView()
|
||||||
|
})
|
||||||
|
|
||||||
|
// Log.d("-------", "continue4")
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
|
||||||
|
val mainHandler = Handler(Looper.getMainLooper())
|
||||||
|
mainHandler.post(Runnable {
|
||||||
|
instance.unLock()
|
||||||
|
})
|
||||||
|
// Log.d("-------", "continue5")
|
||||||
|
}
|
||||||
|
lastLockPackName = packageName
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,113 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.tools
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.ApplicationInfo
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import com.kitobochi.softapp.timberlock.db.AppDatabase
|
||||||
|
import com.kitobochi.softapp.timberlock.db.AppEntity
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.util.Objects
|
||||||
|
|
||||||
|
class AppListManager {
|
||||||
|
private fun addDb(list: List<AppEntity>, isSystem: Boolean, isUpdate: Boolean) {
|
||||||
|
for (i in 0 until list.size) {
|
||||||
|
|
||||||
|
val appEntity = list[i]
|
||||||
|
appEntity.isSyStem = isSystem
|
||||||
|
if (isUpdate) {
|
||||||
|
val appEntity1 = AppDatabase.database.getAppDao().findByPackName(appEntity.packageName)
|
||||||
|
if (appEntity1 == null) {
|
||||||
|
AppDatabase.database.getAppDao().insertData(appEntity)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
appEntity.isRecommend = false
|
||||||
|
AppDatabase.database.getAppDao().insertData(appEntity)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkSystemApp(context: Context, packageName: String): Boolean {
|
||||||
|
try {
|
||||||
|
val info = context.packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES)
|
||||||
|
if (info.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun removeDuplApp(list: List<AppEntity>): List<AppEntity> {
|
||||||
|
val hashMap: HashMap<String, AppEntity> = hashMapOf()
|
||||||
|
for (appEntity: AppEntity in list) {
|
||||||
|
if (!hashMap.containsKey(appEntity.packageName)) {
|
||||||
|
hashMap.put(appEntity.packageName, appEntity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val appEntityList: MutableList<AppEntity> = mutableListOf()
|
||||||
|
for (entry in hashMap.entries) {
|
||||||
|
appEntityList.add(entry.value)
|
||||||
|
}
|
||||||
|
return appEntityList
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun getAppList(context: Context, isUpdate: Boolean): List<AppEntity> {
|
||||||
|
val packageManager = context.packageManager
|
||||||
|
val intent = Intent(Intent.ACTION_MAIN, null)
|
||||||
|
intent.addCategory(Intent.CATEGORY_LAUNCHER)
|
||||||
|
val resolveInfos = packageManager.queryIntentActivities(intent, 0)
|
||||||
|
val systemAppList: MutableList<AppEntity> = mutableListOf()
|
||||||
|
val threeAppList: MutableList<AppEntity> = mutableListOf()
|
||||||
|
for (i in 0 until resolveInfos.size) {
|
||||||
|
val resolveInfo = resolveInfos[i]
|
||||||
|
val packageName = resolveInfo.activityInfo.packageName
|
||||||
|
if (Objects.equals(packageName, context.packageName)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val appInfo: ApplicationInfo
|
||||||
|
try {
|
||||||
|
val applicationInfo =
|
||||||
|
packageManager.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES)
|
||||||
|
val appName = packageManager.getApplicationLabel(applicationInfo).toString()
|
||||||
|
val appEntity = AppEntity()
|
||||||
|
appEntity.packageName = packageName
|
||||||
|
appEntity.appName = appName
|
||||||
|
val isSystemApp = checkSystemApp(context, packageName)
|
||||||
|
if (isSystemApp) {
|
||||||
|
appEntity.isSyStem = true
|
||||||
|
systemAppList.add(appEntity)
|
||||||
|
} else {
|
||||||
|
appEntity.isSyStem = false
|
||||||
|
threeAppList.add(appEntity)
|
||||||
|
}
|
||||||
|
} catch (nameNotFoundException: PackageManager.NameNotFoundException) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val uniqueSystemList: List<AppEntity> = removeDuplApp(systemAppList)
|
||||||
|
val uniqueThreeList: List<AppEntity> = removeDuplApp(threeAppList)
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
addDb(uniqueSystemList, true, isUpdate)
|
||||||
|
addDb(uniqueThreeList, false, isUpdate)
|
||||||
|
}
|
||||||
|
return uniqueThreeList
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun delUnInstallApp(context: Context, packName: String): Boolean {
|
||||||
|
val packageManager = context.packageManager
|
||||||
|
return try {
|
||||||
|
packageManager.getApplicationInfo(packName, PackageManager.GET_UNINSTALLED_PACKAGES)
|
||||||
|
false
|
||||||
|
} catch (nameNotFoundException: PackageManager.NameNotFoundException) {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.tools
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.annotation.ColorRes
|
||||||
|
import androidx.annotation.DimenRes
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
|
||||||
|
class CustomViewTools {
|
||||||
|
fun getPx(context: Context, @DimenRes id: Int): Float {
|
||||||
|
return context.resources.getDimension(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getColor(context: Context?, @ColorRes id: Int): Int {
|
||||||
|
return ContextCompat.getColor(context!!, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.tools
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.PixelFormat
|
||||||
|
import android.graphics.Point
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.DisplayMetrics
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.WindowManager
|
||||||
|
import com.kitobochi.softapp.timberlock.App
|
||||||
|
import com.kitobochi.softapp.timberlock.R
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.customview.InputStateView
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.customview.KeyboardView
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.customview.ListenerLock
|
||||||
|
import java.util.Objects
|
||||||
|
|
||||||
|
class LockManager(context: Context) {
|
||||||
|
|
||||||
|
private lateinit var mContext: Context
|
||||||
|
private lateinit var mView: View
|
||||||
|
private lateinit var lockView: KeyboardView
|
||||||
|
private lateinit var windowManager: WindowManager
|
||||||
|
private lateinit var layoutParams: WindowManager.LayoutParams
|
||||||
|
lateinit var lockManager: LockManager
|
||||||
|
|
||||||
|
init {
|
||||||
|
mContext = context
|
||||||
|
mView = LayoutInflater.from(context).inflate(R.layout.view_lock, null, false)
|
||||||
|
|
||||||
|
windowManager = mContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
|
||||||
|
|
||||||
|
initView()
|
||||||
|
|
||||||
|
val myState = mView.findViewById<InputStateView>(R.id.indicator_dots)
|
||||||
|
|
||||||
|
lockView = mView.findViewById(R.id.pin_lock_view)
|
||||||
|
lockView.attachIndicatorDots(myState)
|
||||||
|
lockView.setPinLockListener(object : ListenerLock {
|
||||||
|
override fun onInPutComplete(pin: String) {
|
||||||
|
|
||||||
|
val pwd = App().getPwd()
|
||||||
|
if (Objects.equals(pin, pin)) {
|
||||||
|
unLock()
|
||||||
|
} else {
|
||||||
|
lockView.resetPinLockView()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unLock() {
|
||||||
|
try {
|
||||||
|
windowManager.removeView(mView)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showLockView() {
|
||||||
|
lockView.resetPinLockView()
|
||||||
|
windowManager.addView(mView, layoutParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initView() {
|
||||||
|
var type = 0
|
||||||
|
type = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
|
||||||
|
} else {
|
||||||
|
WindowManager.LayoutParams.TYPE_PHONE
|
||||||
|
}
|
||||||
|
val displayMetrics = DisplayMetrics()
|
||||||
|
windowManager.getDefaultDisplay().getMetrics(displayMetrics)
|
||||||
|
layoutParams = WindowManager.LayoutParams()
|
||||||
|
layoutParams.type = type
|
||||||
|
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
|
||||||
|
layoutParams.format = PixelFormat.RGBA_8888
|
||||||
|
layoutParams.flags =
|
||||||
|
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_FULLSCREEN or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
||||||
|
|
||||||
|
layoutParams.gravity = Gravity.START or Gravity.TOP
|
||||||
|
|
||||||
|
val screenSize = Point()
|
||||||
|
windowManager.getDefaultDisplay().getRealSize(screenSize)
|
||||||
|
layoutParams.width = screenSize.x
|
||||||
|
layoutParams.height = screenSize.y
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.tools
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.app.AppOpsManager
|
||||||
|
import android.app.usage.UsageEvents
|
||||||
|
import android.app.usage.UsageStatsManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Process
|
||||||
|
import android.provider.Settings
|
||||||
|
import android.text.TextUtils
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
|
||||||
|
class LockServiceManager {
|
||||||
|
fun checkUsageStats(context: Context): String {
|
||||||
|
val sUsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
|
||||||
|
val endTime = System.currentTimeMillis()
|
||||||
|
val beginTime = endTime - 10000
|
||||||
|
var result = ""
|
||||||
|
val event = UsageEvents.Event()
|
||||||
|
val usageEvents = sUsageStatsManager.queryEvents(beginTime, endTime)
|
||||||
|
while (usageEvents.hasNextEvent()) {
|
||||||
|
usageEvents.getNextEvent(event)
|
||||||
|
if (event.eventType == UsageEvents.Event.MOVE_TO_FOREGROUND) {
|
||||||
|
result = event.packageName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return if (!TextUtils.isEmpty(result)) {
|
||||||
|
result
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkPermission(context: Context): Boolean {
|
||||||
|
val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
|
||||||
|
var mode = 0
|
||||||
|
mode = appOps.checkOpNoThrow("android:get_usage_stats", Process.myUid(), context.packageName)
|
||||||
|
return mode == AppOpsManager.MODE_ALLOWED
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
fun getCanDrawOverlays(context: Context?): Boolean {
|
||||||
|
return Settings.canDrawOverlays(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toSetUsagePermission(context: Activity, requestCode: Int) {
|
||||||
|
val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
|
||||||
|
// Uri uri = Uri.fromParts("package", context.getPackageName(), null);
|
||||||
|
// intent.setData(uri);
|
||||||
|
context.startActivityForResult(intent, requestCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun goDrawOverlays(activity: Activity, requestCode: Int) {
|
||||||
|
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
|
||||||
|
//8.0
|
||||||
|
} else {
|
||||||
|
// 6.0、7.0、9.0
|
||||||
|
val uri = Uri.fromParts("package", activity.packageName, null)
|
||||||
|
intent.setData(uri)
|
||||||
|
// intent.setData(Uri.parse("package:" + activity.getPackageName()));
|
||||||
|
}
|
||||||
|
activity.startActivityForResult(intent, requestCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.activity
|
||||||
|
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
|
||||||
|
abstract class BaseActivity : AppCompatActivity() {
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
setContentView(getActivityView())
|
||||||
|
initView()
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun initView() {
|
||||||
|
initStatusBar()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun getActivityView(): View
|
||||||
|
|
||||||
|
private fun initStatusBar() {
|
||||||
|
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
// window.decorView.systemUiVisibility =
|
||||||
|
// (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE) or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
|
||||||
|
// window.statusBarColor = Color.TRANSPARENT
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
|
window.decorView.systemUiVisibility =
|
||||||
|
(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
|
||||||
|
window.statusBarColor = Color.TRANSPARENT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,195 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.activity
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import androidx.fragment.app.FragmentStatePagerAdapter
|
||||||
|
import androidx.viewpager.widget.ViewPager
|
||||||
|
import com.google.android.material.tabs.TabLayout
|
||||||
|
import com.kitobochi.softapp.timberlock.App
|
||||||
|
import com.kitobochi.softapp.timberlock.R
|
||||||
|
import com.kitobochi.softapp.timberlock.databinding.ActivityMainBinding
|
||||||
|
import com.kitobochi.softapp.timberlock.databinding.ViewTabBinding
|
||||||
|
import com.kitobochi.softapp.timberlock.service.AppLockService
|
||||||
|
import com.kitobochi.softapp.timberlock.tools.LockServiceManager
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.customview.DialogPer
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.customview.onPermssionListener
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.fragment.AppListFragment
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.fragment.SettingFragment
|
||||||
|
|
||||||
|
class MainActivity : BaseActivity(), onPermssionListener {
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityMainBinding
|
||||||
|
private lateinit var dialogPer: DialogPer
|
||||||
|
private var fragmentList: ArrayList<Fragment> = arrayListOf()
|
||||||
|
|
||||||
|
override fun getActivityView(): View {
|
||||||
|
binding = ActivityMainBinding.inflate(layoutInflater);
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
override fun initView() {
|
||||||
|
super.initView()
|
||||||
|
initTabLayout()
|
||||||
|
initViewPager()
|
||||||
|
startPermission()
|
||||||
|
startService(Intent(this, AppLockService::class.java))
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
private fun checkPermission(): Boolean {
|
||||||
|
val b: Boolean = LockServiceManager().checkPermission(this)
|
||||||
|
val canDrawOverlays: Boolean = LockServiceManager().getCanDrawOverlays(this)
|
||||||
|
return b && canDrawOverlays
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
private fun startPermission() {
|
||||||
|
if (!checkPermission()) {
|
||||||
|
dialogPer = DialogPer.newInstance()
|
||||||
|
dialogPer.setListener(this)
|
||||||
|
dialogPer.show(supportFragmentManager, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initViewPager() {
|
||||||
|
|
||||||
|
val titles = arrayOf<String>(
|
||||||
|
getString(R.string.text_system),
|
||||||
|
getString(R.string.text_third),
|
||||||
|
getString(R.string.text_setting)
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.mainViewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
|
||||||
|
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPageSelected(position: Int) {
|
||||||
|
binding.mainTab.getTabAt(position)?.select()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPageScrollStateChanged(state: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
binding.mainViewPager.adapter = object : FragmentStatePagerAdapter(supportFragmentManager) {
|
||||||
|
override fun getCount(): Int {
|
||||||
|
return fragmentList.size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItem(position: Int): Fragment {
|
||||||
|
return fragmentList[position]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPageTitle(position: Int): CharSequence {
|
||||||
|
return titles[position]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initTabLayout() {
|
||||||
|
fragmentList.add(AppListFragment(true))
|
||||||
|
fragmentList.add(AppListFragment(false))
|
||||||
|
fragmentList.add(SettingFragment())
|
||||||
|
|
||||||
|
val titles = arrayOf<String>(
|
||||||
|
getString(R.string.text_system),
|
||||||
|
getString(R.string.text_third),
|
||||||
|
getString(R.string.text_setting)
|
||||||
|
)
|
||||||
|
|
||||||
|
for (i in 0 until fragmentList.size) {
|
||||||
|
val newTab = binding.mainTab.newTab()
|
||||||
|
val viewTabBinding = ViewTabBinding.inflate(layoutInflater)
|
||||||
|
viewTabBinding.tvTabtext.text = titles[i]
|
||||||
|
newTab.customView = viewTabBinding.root
|
||||||
|
binding.mainTab.addTab(newTab)
|
||||||
|
}
|
||||||
|
|
||||||
|
val tabAt = binding.mainTab.getTabAt(1)
|
||||||
|
val tabAt2 = binding.mainTab.getTabAt(2)
|
||||||
|
if (tabAt != null && tabAt2 != null) {
|
||||||
|
updateTab(tabAt, false)
|
||||||
|
updateTab(tabAt2, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.mainTab.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||||
|
override fun onTabSelected(p0: TabLayout.Tab?) {
|
||||||
|
if (p0 != null) {
|
||||||
|
updateTab(p0, true)
|
||||||
|
binding.mainViewPager.setCurrentItem(p0.position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabUnselected(p0: TabLayout.Tab?) {
|
||||||
|
p0?.let { updateTab(it, false) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTabReselected(p0: TabLayout.Tab?) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateTab(tabAt: TabLayout.Tab, b: Boolean) {
|
||||||
|
val customView = tabAt.customView ?: return
|
||||||
|
val textView = customView.findViewById<TextView>(R.id.tv_tabtext)
|
||||||
|
textView.isSelected = b
|
||||||
|
if (b) {
|
||||||
|
textView.background = ContextCompat.getDrawable(this@MainActivity, R.drawable.shape_yellow_r30)
|
||||||
|
} else {
|
||||||
|
textView.background = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
override fun onToSetting() {
|
||||||
|
val b: Boolean = LockServiceManager().checkPermission(this)
|
||||||
|
val canDrawOverlays: Boolean = LockServiceManager().getCanDrawOverlays(this)
|
||||||
|
if (!b) {
|
||||||
|
LockServiceManager().toSetUsagePermission(this@MainActivity, App().reqCodeUsage)
|
||||||
|
} else {
|
||||||
|
if (!canDrawOverlays) {
|
||||||
|
LockServiceManager().goDrawOverlays(this, App().reqCodeOverlays)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated("Deprecated in Java")
|
||||||
|
@RequiresApi(Build.VERSION_CODES.M)
|
||||||
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data)
|
||||||
|
if (requestCode == App().reqCodeUsage) {
|
||||||
|
if (checkPermission()) {
|
||||||
|
dialogPer.dismiss()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val canDrawOverlays = LockServiceManager().getCanDrawOverlays(this)
|
||||||
|
if (!canDrawOverlays) {
|
||||||
|
LockServiceManager().goDrawOverlays(this, App().reqCodeOverlays)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requestCode == App().reqCodeOverlays) {
|
||||||
|
if (checkPermission()) {
|
||||||
|
|
||||||
|
Log.d("---------","-------dismiss---")
|
||||||
|
dialogPer.dismiss()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, getString(R.string.no_permission), Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,157 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.activity
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.os.CountDownTimer
|
||||||
|
import android.text.Editable
|
||||||
|
import android.text.TextWatcher
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.EditText
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||||
|
import com.applovin.mediation.MaxAd
|
||||||
|
import com.applovin.mediation.ads.MaxInterstitialAd
|
||||||
|
import com.kitobochi.softapp.timberlock.App
|
||||||
|
import com.kitobochi.softapp.timberlock.R
|
||||||
|
import com.kitobochi.softapp.timberlock.ad.AdListener
|
||||||
|
import com.kitobochi.softapp.timberlock.ad.AdManager
|
||||||
|
import com.kitobochi.softapp.timberlock.databinding.ActivitySetpwdBinding
|
||||||
|
|
||||||
|
class SetPwdActivity : BaseActivity(), View.OnClickListener {
|
||||||
|
|
||||||
|
private lateinit var binding: ActivitySetpwdBinding
|
||||||
|
private var isShowAd: Boolean = false
|
||||||
|
private val IS_SHOW_AD = "IS_SHOW_AD"
|
||||||
|
|
||||||
|
private val countTime: Long = 12000
|
||||||
|
private lateinit var adList: List<MaxInterstitialAd>
|
||||||
|
private lateinit var timer: CountDownTimer
|
||||||
|
|
||||||
|
override fun getActivityView(): View {
|
||||||
|
binding = ActivitySetpwdBinding.inflate(layoutInflater)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
super.initView()
|
||||||
|
initAd()
|
||||||
|
initButton()
|
||||||
|
initInput()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initAd() {
|
||||||
|
isShowAd = intent.getBooleanExtra(IS_SHOW_AD, false)
|
||||||
|
|
||||||
|
timer = object : CountDownTimer(countTime, 200) {
|
||||||
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
|
if (isShowAd) {
|
||||||
|
startShowAd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
override fun onFinish() {
|
||||||
|
if (isShowAd) {
|
||||||
|
startShowAd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startAd()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startAd() {
|
||||||
|
if (!App.initOK) {
|
||||||
|
LocalBroadcastManager.getInstance(this).registerReceiver(object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
loadMyAdAndStart()
|
||||||
|
Log.d("------------", "------------1sucess")
|
||||||
|
}
|
||||||
|
}, IntentFilter(App.AD_INIT))
|
||||||
|
} else {
|
||||||
|
loadMyAdAndStart()
|
||||||
|
Log.d("------------", "------------2sucess")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadMyAdAndStart() {
|
||||||
|
adList = AdManager.adLoad()
|
||||||
|
timer.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startShowAd() {
|
||||||
|
val checkCacheAd = AdManager.onCache(adList)
|
||||||
|
if (checkCacheAd == null) {
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
AdManager.setAdListener(checkCacheAd, object : AdListener {
|
||||||
|
override fun onFail(ad: MaxAd) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSuccess() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onHidden() {
|
||||||
|
checkCacheAd.loadAd()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
checkCacheAd.showAd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initInput() {
|
||||||
|
for (i in 0 until binding.layoutPwd.childCount) {
|
||||||
|
val editText = binding.layoutPwd.getChildAt(i) as EditText
|
||||||
|
var editNext: EditText? = null
|
||||||
|
if ((i + 1) < binding.layoutPwd.childCount) {
|
||||||
|
editNext = binding.layoutPwd.getChildAt(i + 1) as EditText
|
||||||
|
}
|
||||||
|
val finalEditText = editNext
|
||||||
|
editText.addTextChangedListener(object : TextWatcher {
|
||||||
|
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun afterTextChanged(s: Editable?) {
|
||||||
|
finalEditText?.requestFocus()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initButton() {
|
||||||
|
binding.pwdBack.setOnClickListener(this)
|
||||||
|
binding.pwdOk.setOnClickListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View?) {
|
||||||
|
when (v) {
|
||||||
|
binding.pwdOk -> {
|
||||||
|
val stringBuilder = StringBuilder()
|
||||||
|
stringBuilder.append(binding.et1.text.toString())
|
||||||
|
stringBuilder.append(binding.et2.text.toString())
|
||||||
|
stringBuilder.append(binding.et3.text.toString())
|
||||||
|
stringBuilder.append(binding.et4.text.toString())
|
||||||
|
if (stringBuilder.length == 4) {
|
||||||
|
App().updatePwd(stringBuilder.toString())
|
||||||
|
Toast.makeText(this@SetPwdActivity, getString(R.string.pwd_success), Toast.LENGTH_SHORT).show()
|
||||||
|
val intent = Intent(this@SetPwdActivity, MainActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this@SetPwdActivity, getString(R.string.pwd_err), Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.pwdBack -> {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,127 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.activity
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.os.CountDownTimer
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||||
|
import com.applovin.mediation.MaxAd
|
||||||
|
import com.applovin.mediation.ads.MaxInterstitialAd
|
||||||
|
import com.kitobochi.softapp.timberlock.App
|
||||||
|
import com.kitobochi.softapp.timberlock.ad.AdListener
|
||||||
|
import com.kitobochi.softapp.timberlock.ad.AdManager
|
||||||
|
import com.kitobochi.softapp.timberlock.databinding.ActivityStartBinding
|
||||||
|
import com.vungle.ads.Ad
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class StartPageActivity : BaseActivity() {
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityStartBinding
|
||||||
|
|
||||||
|
// private val coroutineScope = CoroutineScope(Dispatchers.Main)
|
||||||
|
private val countTime: Long = 12000
|
||||||
|
|
||||||
|
private val IS_SHOW_AD = "IS_SHOW_AD"
|
||||||
|
|
||||||
|
|
||||||
|
private lateinit var adList: List<MaxInterstitialAd>
|
||||||
|
private lateinit var timer: CountDownTimer
|
||||||
|
private var needShow = true
|
||||||
|
|
||||||
|
override fun getActivityView(): View {
|
||||||
|
binding = ActivityStartBinding.inflate(layoutInflater)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
super.initView()
|
||||||
|
Log.d("start-ad", "onCreate")
|
||||||
|
|
||||||
|
timer = object : CountDownTimer(countTime, 200) {
|
||||||
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
|
if (needShow) {
|
||||||
|
startShowAd {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFinish() {
|
||||||
|
if (needShow) {
|
||||||
|
startShowAd {
|
||||||
|
startMainActivity()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startAd()
|
||||||
|
// startMainActivity()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startAd() {
|
||||||
|
if (!App.initOK) {
|
||||||
|
LocalBroadcastManager.getInstance(this).registerReceiver(object : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context?, intent: Intent?) {
|
||||||
|
loadMyAdAndStart()
|
||||||
|
Log.d("------------", "------------1sucess")
|
||||||
|
}
|
||||||
|
}, IntentFilter(App.AD_INIT))
|
||||||
|
} else {
|
||||||
|
loadMyAdAndStart()
|
||||||
|
Log.d("------------", "------------2sucess")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadMyAdAndStart() {
|
||||||
|
adList = AdManager.adLoad()
|
||||||
|
timer.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startShowAd(action: () -> Unit) {
|
||||||
|
val checkCacheAd = AdManager.onCache(adList)
|
||||||
|
if (checkCacheAd == null) {
|
||||||
|
action.invoke()
|
||||||
|
} else {
|
||||||
|
needShow = false
|
||||||
|
AdManager.setAdListener(checkCacheAd, object : AdListener {
|
||||||
|
override fun onFail(ad: MaxAd) {
|
||||||
|
startMainActivity()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSuccess() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onHidden() {
|
||||||
|
startMainActivity()
|
||||||
|
checkCacheAd.loadAd()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
checkCacheAd.showAd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startMainActivity() {
|
||||||
|
|
||||||
|
if (App().getPwd().isEmpty()) {
|
||||||
|
val intent = Intent(this, SetPwdActivity::class.java)
|
||||||
|
intent.putExtra(IS_SHOW_AD, false)
|
||||||
|
startActivity(intent)
|
||||||
|
} else {
|
||||||
|
val intent = Intent(this, MainActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
timer.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,131 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.adapter
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.CompoundButton
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.widget.SwitchCompat
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.applovin.mediation.MaxAd
|
||||||
|
import com.applovin.mediation.ads.MaxInterstitialAd
|
||||||
|
import com.kitobochi.softapp.timberlock.App
|
||||||
|
import com.kitobochi.softapp.timberlock.R
|
||||||
|
import com.kitobochi.softapp.timberlock.ad.AdListener
|
||||||
|
import com.kitobochi.softapp.timberlock.ad.AdManager
|
||||||
|
import com.kitobochi.softapp.timberlock.ad.AdMsgListener
|
||||||
|
import com.kitobochi.softapp.timberlock.db.AppDatabase
|
||||||
|
import com.kitobochi.softapp.timberlock.db.AppEntity
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class AppListAdapter(
|
||||||
|
context: Context,
|
||||||
|
private val msgListener: AdMsgListener
|
||||||
|
) : RecyclerView.Adapter<AppListAdapter.AppListVH>() {
|
||||||
|
|
||||||
|
private val mContext: Context = context
|
||||||
|
|
||||||
|
private val packageManager = context.packageManager
|
||||||
|
|
||||||
|
private var list: List<AppEntity> = mutableListOf()
|
||||||
|
|
||||||
|
public fun updateSystemApp(infoList: List<AppEntity>) {
|
||||||
|
list = infoList
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class AppListVH(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
val imageView = itemView.findViewById<ImageView>(R.id.item_logo)
|
||||||
|
val textView = itemView.findViewById<TextView>(R.id.item_name)
|
||||||
|
val switchCompat = itemView.findViewById<SwitchCompat>(R.id.app_switch)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppListVH {
|
||||||
|
return AppListVH(LayoutInflater.from(parent.context).inflate(R.layout.item_app, parent, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return list.size
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getAppLog(packageName: String): Drawable {
|
||||||
|
val applicationInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES)
|
||||||
|
return packageManager.getApplicationIcon(applicationInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: AppListVH, position: Int) {
|
||||||
|
holder.switchCompat.setOnCheckedChangeListener(null)
|
||||||
|
val appEntity = list[position]
|
||||||
|
val appName = appEntity.appName
|
||||||
|
val lock = appEntity.isLock
|
||||||
|
holder.switchCompat.isChecked = lock
|
||||||
|
holder.switchCompat.setOnCheckedChangeListener(
|
||||||
|
CompoundButton.OnCheckedChangeListener
|
||||||
|
{ _: CompoundButton, isChecked: Boolean ->
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
appEntity.isLock = isChecked
|
||||||
|
AppDatabase.database.getAppDao().updateData(dataApp = appEntity)
|
||||||
|
}
|
||||||
|
var format: String
|
||||||
|
if (isChecked) {
|
||||||
|
format = String.format(mContext.getString(R.string.text_locked), appName)
|
||||||
|
} else {
|
||||||
|
format = String.format(mContext.getString(R.string.text_unlocked), appName)
|
||||||
|
}
|
||||||
|
Toast.makeText(mContext, format, Toast.LENGTH_SHORT).show()
|
||||||
|
|
||||||
|
|
||||||
|
if (App.count % 5 == 0) {
|
||||||
|
showAd({ showPopup(format) }, format)
|
||||||
|
}
|
||||||
|
App.count++
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
val appLog = getAppLog(appEntity.packageName)
|
||||||
|
holder.imageView.setImageDrawable(appLog)
|
||||||
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
|
|
||||||
|
}
|
||||||
|
holder.textView.text = appName
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showAd(action: () -> Unit, msg: String) {
|
||||||
|
val adList = AdManager.adLoad()
|
||||||
|
val checkCacheAd = AdManager.onCache(adList)
|
||||||
|
if (checkCacheAd == null) {
|
||||||
|
action.invoke()
|
||||||
|
} else {
|
||||||
|
AdManager.setAdListener(checkCacheAd, object : AdListener {
|
||||||
|
override fun onFail(ad: MaxAd) {
|
||||||
|
showPopup(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSuccess() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onHidden() {
|
||||||
|
showPopup(msg)
|
||||||
|
checkCacheAd.loadAd()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
checkCacheAd.showAd()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showPopup(msg: String) {
|
||||||
|
msgListener.msg(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,154 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.adapter
|
||||||
|
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Button
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.kitobochi.softapp.timberlock.R
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.customview.CustomBundle
|
||||||
|
|
||||||
|
|
||||||
|
class KeyboardAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
private var mOnNumberListener: OnNumberClickListener? = null
|
||||||
|
private var mOnDeleteListener: OnDeleteClickListener? = null
|
||||||
|
private var mCustomBundle: CustomBundle? = null
|
||||||
|
private var mCurLength = 0
|
||||||
|
private val mKeyValues: IntArray
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
val viewHolder: RecyclerView.ViewHolder
|
||||||
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
|
if (viewType == TYPE_NUMBER) {
|
||||||
|
val view: View = inflater.inflate(R.layout.item_number, parent, false)
|
||||||
|
viewHolder = NumberViewHolder(view)
|
||||||
|
} else {
|
||||||
|
val view: View = inflater.inflate(R.layout.item_delete, parent, false)
|
||||||
|
viewHolder = DeleteViewHolder(view)
|
||||||
|
}
|
||||||
|
return viewHolder
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
mKeyValues = getKeyValues(intArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
if (holder.itemViewType == TYPE_NUMBER) {
|
||||||
|
val vh1 = holder as NumberViewHolder
|
||||||
|
setNumberBtn(vh1, position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setNumberBtn(holder: NumberViewHolder?, position: Int) {
|
||||||
|
if (holder != null) {
|
||||||
|
if (position == 9) {
|
||||||
|
holder.mNumberButton.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
holder.mNumberButton.text = mKeyValues[position].toString()
|
||||||
|
holder.mNumberButton.visibility = View.VISIBLE
|
||||||
|
holder.mNumberButton.tag = mKeyValues[position]
|
||||||
|
}
|
||||||
|
if (mCustomBundle != null) {
|
||||||
|
holder.mNumberButton.setTextColor(mCustomBundle!!.textColor)
|
||||||
|
if (mCustomBundle!!.backgroundDrawable != null) {
|
||||||
|
holder.mNumberButton.background = mCustomBundle!!.backgroundDrawable
|
||||||
|
}
|
||||||
|
holder.mNumberButton.setTextSize(
|
||||||
|
TypedValue.COMPLEX_UNIT_PX,
|
||||||
|
mCustomBundle!!.textSize.toFloat()
|
||||||
|
)
|
||||||
|
val params: LinearLayout.LayoutParams = LinearLayout.LayoutParams(
|
||||||
|
mCustomBundle!!.buttonSize,
|
||||||
|
mCustomBundle!!.buttonSize
|
||||||
|
)
|
||||||
|
holder.mNumberButton.setLayoutParams(params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemCount(): Int {
|
||||||
|
return 12
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int): Int {
|
||||||
|
return if (position == itemCount - 1) {
|
||||||
|
VIEW_TYPE_DELETE
|
||||||
|
} else TYPE_NUMBER
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPinLength(pinLength: Int) {
|
||||||
|
mCurLength = pinLength
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getKeyValues(keyValues: IntArray): IntArray {
|
||||||
|
val adjustedKeyValues = IntArray(keyValues.size + 1)
|
||||||
|
for (i in keyValues.indices) {
|
||||||
|
if (i < 9) {
|
||||||
|
adjustedKeyValues[i] = keyValues[i]
|
||||||
|
} else {
|
||||||
|
adjustedKeyValues[i] = -1
|
||||||
|
adjustedKeyValues[i + 1] = keyValues[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return adjustedKeyValues
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setOnItemClickListener(onNumberClickListener: OnNumberClickListener?) {
|
||||||
|
mOnNumberListener = onNumberClickListener
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setOnDeleteClickListener(onDeleteClickListener: OnDeleteClickListener?) {
|
||||||
|
mOnDeleteListener = onDeleteClickListener
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setCustomizationOptions(customBundle: CustomBundle?) {
|
||||||
|
mCustomBundle = customBundle
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class NumberViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
var mNumberButton: Button
|
||||||
|
|
||||||
|
init {
|
||||||
|
mNumberButton = itemView.findViewById<View>(R.id.deleteLayout) as Button
|
||||||
|
mNumberButton.setOnClickListener { v ->
|
||||||
|
if (mOnNumberListener != null) {
|
||||||
|
mOnNumberListener!!.onNumberClicked(v.tag as Int)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OnNumberClickListener {
|
||||||
|
fun onNumberClicked(keyValue: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OnDeleteClickListener {
|
||||||
|
fun onDeleteClicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
inner class DeleteViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
|
private var mDeleteLayout: LinearLayout
|
||||||
|
private var mDeleteImage: ImageView
|
||||||
|
|
||||||
|
init {
|
||||||
|
mDeleteLayout = itemView.findViewById<View>(R.id.deleteLayout) as LinearLayout
|
||||||
|
mDeleteImage = itemView.findViewById<View>(R.id.deleteImage) as ImageView
|
||||||
|
if (mCustomBundle?.isShowDeleteButton!! && mCurLength > 0) {
|
||||||
|
mDeleteLayout.setOnClickListener {
|
||||||
|
if (mOnDeleteListener != null) {
|
||||||
|
mOnDeleteListener!!.onDeleteClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TYPE_NUMBER = 0
|
||||||
|
private const val VIEW_TYPE_DELETE = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.customview
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
|
||||||
|
class CustomBundle {
|
||||||
|
@JvmField
|
||||||
|
var textColor = 0
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
var textSize = 0
|
||||||
|
var isShowDeleteButton: Boolean = false
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
var buttonSize = 0
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
var backgroundDrawable: Drawable? = null
|
||||||
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.customview
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.Gravity
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.WindowManager
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import com.kitobochi.softapp.timberlock.R
|
||||||
|
import com.kitobochi.softapp.timberlock.databinding.ViewDialogBinding
|
||||||
|
|
||||||
|
class DialogPer : DialogFragment() {
|
||||||
|
private lateinit var binding: ViewDialogBinding
|
||||||
|
|
||||||
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
binding = ViewDialogBinding.inflate(getLayoutInflater())
|
||||||
|
dialog!!.setCanceledOnTouchOutside(false)
|
||||||
|
dialog!!.setCancelable(false)
|
||||||
|
val window = dialog!!.window
|
||||||
|
window!!.setBackgroundDrawableResource(R.color.null_color)
|
||||||
|
window.decorView.setPadding(0, 0, 0, 0)
|
||||||
|
val wlp = window.attributes
|
||||||
|
wlp.gravity = Gravity.CENTER
|
||||||
|
wlp.width = WindowManager.LayoutParams.MATCH_PARENT
|
||||||
|
wlp.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||||
|
window.setAttributes(wlp)
|
||||||
|
binding.tvGo.setOnClickListener(View.OnClickListener { listener?.onToSetting() })
|
||||||
|
return binding.getRoot()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var listener: onPermssionListener? = null
|
||||||
|
|
||||||
|
public fun setListener(listener: onPermssionListener?) {
|
||||||
|
this.listener = listener
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object{
|
||||||
|
fun newInstance(): DialogPer {
|
||||||
|
return DialogPer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,90 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.customview
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.LinearLayout
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import com.kitobochi.softapp.timberlock.R
|
||||||
|
import com.kitobochi.softapp.timberlock.tools.CustomViewTools
|
||||||
|
|
||||||
|
class InputStateView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
|
||||||
|
LinearLayout(context, attrs, defStyleAttr) {
|
||||||
|
private var mPinLength = 0
|
||||||
|
private var mPreviousLength = 0
|
||||||
|
private var mDotDiameter = 0
|
||||||
|
private var mDotSpacing = 0
|
||||||
|
private var mFillDrawable = 0
|
||||||
|
private var mEmptyDrawable = 0
|
||||||
|
private fun initView(context: Context) {
|
||||||
|
ViewCompat.setLayoutDirection(this, ViewCompat.LAYOUT_DIRECTION_LTR)
|
||||||
|
for (i in 0 until mPinLength) {
|
||||||
|
val dot = View(context)
|
||||||
|
emptyDot(dot)
|
||||||
|
val params = LayoutParams(
|
||||||
|
mDotDiameter,
|
||||||
|
mDotDiameter
|
||||||
|
)
|
||||||
|
params.setMargins(mDotSpacing, 0, mDotSpacing, 0)
|
||||||
|
dot.setLayoutParams(params)
|
||||||
|
addView(dot)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyLock)
|
||||||
|
try {
|
||||||
|
mDotDiameter = typedArray.getDimension(
|
||||||
|
R.styleable.MyLock_dotDiameter,
|
||||||
|
CustomViewTools().getPx(getContext(), R.dimen.default_dot_diameter)
|
||||||
|
).toInt()
|
||||||
|
mDotSpacing = typedArray.getDimension(
|
||||||
|
R.styleable.MyLock_dotSpacing,
|
||||||
|
CustomViewTools().getPx(getContext(), R.dimen.default_dot_spacing)
|
||||||
|
).toInt()
|
||||||
|
mFillDrawable = typedArray.getResourceId(
|
||||||
|
R.styleable.MyLock_dotFilledBackground,
|
||||||
|
R.drawable.shape_oval_white
|
||||||
|
)
|
||||||
|
mEmptyDrawable = typedArray.getResourceId(
|
||||||
|
R.styleable.MyLock_dotEmptyBackground,
|
||||||
|
R.drawable.shape_oval_gray
|
||||||
|
)
|
||||||
|
mPinLength = typedArray.getInt(R.styleable.MyLock_pinLength, DEFAULT_PIN_LENGTH)
|
||||||
|
} finally {
|
||||||
|
typedArray.recycle()
|
||||||
|
}
|
||||||
|
initView(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun emptyDot(dot: View) {
|
||||||
|
dot.setBackgroundResource(mEmptyDrawable)
|
||||||
|
dot.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fillDot(dot: View) {
|
||||||
|
dot.setBackgroundResource(mFillDrawable)
|
||||||
|
dot.animate().scaleX(1.2f).scaleY(1.2f).setDuration(100).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateDot(length: Int) {
|
||||||
|
mPreviousLength = if (length > 0) {
|
||||||
|
if (length > mPreviousLength) {
|
||||||
|
fillDot(getChildAt(length - 1))
|
||||||
|
} else {
|
||||||
|
emptyDot(getChildAt(length))
|
||||||
|
}
|
||||||
|
length
|
||||||
|
} else {
|
||||||
|
for (i in 0 until childCount) {
|
||||||
|
val v = getChildAt(i)
|
||||||
|
emptyDot(v)
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val DEFAULT_PIN_LENGTH = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,178 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.customview
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.kitobochi.softapp.timberlock.R
|
||||||
|
import com.kitobochi.softapp.timberlock.tools.CustomViewTools
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.adapter.KeyboardAdapter
|
||||||
|
|
||||||
|
class KeyboardView : RecyclerView {
|
||||||
|
private var mPin = ""
|
||||||
|
var pinLength = 0
|
||||||
|
private set
|
||||||
|
private var mHorizontalSpacing = 0
|
||||||
|
private var mVerticalSpacing = 0
|
||||||
|
private var mTextColor = 0
|
||||||
|
private var mTextSize = 0
|
||||||
|
private var mButtonSize = 0
|
||||||
|
private var mButtonBgDraw: Drawable? = null
|
||||||
|
private var mAdapter: KeyboardAdapter? = null
|
||||||
|
private var mPinLockListener: ListenerLock? = null
|
||||||
|
private var mCustomBundle: CustomBundle? = null
|
||||||
|
var isShowDeleteButton = false
|
||||||
|
private set
|
||||||
|
private var mMyDots: InputStateView? = null
|
||||||
|
private val numberClickListener: KeyboardAdapter.OnNumberClickListener =
|
||||||
|
object : KeyboardAdapter.OnNumberClickListener {
|
||||||
|
override fun onNumberClicked(keyValue: Int) {
|
||||||
|
if (mPin.length < pinLength) {
|
||||||
|
mPin += keyValue.toString()
|
||||||
|
if (isIndicatorDotsAttached) {
|
||||||
|
mMyDots?.updateDot(mPin.length)
|
||||||
|
}
|
||||||
|
if (mPin.length == 1) {
|
||||||
|
mAdapter?.setPinLength(mPin.length)
|
||||||
|
mAdapter?.notifyItemChanged(mAdapter!!.itemCount - 1)
|
||||||
|
}
|
||||||
|
if (mPinLockListener != null) {
|
||||||
|
if (mPin.length == pinLength) {
|
||||||
|
mPinLockListener!!.onInPutComplete(mPin)
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!isShowDeleteButton) {
|
||||||
|
resetPinLockView()
|
||||||
|
mPin += keyValue.toString()
|
||||||
|
if (isIndicatorDotsAttached) {
|
||||||
|
mMyDots?.updateDot(mPin.length)
|
||||||
|
}
|
||||||
|
if (mPinLockListener != null) {
|
||||||
|
// mPinLockListener.onPinChange(mPin.length(), mPin);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mPinLockListener?.onInPutComplete(mPin)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private val mOnDeleteClickListener: KeyboardAdapter.OnDeleteClickListener =
|
||||||
|
object : KeyboardAdapter.OnDeleteClickListener {
|
||||||
|
override fun onDeleteClicked() {
|
||||||
|
if (mPin.length > 0) {
|
||||||
|
mPin = mPin.substring(0, mPin.length - 1)
|
||||||
|
if (isIndicatorDotsAttached) {
|
||||||
|
mMyDots?.updateDot(mPin.length)
|
||||||
|
}
|
||||||
|
if (mPin.length == 0) {
|
||||||
|
mAdapter?.setPinLength(mPin.length)
|
||||||
|
mAdapter?.notifyItemChanged(mAdapter!!.itemCount - 1)
|
||||||
|
}
|
||||||
|
if (mPinLockListener != null) {
|
||||||
|
if (mPin.length == 0) {
|
||||||
|
// mPinLockListener.onEmpty();
|
||||||
|
clearInternalPin()
|
||||||
|
} else {
|
||||||
|
// mPinLockListener.onPinChange(mPin.length(), mPin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mPinLockListener != null) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(context: Context?) : super(context!!) {
|
||||||
|
init(null, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs) {
|
||||||
|
init(attrs, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(context!!, attrs, defStyle) {
|
||||||
|
init(attrs, defStyle)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun init(attributeSet: AttributeSet?, defStyle: Int) {
|
||||||
|
val typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.MyLock)
|
||||||
|
try {
|
||||||
|
pinLength = typedArray.getInt(R.styleable.MyLock_pinLength, DEFAULT_PWD_LENGTH)
|
||||||
|
mHorizontalSpacing = typedArray.getDimension(
|
||||||
|
R.styleable.MyLock_keypadHorizontalSpacing, CustomViewTools().getPx(
|
||||||
|
context, R.dimen.default_horizontal_spacing
|
||||||
|
)
|
||||||
|
).toInt()
|
||||||
|
mVerticalSpacing = typedArray.getDimension(
|
||||||
|
R.styleable.MyLock_keypadVerticalSpacing,
|
||||||
|
CustomViewTools().getPx(context, R.dimen.default_vertical_spacing)
|
||||||
|
).toInt()
|
||||||
|
mTextColor =
|
||||||
|
typedArray.getColor(
|
||||||
|
R.styleable.MyLock_keypadTextColor,
|
||||||
|
CustomViewTools().getColor(context, R.color.white)
|
||||||
|
)
|
||||||
|
mTextSize = typedArray.getDimension(
|
||||||
|
R.styleable.MyLock_keypadTextSize,
|
||||||
|
CustomViewTools().getPx(context, R.dimen.default_text_size)
|
||||||
|
).toInt()
|
||||||
|
mButtonSize = typedArray.getDimension(
|
||||||
|
R.styleable.MyLock_keypadButtonSize,
|
||||||
|
CustomViewTools().getPx(context, R.dimen.default_button_size)
|
||||||
|
).toInt()
|
||||||
|
mButtonBgDraw = typedArray.getDrawable(R.styleable.MyLock_keypadButtonBackgroundDrawable)
|
||||||
|
isShowDeleteButton = typedArray.getBoolean(R.styleable.MyLock_keypadShowDeleteButton, true)
|
||||||
|
} finally {
|
||||||
|
typedArray.recycle()
|
||||||
|
}
|
||||||
|
mCustomBundle = CustomBundle()
|
||||||
|
mCustomBundle!!.textColor = mTextColor
|
||||||
|
mCustomBundle!!.textSize = mTextSize
|
||||||
|
mCustomBundle!!.buttonSize = mButtonSize
|
||||||
|
mCustomBundle!!.backgroundDrawable = mButtonBgDraw
|
||||||
|
mCustomBundle!!.isShowDeleteButton = isShowDeleteButton
|
||||||
|
initView()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initView() {
|
||||||
|
mAdapter = KeyboardAdapter()
|
||||||
|
setLayoutManager(GridLayoutManager(context, 3))
|
||||||
|
mAdapter!!.setOnItemClickListener(numberClickListener)
|
||||||
|
mAdapter!!.setOnDeleteClickListener(mOnDeleteClickListener)
|
||||||
|
mAdapter!!.setCustomizationOptions(mCustomBundle)
|
||||||
|
setAdapter(mAdapter)
|
||||||
|
addItemDecoration(LockSpace(mHorizontalSpacing, mVerticalSpacing, 3, false))
|
||||||
|
setOverScrollMode(OVER_SCROLL_NEVER)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setPinLockListener(pinLockListener: ListenerLock?) {
|
||||||
|
mPinLockListener = pinLockListener
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearInternalPin() {
|
||||||
|
mPin = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resetPinLockView() {
|
||||||
|
clearInternalPin()
|
||||||
|
mAdapter?.setPinLength(mPin.length)
|
||||||
|
mAdapter?.notifyItemChanged(mAdapter!!.getItemCount() - 1)
|
||||||
|
mMyDots?.updateDot(mPin.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
val isIndicatorDotsAttached: Boolean
|
||||||
|
get() = mMyDots != null
|
||||||
|
|
||||||
|
fun attachIndicatorDots(mMyDots: InputStateView?) {
|
||||||
|
this.mMyDots = mMyDots
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val DEFAULT_PWD_LENGTH = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.customview
|
||||||
|
|
||||||
|
interface ListenerLock {
|
||||||
|
fun onInPutComplete(pin: String)
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.customview
|
||||||
|
|
||||||
|
import android.graphics.Rect
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.recyclerview.widget.RecyclerView.ItemDecoration
|
||||||
|
|
||||||
|
|
||||||
|
class LockSpace(
|
||||||
|
private val HSpace: Int,
|
||||||
|
private val mVSpace: Int,
|
||||||
|
private val mSpanCount: Int,
|
||||||
|
private val mInclude: Boolean
|
||||||
|
) :
|
||||||
|
ItemDecoration() {
|
||||||
|
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
|
||||||
|
val position = parent.getChildAdapterPosition(view)
|
||||||
|
val column = position % mSpanCount
|
||||||
|
if (mInclude) {
|
||||||
|
outRect.left = HSpace - column * HSpace / mSpanCount
|
||||||
|
outRect.right = (column + 1) * HSpace / mSpanCount
|
||||||
|
if (position < mSpanCount) {
|
||||||
|
outRect.top = mVSpace
|
||||||
|
}
|
||||||
|
outRect.bottom = mVSpace
|
||||||
|
} else {
|
||||||
|
outRect.left = column * HSpace / mSpanCount
|
||||||
|
outRect.right = HSpace - (column + 1) * HSpace / mSpanCount
|
||||||
|
if (position >= mSpanCount) {
|
||||||
|
outRect.top = mVSpace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.customview
|
||||||
|
|
||||||
|
interface onPermssionListener {
|
||||||
|
fun onToSetting()
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.fragment
|
||||||
|
|
||||||
|
import android.app.AlertDialog
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import com.kitobochi.softapp.timberlock.ad.AdListener
|
||||||
|
import com.kitobochi.softapp.timberlock.ad.AdMsgListener
|
||||||
|
import com.kitobochi.softapp.timberlock.databinding.FragmentApplistBinding
|
||||||
|
import com.kitobochi.softapp.timberlock.db.AppDatabase
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.adapter.AppListAdapter
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
class AppListFragment(
|
||||||
|
private val isSystem: Boolean
|
||||||
|
) : BaseFragment() {
|
||||||
|
|
||||||
|
private lateinit var binding: FragmentApplistBinding
|
||||||
|
override fun getFragmentView(): View {
|
||||||
|
binding = FragmentApplistBinding.inflate(layoutInflater)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
super.initView()
|
||||||
|
initAppList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initAppList() {
|
||||||
|
val adapter = AppListAdapter(requireContext(), object : AdMsgListener {
|
||||||
|
override fun msg(msg: String) {
|
||||||
|
// Log.e("------", "回调成功")
|
||||||
|
val builder = AlertDialog.Builder(requireContext())
|
||||||
|
builder.setTitle("Successfully set")
|
||||||
|
builder.setMessage(msg)
|
||||||
|
builder.setPositiveButton("OK") { dialog, _ ->
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
val alertDialog = builder.create()
|
||||||
|
alertDialog.show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
binding.appList.adapter = adapter
|
||||||
|
binding.appList.layoutManager = LinearLayoutManager(requireContext())
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
val data = AppDatabase.database.getAppDao().findByType(isSystem, false)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (data != null) {
|
||||||
|
adapter.updateSystemApp(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.fragment
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
|
||||||
|
abstract class BaseFragment : Fragment() {
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
return getFragmentView()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
initView()
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun initView() {
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun getFragmentView(): View
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock.ui.fragment
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.view.View
|
||||||
|
import com.kitobochi.softapp.timberlock.App
|
||||||
|
import com.kitobochi.softapp.timberlock.R
|
||||||
|
import com.kitobochi.softapp.timberlock.databinding.FragmentSettingBinding
|
||||||
|
import com.kitobochi.softapp.timberlock.tools.LockServiceManager
|
||||||
|
import com.kitobochi.softapp.timberlock.ui.activity.SetPwdActivity
|
||||||
|
|
||||||
|
class SettingFragment : BaseFragment(), View.OnClickListener {
|
||||||
|
|
||||||
|
private val IS_SHOW_AD = "IS_SHOW_AD"
|
||||||
|
private lateinit var binding: FragmentSettingBinding
|
||||||
|
override fun getFragmentView(): View {
|
||||||
|
binding = FragmentSettingBinding.inflate(layoutInflater)
|
||||||
|
return binding.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun initView() {
|
||||||
|
super.initView()
|
||||||
|
initButton()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initButton() {
|
||||||
|
binding.settingRating.setOnClickListener(this)
|
||||||
|
binding.settingShare.setOnClickListener(this)
|
||||||
|
binding.settingPassword.setOnClickListener(this)
|
||||||
|
// binding.settingInit.setOnClickListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View?) {
|
||||||
|
when (v) {
|
||||||
|
binding.settingRating -> {
|
||||||
|
val url = getString(R.string.setting_link) + (activity?.packageName ?: "")
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW)
|
||||||
|
intent.setData(Uri.parse(url))
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.settingShare -> {
|
||||||
|
val url = getString(R.string.setting_link) + (activity?.packageName ?: "")
|
||||||
|
val intent = Intent(Intent.ACTION_SEND)
|
||||||
|
intent.setType("text/plain")
|
||||||
|
intent.putExtra(Intent.EXTRA_TEXT, url)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.settingPassword -> {
|
||||||
|
val intent = Intent(requireContext(), SetPwdActivity::class.java)
|
||||||
|
intent.putExtra(IS_SHOW_AD, true)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// binding.settingInit -> {
|
||||||
|
//// LockServiceManager().toSetUsagePermission(requireActivity(), App().reqCodeUsage)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
app/src/main/res/drawable-v24/ic_launcher_foreground.xml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:aapt="http://schemas.android.com/aapt"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||||
|
<aapt:attr name="android:fillColor">
|
||||||
|
<gradient
|
||||||
|
android:endX="85.84757"
|
||||||
|
android:endY="92.4963"
|
||||||
|
android:startX="42.9492"
|
||||||
|
android:startY="49.59793"
|
||||||
|
android:type="linear">
|
||||||
|
<item
|
||||||
|
android:color="#44000000"
|
||||||
|
android:offset="0.0" />
|
||||||
|
<item
|
||||||
|
android:color="#00000000"
|
||||||
|
android:offset="1.0" />
|
||||||
|
</gradient>
|
||||||
|
</aapt:attr>
|
||||||
|
</path>
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:strokeColor="#00000000" />
|
||||||
|
</vector>
|
||||||
170
app/src/main/res/drawable/ic_launcher_background.xml
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="108dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="108"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:fillColor="#3DDC84"
|
||||||
|
android:pathData="M0,0h108v108h-108z" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M9,0L9,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,0L19,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,0L29,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,0L39,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,0L49,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,0L59,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,0L69,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,0L79,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M89,0L89,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M99,0L99,108"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,9L108,9"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,19L108,19"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,29L108,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,39L108,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,49L108,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,59L108,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,69L108,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,79L108,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,89L108,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M0,99L108,99"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,29L89,29"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,39L89,39"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,49L89,49"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,59L89,59"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,69L89,69"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M19,79L89,79"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M29,19L29,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M39,19L39,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M49,19L49,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M59,19L59,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M69,19L69,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
<path
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:pathData="M79,19L79,89"
|
||||||
|
android:strokeWidth="0.8"
|
||||||
|
android:strokeColor="#33FFFFFF" />
|
||||||
|
</vector>
|
||||||
7
app/src/main/res/drawable/selector_switch.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item android:drawable="@drawable/shape_yellow_switch" android:state_checked="true" />
|
||||||
|
<item android:drawable="@drawable/shape_white_switch" android:state_checked="false" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
6
app/src/main/res/drawable/selector_text_color.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:color="@color/white" android:state_selected="true" />
|
||||||
|
<item android:color="@color/black" android:state_selected="false" />
|
||||||
|
|
||||||
|
</selector>
|
||||||
5
app/src/main/res/drawable/shape_oval_gray.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="@color/yellow_color" />
|
||||||
|
</shape>
|
||||||
5
app/src/main/res/drawable/shape_oval_white.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="@color/white" />
|
||||||
|
</shape>
|
||||||
7
app/src/main/res/drawable/shape_pink_r30.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="30dp" />
|
||||||
|
<solid android:color="@color/pink_bg_color" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
7
app/src/main/res/drawable/shape_pwd_bg.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="15dp" />
|
||||||
|
<solid android:color="@color/white" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
7
app/src/main/res/drawable/shape_pwd_ok.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="36dp" />
|
||||||
|
<solid android:color="@color/yellow_color" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
7
app/src/main/res/drawable/shape_rect_r12.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="12dp"/>
|
||||||
|
<solid android:color="@color/main_bg_color"/>
|
||||||
|
|
||||||
|
</shape>
|
||||||
10
app/src/main/res/drawable/shape_white_switch.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="@color/ash_color" />
|
||||||
|
<corners android:radius="100dp" />
|
||||||
|
<size
|
||||||
|
android:width="36dp"
|
||||||
|
android:height="22dp" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
7
app/src/main/res/drawable/shape_yellow_r30.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<corners android:radius="30dp" />
|
||||||
|
<solid android:color="@color/yellow_color" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
10
app/src/main/res/drawable/shape_yellow_switch.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="@color/main_bg" />
|
||||||
|
<corners android:radius="100dp" />
|
||||||
|
<size
|
||||||
|
android:width="36dp"
|
||||||
|
android:height="22dp" />
|
||||||
|
|
||||||
|
</shape>
|
||||||
12
app/src/main/res/drawable/svg_back.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="200dp"
|
||||||
|
android:height="200dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M512,0C229.9,0 0,229.9 0,512s229.9,512 512,512 512,-229.9 512,-512S794.1,0 512,0zM512,916c-222.7,0 -404,-181.2 -404,-404S289.3,108 512,108s404,181.2 404,404 -181.2,404 -404,404z"
|
||||||
|
android:fillColor="@color/white"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M586.2,364.5H426l13.8,-13.8c13.8,-13.8 13.8,-36.9 0,-50.7s-36.9,-13.8 -51.2,0L308.2,379.9c-13.8,13.8 -13.8,36.9 0,50.7l80.4,80.4c7.2,7.2 16.4,10.8 25.6,10.8 9.2,0 18.4,-3.6 25.6,-10.8 13.8,-13.8 13.8,-36.9 0,-50.7l-3.6,-3.6h150c37.4,0 67.6,36.9 67.6,82.4s-30.2,82.4 -67.6,82.4h-230.4c-25.6,0 -46.1,20.5 -46.1,46.1s20.5,46.1 46.1,46.1h230.9c88.6,0 160.3,-78.3 160.3,-175.1s-72.2,-174.1 -160.8,-174.1z"
|
||||||
|
android:fillColor="@color/white"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/svg_delete.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="200dp"
|
||||||
|
android:height="200dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M303.9,277.3h491.8a42.7,42.7 0,0 1,42.7 42.7v384a42.7,42.7 0,0 1,-42.7 42.7L303.9,746.7a42.7,42.7 0,0 1,-33 -15.7l-157.1,-192a42.7,42.7 0,0 1,0 -54l157.1,-192A42.7,42.7 0,0 1,303.9 277.3zM521.2,466.8l-98.7,-98.7a9.8,9.8 0,0 0,-13.8 0l-31.4,31.4a9.8,9.8 0,0 0,0 13.8l98.7,98.7 -98.7,98.7a9.8,9.8 0,0 0,0 13.8l31.4,31.4c3.8,3.8 10,3.8 13.8,0l98.7,-98.7 98.7,98.7c3.8,3.8 10,3.8 13.8,0l31.4,-31.4a9.8,9.8 0,0 0,0 -13.8l-98.7,-98.7 98.7,-98.7a9.8,9.8 0,0 0,0 -13.8l-31.4,-31.4a9.8,9.8 0,0 0,-13.8 0l-98.7,98.7z"
|
||||||
|
android:fillColor="#ffffff"/>
|
||||||
|
</vector>
|
||||||
12
app/src/main/res/drawable/svg_rating.xml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="200dp"
|
||||||
|
android:height="200dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/black"
|
||||||
|
android:pathData="M724.5,877.3c-7.8,0 -15.5,-2.9 -21.5,-8.3L575.8,753.4l-167.4,39.2c-11.9,2.7 -24.3,-1.4 -32,-10.8 -7.8,-9.4 -9.5,-22.4 -4.5,-33.5l70.7,-156.7 -89,-147c-6.3,-10.4 -6.2,-23.5 0.4,-33.8 6.5,-10.3 18.3,-16 30.5,-14.6L555.4,415l112.3,-130.1c8,-9.2 20.4,-13.2 32.3,-10 11.8,3 20.8,12.5 23.3,24.5l35,168.3 158.5,66.7c11.2,4.8 18.8,15.4 19.5,27.6 0.7,12.2 -5.5,23.7 -16.1,29.7l-149.3,85.2L756.4,848c-1,12.2 -8.8,22.7 -20.2,27.1 -3.7,1.5 -7.7,2.2 -11.7,2.2zM584.9,686.4c7.9,0 15.6,2.9 21.5,8.3l91.7,83.3 10.4,-123.5c0.9,-10.5 6.9,-19.9 16,-25.1L832.1,568l-114.2,-48c-9.7,-4.1 -16.8,-12.7 -18.9,-23l-25.2,-121.3 -81,93.8c-6.9,8 -17.3,11.9 -27.7,10.9L442,466.8l64.2,106c5.5,9 6.1,20.1 1.8,29.8l-51,112.9 120.6,-28.3c2.4,-0.5 4.9,-0.8 7.3,-0.8z"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M637.4,268.8c-5.5,-10.7 -16.6,-17.9 -28.6,-17.9l-142.9,-0.9 -80.6,-118.2c-6.8,-9.8 -18.8,-15.4 -30.7,-13.7 -12.4,1.7 -22.2,10.2 -26,21.8l-44.8,135.7 -137.4,39.7c-11.9,3.4 -20.5,13.2 -22.6,25.2 -2.1,11.9 2.6,24.3 12.4,31.6l115.2,84.5 -4.4,142.9c-0.4,12.4 6,23.5 16.6,29.4 4.7,2.6 10.2,3.8 15.4,3.8 6.4,0 12.8,-2.1 18.3,-6.4l98.6,-70.4 -33.3,-55 -49.9,35.8 3,-94.7c0.4,-10.7 -4.3,-20.9 -12.8,-26.9l-76.4,-56.3 90.9,-26.5c10.2,-3 18.3,-10.7 21.3,-20.9l30.3,-90 53.3,78.5c6,9 15.8,14.1 26,14.1l95.1,0.4 -55.9,71.7 74.9,8.1 71.1,-91.7c4.7,-5.1 6.8,-12.4 6.8,-18.8 0.1,-5.1 -0.7,-10.2 -2.9,-14.9z"
|
||||||
|
android:fillColor="#FFCE00"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/svg_reset_password.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="200dp"
|
||||||
|
android:height="200dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M365.7,438.9v-73.1a146.3,146.3 0,1 1,292.6 0v73.1h36.6a36.6,36.6 0,0 1,36.6 36.6v219.4a36.6,36.6 0,0 1,-36.6 36.6L329.1,731.4a36.6,36.6 0,0 1,-36.6 -36.6v-219.4a36.6,36.6 0,0 1,36.6 -36.6h36.6zM438.9,438.9h146.3v-73.1a73.1,73.1 0,0 0,-146.3 0v73.1zM365.7,512v146.3h292.6v-146.3h-292.6zM768.8,251.6A364.5,364.5 0,0 0,512 146.3C310,146.3 146.3,310 146.3,512s163.7,365.7 365.7,365.7 365.7,-163.7 365.7,-365.7h73.1c0,242.4 -196.5,438.9 -438.9,438.9S73.1,754.4 73.1,512 269.6,73.1 512,73.1c120.3,0 229.3,48.4 308.5,126.8l49,-49 25.9,181 -181,-25.9 54.4,-54.4z"
|
||||||
|
android:fillColor="@color/black"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/svg_set.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="200dp"
|
||||||
|
android:height="200dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:pathData="M882.2,620.9l-24.1,-14c-11.6,-6.8 -18.1,-19.8 -16.3,-33.3 2.2,-15.1 3.3,-30.4 3.3,-46.2 0,-15.8 -1.2,-31.1 -3.3,-46.2 -1.8,-13.5 4.5,-26.4 19.5,-35.1l21,-12.1c14,-8 20.1,-24.8 14.8,-39.9 -7.2,-20.6 -16.3,-40.4 -26.8,-59.4 -2.5,-4.7 -5.3,-9.5 -8.2,-14.1 -11.1,-18.5 -23.8,-35.9 -37.8,-52.2 -10.5,-12.3 -28.1,-15.1 -45.1,-5.3l-21.3,12.3c-11.6,6.8 -26.3,5.8 -36.9,-2.5 -24.1,-19.1 -50.9,-34.8 -80,-46.4 -12.5,-5 -20.5,-17.3 -20.5,-30.6v-28.1c0,-16.1 -11.5,-29.9 -27.3,-32.9 -23.6,-4.3 -47.7,-6.5 -72.5,-6.5 -24.8,0 -48.9,2.2 -72.5,6.5 -15.8,3 -27.3,16.8 -27.3,32.9v28.1c0,13.3 -8,25.6 -20.5,30.6 -29.1,11.6 -55.9,27.3 -80,46.4 -10.6,8.3 -25.3,9.3 -36.9,2.5l-24.3,-14.1c-14,-8 -31.6,-5.2 -42.1,7.2 -14,16.3 -26.6,33.8 -37.8,52.2 -2.8,4.7 -5.7,9.5 -8.2,14.1 -10.5,19 -19.6,38.8 -26.8,59.4 -5.3,15.1 0.8,31.9 14.8,39.9l24.1,14c11.6,6.8 18.1,19.8 16.3,33.3 -2.2,15.1 -3.3,30.4 -3.3,46.2 0,15.8 1.2,31.1 3.3,46.2 1.8,13.5 -4.7,26.4 -16.3,33.3l-24.1,14c-14,8 -20.1,24.8 -14.8,39.9 7.2,20.6 16.3,40.4 26.8,59.4 2.5,4.7 5.3,9.5 8.2,14.1 11.1,18.5 23.8,35.9 37.8,52.2 10.5,12.3 28.1,15.1 42.1,7.2l24.3,-14.1c11.6,-6.8 26.3,-5.8 36.9,2.5 24.1,19.1 50.9,34.8 80,46.4 12.5,5 20.5,17.3 20.5,30.6v28.1c0,16.1 11.5,29.9 27.3,32.9 23.6,4.3 47.7,6.5 72.5,6.5 24.8,0 48.9,-2.2 72.5,-6.5 15.8,-3 27.3,-16.8 27.3,-32.9v-28.1c0,-13.3 8,-25.6 20.5,-30.6 29.1,-11.6 55.9,-27.3 80,-46.4 10.6,-8.3 25.3,-9.3 36.9,-2.5l24.3,14.1c14,8 31.6,5.2 42.1,-7.2 14,-16.3 26.6,-33.8 37.8,-52.2 2.8,-4.7 5.7,-9.5 8.2,-14.1 10.5,-19 19.6,-38.8 26.8,-59.4 5.2,-15.3 -0.9,-32.1 -14.9,-40.1zM520.7,677.1c-82.7,0 -149.7,-67 -149.7,-149.7 0,-82.7 67,-149.7 149.7,-149.7s149.7,67 149.7,149.7c0,82.7 -67,149.7 -149.7,149.7z"
|
||||||
|
android:fillColor="#2c2c2c"/>
|
||||||
|
</vector>
|
||||||
9
app/src/main/res/drawable/svg_share.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="200dp"
|
||||||
|
android:height="200dp"
|
||||||
|
android:viewportWidth="1024"
|
||||||
|
android:viewportHeight="1024">
|
||||||
|
<path
|
||||||
|
android:fillColor="@color/black"
|
||||||
|
android:pathData="M558.9,699.7l-170.7,-93.9c-25.6,21.3 -55.5,34.1 -89.6,34.1 -72.5,0 -128,-55.5 -128,-128s55.5,-128 128,-128c38.4,0 68.3,17.1 93.9,38.4L597.3,320L597.3,298.7c0,-72.5 55.5,-128 128,-128s128,55.5 128,128 -55.5,128 -128,128c-34.1,0 -64,-12.8 -85.3,-34.1l-213.3,110.9v21.3l174.9,98.1c21.3,-17.1 51.2,-29.9 81.1,-29.9 72.5,0 128,55.5 128,128s-55.5,128 -128,128 -128,-55.5 -128,-128c0,-4.3 0,-12.8 4.3,-21.3zM298.7,554.7c25.6,0 42.7,-17.1 42.7,-42.7s-17.1,-42.7 -42.7,-42.7 -42.7,17.1 -42.7,42.7 17.1,42.7 42.7,42.7zM725.3,341.3c25.6,0 42.7,-17.1 42.7,-42.7s-17.1,-42.7 -42.7,-42.7 -42.7,17.1 -42.7,42.7 17.1,42.7 42.7,42.7zM682.7,768c25.6,0 42.7,-17.1 42.7,-42.7s-17.1,-42.7 -42.7,-42.7 -42.7,17.1 -42.7,42.7 17.1,42.7 42.7,42.7z" />
|
||||||
|
</vector>
|
||||||
17
app/src/main/res/drawable/svg_switch.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:bottom="2dp"
|
||||||
|
android:left="2dp"
|
||||||
|
android:right="2dp"
|
||||||
|
android:top="2dp">
|
||||||
|
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/white" />
|
||||||
|
<size
|
||||||
|
android:width="18dp"
|
||||||
|
android:height="18dp" />
|
||||||
|
<corners android:radius="8dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
||||||
16
app/src/main/res/drawable/thumb_sw.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item
|
||||||
|
android:bottom="2dp"
|
||||||
|
android:left="2dp"
|
||||||
|
android:right="2dp"
|
||||||
|
android:top="2dp">
|
||||||
|
|
||||||
|
<shape android:shape="oval">
|
||||||
|
<solid android:color="@color/white" />
|
||||||
|
<size
|
||||||
|
android:width="18dp"
|
||||||
|
android:height="18dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</layer-list>
|
||||||
59
app/src/main/res/layout/activity_main.xml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/main_bg_color"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".ui.activity.MainActivity">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/main_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginStart="25dp"
|
||||||
|
android:layout_marginTop="45dp"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@id/main_title"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.viewpager.widget.ViewPager
|
||||||
|
android:id="@+id/main_viewPager"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginStart="14dp"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:layout_marginEnd="14dp"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/shape_pink_r30" />
|
||||||
|
|
||||||
|
<com.google.android.material.tabs.TabLayout
|
||||||
|
android:id="@+id/main_tab"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="54dp"
|
||||||
|
android:layout_marginStart="14dp"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:layout_marginEnd="14dp"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:background="@drawable/shape_pink_r30"
|
||||||
|
app:tabGravity="fill"
|
||||||
|
app:tabIndicatorHeight="0dp"
|
||||||
|
app:tabMaxWidth="0dp"
|
||||||
|
app:tabMode="fixed"
|
||||||
|
app:tabPaddingBottom="0dp"
|
||||||
|
app:tabPaddingEnd="0dp"
|
||||||
|
app:tabPaddingStart="0dp"
|
||||||
|
app:tabPaddingTop="0dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
127
app/src/main/res/layout/activity_setpwd.xml
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/main_bg_color"
|
||||||
|
tools:context="com.kitobochi.softapp.timberlock.ui.activity.SetPwdActivity">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/pwd_back"
|
||||||
|
android:layout_width="34dp"
|
||||||
|
android:layout_height="34dp"
|
||||||
|
android:layout_marginStart="30dp"
|
||||||
|
android:layout_marginTop="48dp"
|
||||||
|
android:src="@drawable/svg_back" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/pwd_logo"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="133dp"
|
||||||
|
android:src="@mipmap/icon_logo" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pwd_title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/pwd_logo"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:text="@string/pwd_title"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="28sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pwd_sub"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/pwd_title"
|
||||||
|
android:layout_alignStart="@id/pwd_title"
|
||||||
|
android:layout_alignEnd="@id/pwd_title"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="22dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/pwd_content"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layout_pwd"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/pwd_sub"
|
||||||
|
android:layout_marginTop="60dp"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/et1"
|
||||||
|
android:layout_width="58dp"
|
||||||
|
android:layout_height="58dp"
|
||||||
|
android:background="@drawable/shape_pwd_bg"
|
||||||
|
android:gravity="center"
|
||||||
|
android:imeOptions="actionNext"
|
||||||
|
android:inputType="number"
|
||||||
|
android:maxLength="1"
|
||||||
|
android:text=""
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="23sp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/et2"
|
||||||
|
android:layout_width="58dp"
|
||||||
|
android:layout_height="58dp"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:background="@drawable/shape_pwd_bg"
|
||||||
|
android:gravity="center"
|
||||||
|
android:imeOptions="actionNext"
|
||||||
|
android:inputType="number"
|
||||||
|
android:maxLength="1"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="23sp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/et3"
|
||||||
|
android:layout_width="58dp"
|
||||||
|
android:layout_height="58dp"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:background="@drawable/shape_pwd_bg"
|
||||||
|
android:gravity="center"
|
||||||
|
android:imeOptions="actionNext"
|
||||||
|
android:inputType="number"
|
||||||
|
android:maxLength="1"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="23sp" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/et4"
|
||||||
|
android:layout_width="58dp"
|
||||||
|
android:layout_height="58dp"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:background="@drawable/shape_pwd_bg"
|
||||||
|
android:gravity="center"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:inputType="number"
|
||||||
|
android:maxLength="1"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="23sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pwd_ok"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="63dp"
|
||||||
|
android:layout_below="@id/layout_pwd"
|
||||||
|
android:layout_marginStart="30dp"
|
||||||
|
android:layout_marginTop="80dp"
|
||||||
|
android:layout_marginEnd="30dp"
|
||||||
|
android:background="@drawable/shape_pwd_ok"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/pwd_ok"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</RelativeLayout>
|
||||||
49
app/src/main/res/layout/activity_start.xml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/white"
|
||||||
|
tools:context=".ui.activity.StartPageActivity">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="80dp"
|
||||||
|
android:layout_height="80dp"
|
||||||
|
app:cardCornerRadius="12dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:src="@mipmap/icon_logo" />
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="260dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="32dp"
|
||||||
|
android:layout_marginBottom="60dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:lineSpacingExtra="20dp"
|
||||||
|
android:lineSpacingMultiplier="0.6"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textColor="@color/main_bg_color"
|
||||||
|
android:textSize="26sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:layout_width="42dp"
|
||||||
|
android:layout_height="42dp"
|
||||||
|
android:layout_gravity="center_horizontal|bottom"
|
||||||
|
android:layout_marginBottom="110dp"
|
||||||
|
android:indeterminateTint="@color/main_bg_color"
|
||||||
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
14
app/src/main/res/layout/fragment_applist.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".ui.fragment.AppListFragment">
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/app_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingBottom="10dp" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
115
app/src/main/res/layout/fragment_setting.xml
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".ui.fragment.SettingFragment">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_marginStart="28dp"
|
||||||
|
android:layout_marginTop="28dp"
|
||||||
|
android:layout_marginEnd="28dp"
|
||||||
|
android:backgroundTint="@color/white"
|
||||||
|
app:cardCornerRadius="30dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/setting_rating"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="27dp"
|
||||||
|
android:layout_height="27dp"
|
||||||
|
android:layout_marginStart="25dp"
|
||||||
|
android:src="@drawable/svg_rating" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/setting_rating"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_marginStart="28dp"
|
||||||
|
android:layout_marginTop="18dp"
|
||||||
|
android:layout_marginEnd="28dp"
|
||||||
|
android:backgroundTint="@color/white"
|
||||||
|
app:cardCornerRadius="30dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/setting_share"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="27dp"
|
||||||
|
android:layout_height="27dp"
|
||||||
|
android:layout_marginStart="25dp"
|
||||||
|
android:src="@drawable/svg_share" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/setting_share"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_marginStart="28dp"
|
||||||
|
android:layout_marginTop="18dp"
|
||||||
|
android:layout_marginEnd="28dp"
|
||||||
|
android:backgroundTint="@color/white"
|
||||||
|
app:cardCornerRadius="30dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/setting_password"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="27dp"
|
||||||
|
android:layout_height="27dp"
|
||||||
|
android:layout_marginStart="25dp"
|
||||||
|
android:src="@drawable/svg_reset_password" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/setting_password"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
40
app/src/main/res/layout/item_app.xml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_marginTop="17dp"
|
||||||
|
android:paddingStart="26dp"
|
||||||
|
android:paddingEnd="26dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/item_logo"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:src="@mipmap/ic_launcher" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/item_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignTop="@id/item_logo"
|
||||||
|
android:layout_alignBottom="@id/item_logo"
|
||||||
|
android:layout_marginStart="12dp"
|
||||||
|
android:layout_toEndOf="@id/item_logo"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.SwitchCompat
|
||||||
|
android:id="@+id/app_switch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:checked="true"
|
||||||
|
android:thumb="@drawable/thumb_sw"
|
||||||
|
app:track="@drawable/selector_switch" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
20
app/src/main/res/layout/item_delete.xml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/deleteLayout"
|
||||||
|
android:layout_width="64dp"
|
||||||
|
android:layout_height="64dp"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/deleteImage"
|
||||||
|
android:layout_width="45dp"
|
||||||
|
android:layout_height="45dp"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:clickable="false"
|
||||||
|
android:focusable="false"
|
||||||
|
android:scaleType="fitCenter"
|
||||||
|
android:src="@drawable/svg_delete" />
|
||||||
|
</LinearLayout>
|
||||||
15
app/src/main/res/layout/item_number.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/deleteLayout"
|
||||||
|
android:layout_width="64dp"
|
||||||
|
android:layout_height="64dp"
|
||||||
|
android:background="?android:attr/selectableItemBackground" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
56
app/src/main/res/layout/view_dialog.xml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="26dp"
|
||||||
|
android:layout_marginEnd="26dp"
|
||||||
|
android:background="@drawable/shape_rect_r12"
|
||||||
|
android:paddingBottom="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_title"
|
||||||
|
android:layout_width="260dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/dialog_title"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_sub"
|
||||||
|
android:layout_width="260dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/tv_title"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
android:lineSpacingExtra="10dp"
|
||||||
|
android:text="@string/dialog_content"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_go"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="43dp"
|
||||||
|
android:layout_below="@id/tv_sub"
|
||||||
|
android:layout_marginStart="30dp"
|
||||||
|
android:layout_marginTop="40dp"
|
||||||
|
android:layout_marginEnd="30dp"
|
||||||
|
android:background="@drawable/shape_yellow_r30"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/dialog_go"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
54
app/src/main/res/layout/view_lock.xml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/main_bg_color"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="85dp"
|
||||||
|
android:layout_height="85dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="140dp"
|
||||||
|
android:src="@mipmap/icon_logo" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_password_tip"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="14dp"
|
||||||
|
android:layout_marginBottom="36dp"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
|
||||||
|
<com.kitobochi.softapp.timberlock.ui.customview.InputStateView
|
||||||
|
android:id="@+id/indicator_dots"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginBottom="22dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
app:dotDiameter="12dp"
|
||||||
|
app:dotSpacing="20dp"
|
||||||
|
app:indicatorType="fixed" />
|
||||||
|
|
||||||
|
<com.kitobochi.softapp.timberlock.ui.customview.KeyboardView
|
||||||
|
android:id="@+id/pin_lock_view"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:layout_marginTop="28dp"
|
||||||
|
app:keypadHorizontalSpacing="64dp"
|
||||||
|
app:keypadShowDeleteButton="true"
|
||||||
|
app:keypadTextColor="@color/white"
|
||||||
|
app:keypadTextSize="36sp"
|
||||||
|
app:keypadVerticalSpacing="24dp"
|
||||||
|
app:pinLength="4" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
18
app/src/main/res/layout/view_tab.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingStart="4dp"
|
||||||
|
android:paddingEnd="4dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_tabtext"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="38dp"
|
||||||
|
android:background="@drawable/shape_yellow_r30"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/app_name"
|
||||||
|
android:textColor="@drawable/selector_text_color"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
6
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@drawable/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||||
|
</adaptive-icon>
|
||||||
BIN
app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 982 B |
BIN
app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 3.8 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/icon_logo.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
7
app/src/main/res/values-night/themes.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="Base.Theme.TimberLock" parent="Theme.Material3.DayNight.NoActionBar">
|
||||||
|
<!-- Customize your dark theme here. -->
|
||||||
|
<!-- <item name="colorPrimary">@color/my_dark_primary</item> -->
|
||||||
|
</style>
|
||||||
|
</resources>
|
||||||
54
app/src/main/res/values/attrs.xml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<declare-styleable name="Lock_Theme">
|
||||||
|
|
||||||
|
<attr name="app_bar_bg" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="act_bg" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="menu_bg" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="image_color" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="image_color_2" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="warning" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="lock_bg" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="lock_keypad_button_color" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="lock_keypad_button_bg_color" format="reference|color" />
|
||||||
|
<attr name="btn_pressed_shadow" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="text_1" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="text_2" format="reference|color" />
|
||||||
|
|
||||||
|
<attr name="text_3" format="reference|color" />
|
||||||
|
<attr name="sc_track_color" format="reference|color" />
|
||||||
|
|
||||||
|
</declare-styleable>
|
||||||
|
<declare-styleable name="MyLock">
|
||||||
|
<attr name="pinLength" format="integer" />
|
||||||
|
<attr name="keypadShowDeleteButton" format="boolean" />
|
||||||
|
<attr name="dotEmptyBackground" format="reference" />
|
||||||
|
<attr name="dotFilledBackground" format="reference" />
|
||||||
|
<attr name="dotDiameter" format="dimension" />
|
||||||
|
<attr name="dotSpacing" format="dimension" />
|
||||||
|
<attr name="indicatorType" format="enum">
|
||||||
|
<enum name="fixed" value="0" />
|
||||||
|
<enum name="fill" value="1" />
|
||||||
|
<enum name="fillWithAnimation" value="2" />
|
||||||
|
</attr>
|
||||||
|
<attr name="keypadTextColor" format="color" />
|
||||||
|
<attr name="keypadTextSize" format="dimension" />
|
||||||
|
<attr name="keypadButtonSize" format="dimension" />
|
||||||
|
<attr name="keypadVerticalSpacing" format="dimension" />
|
||||||
|
<attr name="keypadHorizontalSpacing" format="dimension" />
|
||||||
|
<attr name="keypadButtonBackgroundDrawable" format="integer" />
|
||||||
|
<attr name="keypadDeleteButtonDrawable" format="integer" />
|
||||||
|
|
||||||
|
|
||||||
|
</declare-styleable>
|
||||||
|
</resources>
|
||||||
16
app/src/main/res/values/colors.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<color name="black">#FF2C2C2C</color>
|
||||||
|
<color name="white">#FFFFFFFF</color>
|
||||||
|
|
||||||
|
<color name="yellow_color">#FFFF9800</color>
|
||||||
|
<color name="blue_bg_color">#80BFEFFF</color>
|
||||||
|
<color name="pink_bg_color">#FFFFE4E1</color>
|
||||||
|
<color name="main_bg_color">#FF8E8EFE</color>
|
||||||
|
<color name="white_sw_color">#E5E5E5</color>
|
||||||
|
<color name="null_color">#00000000</color>
|
||||||
|
|
||||||
|
<color name="main_bg">#FF9800</color>
|
||||||
|
|
||||||
|
<color name="ash_color">#ffaaa8a8</color>
|
||||||
|
</resources>
|
||||||
9
app/src/main/res/values/dimmens.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<dimen name="default_text_size">16sp</dimen>
|
||||||
|
<dimen name="default_button_size">60dp</dimen>
|
||||||
|
<dimen name="default_horizontal_spacing">32dp</dimen>
|
||||||
|
<dimen name="default_vertical_spacing">0dp</dimen>
|
||||||
|
<dimen name="default_dot_diameter">8dp</dimen>
|
||||||
|
<dimen name="default_dot_spacing">8dp</dimen>
|
||||||
|
</resources>
|
||||||
27
app/src/main/res/values/strings.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<resources>
|
||||||
|
<string name="app_name">AppLock Defender</string>
|
||||||
|
|
||||||
|
<string name="text_system">System App</string>
|
||||||
|
<string name="text_third">Third-party App</string>
|
||||||
|
<string name="text_setting">Setting</string>
|
||||||
|
|
||||||
|
<string name="setting_system">System Setting</string>
|
||||||
|
<string name="setting_rating">Rating this application</string>
|
||||||
|
<string name="setting_share">Share this application</string>
|
||||||
|
<string name="setting_password">Reset password</string>
|
||||||
|
<string name="setting_link">https://play.google.com/store/apps/details?id=</string>
|
||||||
|
|
||||||
|
<string name="text_locked">locked: %s</string>
|
||||||
|
<string name="text_unlocked">Unlocked: %s</string>
|
||||||
|
|
||||||
|
<string name="pwd_title">Set lock password</string>
|
||||||
|
<string name="pwd_content">Set your application lock password so that you can lock the application when you open it</string>
|
||||||
|
<string name="pwd_ok">OK</string>
|
||||||
|
<string name="pwd_success">Have successfully set the password</string>
|
||||||
|
<string name="pwd_err">Please input complete</string>
|
||||||
|
|
||||||
|
<string name="dialog_title">Please grant permissions for normal use applications</string>
|
||||||
|
<string name="dialog_content">1.Usage access\n2.Display on top of other apps</string>
|
||||||
|
<string name="dialog_go">GO</string>
|
||||||
|
<string name="no_permission">For normal use, please grant relevant permissions</string>
|
||||||
|
</resources>
|
||||||
9
app/src/main/res/values/themes.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<!-- Base application theme. -->
|
||||||
|
<style name="Base.Theme.TimberLock" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||||
|
<!-- Customize your light theme here. -->
|
||||||
|
<!-- <item name="colorPrimary">@color/my_light_primary</item> -->
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="Theme.TimberLock" parent="Base.Theme.TimberLock" />
|
||||||
|
</resources>
|
||||||
13
app/src/main/res/xml/backup_rules.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
Sample backup rules file; uncomment and customize as necessary.
|
||||||
|
See https://developer.android.com/guide/topics/data/autobackup
|
||||||
|
for details.
|
||||||
|
Note: This file is ignored for devices older that API 31
|
||||||
|
See https://developer.android.com/about/versions/12/backup-restore
|
||||||
|
-->
|
||||||
|
<full-backup-content>
|
||||||
|
<!--
|
||||||
|
<include domain="sharedpref" path="."/>
|
||||||
|
<exclude domain="sharedpref" path="device.xml"/>
|
||||||
|
-->
|
||||||
|
</full-backup-content>
|
||||||
19
app/src/main/res/xml/data_extraction_rules.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
Sample data extraction rules file; uncomment and customize as necessary.
|
||||||
|
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||||
|
for details.
|
||||||
|
-->
|
||||||
|
<data-extraction-rules>
|
||||||
|
<cloud-backup>
|
||||||
|
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
||||||
|
<include .../>
|
||||||
|
<exclude .../>
|
||||||
|
-->
|
||||||
|
</cloud-backup>
|
||||||
|
<!--
|
||||||
|
<device-transfer>
|
||||||
|
<include .../>
|
||||||
|
<exclude .../>
|
||||||
|
</device-transfer>
|
||||||
|
-->
|
||||||
|
</data-extraction-rules>
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.kitobochi.softapp.timberlock
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import org.junit.Assert.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Example local unit test, which will execute on the development machine (host).
|
||||||
|
*
|
||||||
|
* See [testing documentation](http://d.android.com/tools/testing).
|
||||||
|
*/
|
||||||
|
class ExampleUnitTest {
|
||||||
|
@Test
|
||||||
|
fun addition_isCorrect() {
|
||||||
|
assertEquals(4, 2 + 2)
|
||||||
|
}
|
||||||
|
}
|
||||||
14
build.gradle
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
buildscript{
|
||||||
|
dependencies{
|
||||||
|
classpath("com.applovin.quality:AppLovinQualityServiceGradlePlugin:+")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
alias(libs.plugins.androidApplication) apply false
|
||||||
|
alias(libs.plugins.jetbrainsKotlinAndroid) apply false
|
||||||
|
|
||||||
|
id("com.google.gms.google-services") version "4.3.15" apply false
|
||||||
|
id ("com.google.firebase.crashlytics") version "2.9.2" apply false
|
||||||
|
}
|
||||||
26
gradle/libs.versions.toml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
[versions]
|
||||||
|
agp = "8.1.3"
|
||||||
|
kotlin = "1.9.0"
|
||||||
|
coreKtx = "1.13.1"
|
||||||
|
junit = "4.13.2"
|
||||||
|
junitVersion = "1.1.5"
|
||||||
|
espressoCore = "3.5.1"
|
||||||
|
appcompat = "1.6.1"
|
||||||
|
material = "1.12.0"
|
||||||
|
activity = "1.8.0"
|
||||||
|
constraintlayout = "2.1.4"
|
||||||
|
|
||||||
|
[libraries]
|
||||||
|
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
|
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||||
|
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||||
|
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||||
|
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
||||||
|
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||||
|
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
|
||||||
|
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
|
||||||
|
|
||||||
|
[plugins]
|
||||||
|
androidApplication = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
jetbrainsKotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||||
|
|
||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
6
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#Mon May 20 11:31:32 CST 2024
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
26
settings.gradle
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
pluginManagement {
|
||||||
|
repositories {
|
||||||
|
google {
|
||||||
|
content {
|
||||||
|
includeGroupByRegex("com\\.android.*")
|
||||||
|
includeGroupByRegex("com\\.google.*")
|
||||||
|
includeGroupByRegex("androidx.*")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
maven { url "https://artifacts.applovin.com/android"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependencyResolutionManagement {
|
||||||
|
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
|
mavenCentral()
|
||||||
|
maven { url "https://artifact.bytedance.com/repository/pangle" }
|
||||||
|
maven { url = uri("https://dl-maven-android.mintegral.com/repository/mbridge_android_sdk_oversea") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.name = "TimberLock"
|
||||||
|
include ':app'
|
||||||