diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..aa724b7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+*.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
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..b589d56
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..80bddb0
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..0897082
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..fdf8d99
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..8978d23
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/.gitignore b/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
new file mode 100644
index 0000000..f570cae
--- /dev/null
+++ b/app/build.gradle.kts
@@ -0,0 +1,58 @@
+import java.util.Date
+import java.text.SimpleDateFormat
+
+val timestamp = SimpleDateFormat("MM_dd_HH_mm").format(Date())
+plugins {
+ id("com.android.application")
+ id("org.jetbrains.kotlin.android")
+ id("kotlin-kapt")
+}
+
+android {
+ namespace = "com.tool.app.protectorpro"
+ compileSdk = 34
+
+ defaultConfig {
+ applicationId = "com.tool.app.protectorpro"
+ minSdk = 23
+ targetSdk = 34
+ versionCode = 1
+ versionName = "1.0.0"
+ // setProperty("archivesBaseName", "AppLocker_V" + versionName + "(${versionCode})_$timestamp")
+ testInstrumentationRunner = "androidx.protectorpro.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ isMinifyEnabled = 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("de.hdodenhof:circleimageview:3.1.0")
+
+ implementation("androidx.core:core-ktx:1.9.0")
+ implementation("androidx.appcompat:appcompat:1.6.1")
+ implementation("com.google.android.material:material:1.11.0")
+ implementation("androidx.constraintlayout:constraintlayout:2.1.4")
+ implementation("androidx.room:room-ktx:2.6.1")
+ implementation("androidx.room:room-runtime:2.6.1")
+ kapt("androidx.room:room-compiler:2.6.1")
+
+
+}
\ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..9aeff70
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1,33 @@
+# 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
+ -keepclassmembers class com.tool.app.protectorpro.MyApplication{
+ public static final java.lang.String DB_Name;
+ public static final int DB_Version;
+ }
+ -keepclassmembers class *{
+ @androidx.room.Query ;
+ }
+
+ -keep class com.tool.app.protectorpro.mydb.MyDataBase { *; }
+ -keep class com.tool.app.protectorpro.listener.ListenerDao { *; }
+ -keep class com.tool.app.protectorpro.mydb.DataApp { *; }
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..061c1cf
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/tool/app/protectorpro/MyApplication.java b/app/src/main/java/com/tool/app/protectorpro/MyApplication.java
new file mode 100644
index 0000000..3854f89
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/MyApplication.java
@@ -0,0 +1,75 @@
+package com.tool.app.protectorpro;
+
+import android.app.Application;
+import android.content.Context;
+import android.content.SharedPreferences;
+
+import com.tool.app.protectorpro.mydb.DataApp;
+import com.tool.app.protectorpro.mydb.MyDataBase;
+import com.tool.app.protectorpro.tools.Common;
+import com.tool.app.protectorpro.tools.MyThread;
+
+public class MyApplication extends Application {
+ public static String spName = "share_name";
+
+ public static MyApplication appContext;
+
+ public static final int reqCodeUsage = 1;
+ public static final int DB_Version = 1;
+ public static final String Table_Name = "DataApp";
+ public static final int reqCodeOverlays = 2;
+ public static final String DB_Name = "app_locker";
+
+
+ public static SharedPreferences sp;
+ public static final String PWD_KEY = "locker_pwd";
+
+ public static SharedPreferences.Editor SpEditor;
+ public static final int type_0 = 0;
+
+ public static final int type_1 = 1;
+
+ public static final int type_2 = 2;
+ public static final String init_pwd_key = "pwd_type";
+
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ appContext = this;
+ initSp();
+ MyThread.runIO(() -> {
+ for (DataApp dataApp : MyDataBase.getInstance().getRoomDao().findApp()) {
+ Boolean needDelete = Common.delUnInstallApp(this, dataApp.getPackageName());
+ if (needDelete) {
+ MyDataBase.getInstance().getRoomDao().deleteData(dataApp);
+
+ }
+ }
+ });
+ String pwd = getPwd();
+ if (pwd.isEmpty()) {
+ Common.getAppList(this, false);
+ } else {
+ Common.getAppList(this, true);
+ }
+
+
+ }
+
+ public static void updatePwd(String pwd) {
+ SpEditor.putString(PWD_KEY, pwd);
+ SpEditor.apply();
+ }
+
+ public static String getPwd() {
+ return sp.getString(PWD_KEY, "");
+ }
+
+ private void initSp() {
+ sp = MyApplication.appContext.getSharedPreferences(spName, Context.MODE_PRIVATE);
+ SpEditor = sp.edit();
+ }
+
+
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/activity/ActivityComplete.kt b/app/src/main/java/com/tool/app/protectorpro/activity/ActivityComplete.kt
new file mode 100644
index 0000000..ad8bfd5
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/activity/ActivityComplete.kt
@@ -0,0 +1,26 @@
+package com.tool.app.protectorpro.activity
+
+import android.annotation.SuppressLint
+import android.graphics.Color
+import android.os.Bundle
+import android.view.View
+import androidx.appcompat.app.AppCompatActivity
+import com.tool.app.protectorpro.R
+
+class ActivityComplete : AppCompatActivity() {
+ @SuppressLint("MissingInflatedId")
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_complete)
+ findViewById(R.id.im_back).setOnClickListener { finish() }
+ initStatusBar()
+ }
+
+ private fun initStatusBar() {
+ val decorView = window.decorView
+ val flag = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ or View.SYSTEM_UI_FLAG_LAYOUT_STABLE)
+ decorView.systemUiVisibility = flag
+ window.statusBarColor = Color.TRANSPARENT
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tool/app/protectorpro/activity/ActivityMain.java b/app/src/main/java/com/tool/app/protectorpro/activity/ActivityMain.java
new file mode 100644
index 0000000..2820076
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/activity/ActivityMain.java
@@ -0,0 +1,272 @@
+package com.tool.app.protectorpro.activity;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.SearchView;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentStatePagerAdapter;
+import androidx.viewpager.widget.ViewPager;
+
+import com.google.android.material.bottomsheet.BottomSheetDialog;
+import com.google.android.material.tabs.TabLayout;
+import com.tool.app.protectorpro.MyApplication;
+
+import com.tool.app.protectorpro.R;
+import com.tool.app.protectorpro.databinding.ActivityMainLayoutBinding;
+import com.tool.app.protectorpro.databinding.TabViewBinding;
+import com.tool.app.protectorpro.listener.onPermssionListener;
+import com.tool.app.protectorpro.service.LockService;
+import com.tool.app.protectorpro.tools.Common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ActivityMain extends AppCompatActivity implements SearchView.OnQueryTextListener, onPermssionListener {
+ private ActivityMainLayoutBinding binding;
+
+ private DialogPer dialogPer;
+
+ List fragmentList = new ArrayList<>();
+
+ private void initStatusBar() {
+ View decorView = getWindow().getDecorView();
+ int flag = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+ decorView.setSystemUiVisibility(flag);
+ getWindow().setStatusBarColor(Color.TRANSPARENT);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = ActivityMainLayoutBinding.inflate(getLayoutInflater());
+ setContentView(binding.getRoot());
+ binding.searchItem.setOnQueryTextListener(this);
+ initStatusBar();
+ openPermission();
+ startService(new Intent(this, LockService.class));
+ initTab();
+ initClick();
+ }
+
+ private void initTab() {
+
+ String[] titles = new String[]{getString(R.string.text_system), getString(R.string.text_third), getString(R.string.text_recommended)};
+ Drawable[] tabIcon = new Drawable[]{getDrawable(R.drawable.bg_tab_sys), getDrawable(R.drawable.bg_tab_three), getDrawable(R.drawable.bg_tab_lock)};
+
+ fragmentList.add(FragmentMy.newInstance(1));
+ fragmentList.add(FragmentMy.newInstance(2));
+ fragmentList.add(FragmentMy.newInstance(3));
+
+ for (int i = 0; i < 3; i++) {
+ TabLayout.Tab tab = binding.tab.newTab();
+ TabViewBinding viewBinding = TabViewBinding.inflate(getLayoutInflater());
+
+ viewBinding.tvTabtext.setText(titles[i]);
+ viewBinding.ivTabIcon.setImageDrawable(tabIcon[i]);
+
+ tab.setCustomView(viewBinding.getRoot());
+ binding.tab.addTab(tab);
+ }
+ binding.viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+
+ }
+
+ @Override
+ public void onPageSelected(int position) {
+
+ TabLayout.Tab tabAt = binding.tab.getTabAt(position);
+ if (tabAt != null) {
+ binding.tvAppTabname.setText(titles[position]);
+ tabAt.select();
+ }
+ }
+
+ @Override
+ public void onPageScrollStateChanged(int state) {
+
+ }
+ });
+ binding.viewPager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
+ @NonNull
+ @Override
+ public Fragment getItem(int position) {
+ return fragmentList.get(position);
+ }
+
+ @Override
+ public int getCount() {
+ return fragmentList.size();
+ }
+
+ @Nullable
+ @Override
+ public CharSequence getPageTitle(int position) {
+ return titles[position];
+ }
+ });
+
+ TabLayout.Tab tabAt = binding.tab.getTabAt(1);
+ if (tabAt != null)
+ updateTab(tabAt, false);
+ binding.tab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
+ @Override
+ public void onTabSelected(TabLayout.Tab tab) {
+ updateTab(tab, true);
+ binding.viewPager.setCurrentItem(tab.getPosition());
+ }
+
+ @Override
+ public void onTabUnselected(TabLayout.Tab tab) {
+ updateTab(tab, false);
+ }
+
+ @Override
+ public void onTabReselected(TabLayout.Tab tab) {
+
+ }
+ });
+ }
+
+ private void initClick() {
+ binding.imSetPwd.setOnClickListener(v -> setBottomSheetView());
+ }
+
+ private void setBottomSheetView() {
+ if (isDestroyed())
+ return;
+
+ BottomSheetDialog bottomSheetDialog = new BottomSheetDialog(ActivityMain.this);
+ View bottomSheetView = LayoutInflater.from(ActivityMain.this).inflate(R.layout.set_bottom_sheet_layout, null);
+ bottomSheetDialog.setContentView(bottomSheetView);
+
+ ImageView ivClose = bottomSheetView.findViewById(R.id.ivClose);
+ TextView btnOption1 = bottomSheetView.findViewById(R.id.btnOption1);
+ TextView btnOption2 = bottomSheetView.findViewById(R.id.btnOption2);
+
+ ivClose.setOnClickListener(v -> bottomSheetDialog.dismiss());
+
+ // 按钮1点击事件
+ btnOption1.setOnClickListener(v -> {
+ Intent intent = new Intent(ActivityMain.this, ActivitySetPwd.class);
+ intent.putExtra(MyApplication.init_pwd_key, MyApplication.type_1);
+ startActivity(intent);
+ bottomSheetDialog.dismiss();
+ });
+
+ // 按钮2点击事件
+ btnOption2.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ bottomSheetDialog.dismiss();
+ }
+ });
+
+ bottomSheetDialog.show();
+ }
+
+ private void updateTab(TabLayout.Tab tab, boolean isSelected) {
+ View customView = tab.getCustomView();
+ if (customView == null) return;
+ TextView tv = customView.findViewById(R.id.tv_tabtext);
+ tv.setSelected(isSelected);
+ ImageView iv = customView.findViewById(R.id.iv_tab_icon);
+
+ iv.setSelected(isSelected);
+
+ }
+
+ private boolean checkPermission() {
+ boolean b = Common.checkPermission(this);
+ boolean canDrawOverlays = Common.getCanDrawOverlays(this);
+ return b && canDrawOverlays;
+ }
+
+ private void openPermission() {
+ if (!checkPermission()) {
+ if (dialogPer == null) {
+ dialogPer = DialogPer.newInstance();
+ dialogPer.setListener(this);
+ }
+ dialogPer.show(getSupportFragmentManager(), "");
+ }
+
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == MyApplication.reqCodeUsage) {
+ if (checkPermission()) {
+ dialogPer.dismiss();
+ return;
+ }
+ boolean canDrawOverlays = Common.getCanDrawOverlays(this);
+ if (!canDrawOverlays) {
+ Common.goDrawOverlays(this, MyApplication.reqCodeOverlays);
+ }
+ } else if (requestCode == MyApplication.reqCodeOverlays) {
+ if (checkPermission()) {
+ dialogPer.dismiss();
+ } else {
+ Toast.makeText(this, getString(R.string.text_permission_hint), Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+
+ @Override
+ public void onToSetting() {
+ boolean b = Common.checkPermission(this);
+ boolean canDrawOverlays = Common.getCanDrawOverlays(this);
+
+ if (!b) {
+ Common.toSetUsagePermission(ActivityMain.this, MyApplication.reqCodeUsage);
+ } else {
+
+ if (!canDrawOverlays) {
+ Common.goDrawOverlays(this, MyApplication.reqCodeOverlays);
+ }
+ }
+
+
+ }
+
+ private void filterApps(String query) {
+ // 获取当前显示的Fragment
+ int position = binding.viewPager.getCurrentItem();
+ Fragment fragment = fragmentList.get(position);
+
+ // 如果Fragment是FragmentMy,则调用其filter方法
+ if ((fragment instanceof FragmentMy)) {
+ ((FragmentMy) fragment).filter(query);
+ }
+ }
+
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+
+ filterApps(query);
+
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ filterApps(newText);
+ return true;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tool/app/protectorpro/activity/ActivitySetPwd.java b/app/src/main/java/com/tool/app/protectorpro/activity/ActivitySetPwd.java
new file mode 100644
index 0000000..0224305
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/activity/ActivitySetPwd.java
@@ -0,0 +1,283 @@
+package com.tool.app.protectorpro.activity;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.InputType;
+import android.text.TextWatcher;
+import android.util.Log;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.tool.app.protectorpro.MyApplication;
+import com.tool.app.protectorpro.R;
+import com.tool.app.protectorpro.customerview.MyLockView;
+import com.tool.app.protectorpro.customerview.MyPasswordInputView;
+import com.tool.app.protectorpro.databinding.ActivitySetPwdBinding;
+import com.tool.app.protectorpro.listener.ListenerLock;
+
+public class ActivitySetPwd extends AppCompatActivity {
+
+ private static final String TAG = "ActivitySetPwd";
+
+ private ActivitySetPwdBinding binding;
+ private int type;
+ private MyPasswordInputView passwordInputView;
+ private StringBuilder surePassword = new StringBuilder();
+ private StringBuilder tempPassword = new StringBuilder();
+
+ private void initStatusBar() {
+ View decorView = getWindow().getDecorView();
+ int flag = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+ decorView.setSystemUiVisibility(flag);
+ getWindow().setStatusBarColor(Color.TRANSPARENT);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = ActivitySetPwdBinding.inflate(getLayoutInflater());
+ initStatusBar();
+ setContentView(binding.getRoot());
+ passwordInputView = binding.layoutEt;
+ type = getIntent().getIntExtra(MyApplication.init_pwd_key, MyApplication.type_0);
+ initView();
+ initInput();
+ initClick();
+ initKeyboard();
+ }
+
+ private void initView() {
+ // 0 设置 1 修改 2 确认
+ switch (type) {
+ case MyApplication.type_0:
+ binding.imBack.setVisibility(View.GONE);
+ binding.tvPassName.setText(R.string.text_original_pwd);
+ // binding.tvTitle.setText(getString(R.string.text_original_pwd));
+ binding.tvSub.setText(getString(R.string.text_original_pwd_describe));
+ // binding.tvContinue.setText(getString(R.string.text_continue));
+ break;
+ case MyApplication.type_1:
+ binding.imBack.setVisibility(View.VISIBLE);
+ binding.tvPassName.setText(R.string.sheet_change_password);
+ // binding.tvTitle.setText(getString(R.string.text_change_pwd));
+ binding.tvSub.setText(getString(R.string.text_change_pwd_sub));
+ // binding.tvContinue.setText(getString(R.string.text_save));
+ break;
+ case MyApplication.type_2:
+ binding.imBack.setVisibility(View.VISIBLE);
+ binding.tvPassName.setText(R.string.text_confirm_pwd);
+ // binding.tvTitle.setText(getString(R.string.text_confirm_pwd));
+ // binding.tvSub.setText(getString(R.string.text_change_pwd_sub));
+ // binding.tvContinue.setText(getString(R.string.text_save));
+ break;
+ }
+ updateEditText();
+ }
+
+ private void initInput() {
+ for (int i = 0; i < binding.layoutEt.getChildCount(); i++) {
+ EditText editText = (EditText) binding.layoutEt.getChildAt(i);
+ EditText nextEditText = null;
+ if ((i + 1) < binding.layoutEt.getChildCount()) {
+ nextEditText = (EditText) binding.layoutEt.getChildAt(i + 1);
+ }
+
+ editText.setInputType(InputType.TYPE_NULL);
+
+ EditText finalNextEditText = nextEditText;
+ editText.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ if (s.length() > 0 && finalNextEditText != null) {
+ finalNextEditText.requestFocus();
+ }
+ }
+ });
+ }
+
+ }
+
+ private void initKeyboard() {
+ binding.lockSetPassword.setPinLockListener(new ListenerLock() {
+ @Override
+ public void onInPutComplete(String pin) {
+ Log.d(TAG, "onInPutComplete: " + pin);
+
+ if (type == MyApplication.type_0 || type == MyApplication.type_1) {
+ Log.d(TAG, "在设置界面");
+ if (pin.length() == 4) {
+ Log.d(TAG, "跳转到二次");
+ type = MyApplication.type_2;
+ initView();
+ }
+
+ } else {
+ initView();
+ Log.d(TAG, "在二次确认界面");
+ checkPassword();
+ }
+ }
+
+ @Override
+ public void onNumberClickComplete(String keyValue) {
+ Log.d(TAG, "onNumberClickComplete: " + keyValue);
+
+ if (type == MyApplication.type_0 || type == MyApplication.type_1) {
+
+ if (tempPassword.length() < 4) {
+ tempPassword.append(keyValue);
+ passwordInputView.setInput(tempPassword);
+ Log.d(TAG, "tempPassword: " + tempPassword.toString());
+ }
+
+ } else if (type == MyApplication.type_2) {
+ if (surePassword.length() < 4) {
+ surePassword.append(keyValue);
+ passwordInputView.setInput(surePassword);
+ Log.d(TAG, "passwordBuilder: " + surePassword.toString());
+ }
+ }
+ }
+
+ @Override
+ public void onKeyBordDelete(int pin) {
+
+ Log.d("fsdafsd", pin + "__dfs");
+ if (pin == 1) {
+ surePassword.setLength(0);
+ tempPassword.setLength(0);
+ initView();
+ }
+
+ if (type == MyApplication.type_2) {
+ passwordInputView.setInput(surePassword);
+ // 删除 surePassword 中的字符
+ if (surePassword.length() > 0) {
+ surePassword.deleteCharAt(surePassword.length() - 1);
+ passwordInputView.deleteLastInput();
+
+
+ }
+ // 如果 surePassword 被删完了,将 type 设置为 type_0,并重新初始化视图和更新 EditText
+ if (surePassword.length() == 0) {
+ type = MyApplication.type_0;
+ initView();
+ }
+ } else if (type == MyApplication.type_0 || type == MyApplication.type_1) {
+ passwordInputView.setInput(tempPassword);
+ // 删除 tempPassword 中的字符
+ if (tempPassword.length() > 0) {
+ tempPassword.deleteCharAt(tempPassword.length() - 1);
+ passwordInputView.deleteLastInput();
+
+ }
+ }
+ Log.d(TAG, "onKeyBordDelete: Deleted last input. tempPassword: " + tempPassword.toString() + ", surePassword: " + surePassword.toString());
+ }
+
+
+ });
+ Log.d(TAG, "initKeyboard: Initialized pin lock listener");
+ }
+
+ private void initClick() {
+ binding.imBack.setOnClickListener(v -> {
+ finish();
+ Log.d(TAG, "onClick: Back button clicked");
+ });
+
+ binding.tvContinue.setOnClickListener(v -> {
+ // Placeholder for specific logic
+ Log.d(TAG, "onClick: Continue button clicked");
+ });
+ Log.d(TAG, "initClick: Initialized click listeners");
+ }
+
+ private void checkPassword() {
+ if (surePassword.toString().equals(tempPassword.toString())) {
+ savePassword();
+ Log.d(TAG, "checkPassword: Passwords matched, saving password");
+ } else {
+
+ if ((surePassword.length() == tempPassword.length())) {
+ Toast.makeText(ActivitySetPwd.this, getString(R.string.text_pass_sure), Toast.LENGTH_SHORT).show();
+
+ }
+ Log.d(TAG, "checkPassword: Passwords do not match, showing toast");
+ }
+ }
+
+ private void savePassword() {
+ String password = surePassword.toString();
+ if (password.length() == 4) {
+ MyApplication.updatePwd(password);
+
+ switch (type) {
+ case MyApplication.type_0:
+ case MyApplication.type_2:
+ startActivity(new Intent(ActivitySetPwd.this, ActivityMain.class));
+ break;
+ case MyApplication.type_1:
+ startActivity(new Intent(ActivitySetPwd.this, ActivityComplete.class));
+ break;
+ }
+ finish();
+ Log.d(TAG, "savePassword: Password saved successfully");
+ } else {
+ Toast.makeText(ActivitySetPwd.this, getString(R.string.text_hint), Toast.LENGTH_SHORT).show();
+ Log.d(TAG, "savePassword: Password length is not 4, showing hint toast");
+ }
+ }
+
+
+ private void updateEditText() {
+ for (int i = 0; i < binding.layoutEt.getChildCount(); i++) {
+ EditText editText = (EditText) binding.layoutEt.getChildAt(i);
+ editText.setText("");
+ }
+
+ // 根据当前的 type 决定显示哪个密码
+ String displayText = "";
+ if (type == MyApplication.type_0 || type == MyApplication.type_1) {
+
+ displayText = tempPassword.toString();
+ } else if (type == MyApplication.type_2) {
+ displayText = surePassword.toString();
+ }
+
+ Log.d("dsafsdaf", tempPassword.toString() + "___" + surePassword.toString());
+ // 设置 EditText 的内容
+ for (int i = 0; i < displayText.length(); i++) {
+ if (i < binding.layoutEt.getChildCount()) {
+ EditText editText = (EditText) binding.layoutEt.getChildAt(i);
+ editText.setText(String.valueOf(displayText.charAt(i)));
+ }
+ }
+
+ // 重新设置光标位置
+ if (binding.layoutEt.getChildCount() > 0) {
+ EditText editText = (EditText) binding.layoutEt.getChildAt(0);
+ editText.requestFocus();
+ }
+
+ Log.d(TAG, "updateEditText: Updated EditText fields");
+ }
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tool/app/protectorpro/activity/ActivityWel.java b/app/src/main/java/com/tool/app/protectorpro/activity/ActivityWel.java
new file mode 100644
index 0000000..e53814b
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/activity/ActivityWel.java
@@ -0,0 +1,62 @@
+package com.tool.app.protectorpro.activity;
+
+import android.content.Intent;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.os.CountDownTimer;
+import android.view.View;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.tool.app.protectorpro.MyApplication;
+import com.tool.app.protectorpro.databinding.ActivityWelBinding;
+
+public class ActivityWel extends AppCompatActivity {
+
+ private ActivityWelBinding binding;
+
+
+ private CountDownTimer countDownTimer;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ binding = ActivityWelBinding.inflate(getLayoutInflater());
+ setContentView(binding.getRoot());
+ initBar();
+
+ countDownTimer = new CountDownTimer(2000L, 500L) {
+ @Override
+ public void onTick(long millisUntilFinished) {
+
+ }
+
+ @Override
+ public void onFinish() {
+ String pwd = MyApplication.getPwd();
+ if (pwd.isEmpty()) {
+ startActivity(new Intent(ActivityWel.this, ActivitySetPwd.class));
+ } else {
+ startActivity(new Intent(ActivityWel.this, ActivityMain.class));
+ }
+ finish();
+
+ }
+ };
+ countDownTimer.start();
+ }
+
+ private void initBar() {
+ View decorView = getWindow().getDecorView();
+ int flag = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ | View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
+ decorView.setSystemUiVisibility(flag);
+ getWindow().setStatusBarColor(Color.TRANSPARENT);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ countDownTimer.cancel();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tool/app/protectorpro/activity/DialogPer.java b/app/src/main/java/com/tool/app/protectorpro/activity/DialogPer.java
new file mode 100644
index 0000000..1c46da8
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/activity/DialogPer.java
@@ -0,0 +1,93 @@
+package com.tool.app.protectorpro.activity;
+
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.DialogFragment;
+
+import com.tool.app.protectorpro.R;
+import com.tool.app.protectorpro.databinding.DialogPermisBinding;
+import com.tool.app.protectorpro.listener.onPermssionListener;
+import com.tool.app.protectorpro.tools.Common;
+
+public class DialogPer extends DialogFragment {
+ private DialogPermisBinding layoutPermissionBinding;
+
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
+ layoutPermissionBinding = DialogPermisBinding.inflate(getLayoutInflater());
+
+ getDialog().setCanceledOnTouchOutside(false);
+ getDialog().setCancelable(false);
+
+ final Window window = getDialog().getWindow();
+ window.setBackgroundDrawableResource(R.color.transparent);
+ window.getDecorView().setPadding(0, 0, 0, 0);
+ WindowManager.LayoutParams wlp = window.getAttributes();
+ wlp.gravity = Gravity.CENTER;
+ wlp.width = WindowManager.LayoutParams.MATCH_PARENT;
+ wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
+ window.setAttributes(wlp);
+
+
+ layoutPermissionBinding.llSet1.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ if (!layoutPermissionBinding.tvSelect.isSelected()) {
+ listener.onToSetting();
+ }
+
+ }
+ });
+ layoutPermissionBinding.llSet2.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ listener.onToSetting();
+ }
+ });
+
+
+ return layoutPermissionBinding.getRoot();
+ }
+
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ initView();
+ }
+
+ private onPermssionListener listener;
+
+ public void setListener(onPermssionListener listener) {
+ this.listener = listener;
+ }
+
+ public static DialogPer newInstance() {
+ return new DialogPer();
+ }
+
+ private void initView() {
+ boolean b = Common.checkPermission(getActivity());
+ if (!b) {
+ layoutPermissionBinding.llSet1.setSelected(false);
+ layoutPermissionBinding.ivSet1.setVisibility(View.INVISIBLE);
+ } else {
+ layoutPermissionBinding.diaCheck.setSelected(true);
+ layoutPermissionBinding.llSet2.setSelected(false);
+ layoutPermissionBinding.ivSet1.setVisibility(View.VISIBLE);
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/activity/FragmentMy.java b/app/src/main/java/com/tool/app/protectorpro/activity/FragmentMy.java
new file mode 100644
index 0000000..b3be39b
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/activity/FragmentMy.java
@@ -0,0 +1,82 @@
+package com.tool.app.protectorpro.activity;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.appcompat.widget.SearchView;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+
+import com.tool.app.protectorpro.databinding.FragmentMyBinding;
+import com.tool.app.protectorpro.listadapter.AdapterAllApp;
+import com.tool.app.protectorpro.mydb.DataApp;
+import com.tool.app.protectorpro.mydb.MyDataBase;
+import com.tool.app.protectorpro.tools.MyThread;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class FragmentMy extends Fragment {
+ private int appType;
+ private FragmentMyBinding binding;
+ private static final String ARG_PARAM1 = "key_data";
+ private AdapterAllApp adapterAllApp;
+
+ public FragmentMy() {
+ }
+
+
+ public static FragmentMy newInstance(int appType) {
+ FragmentMy fragment = new FragmentMy();
+ Bundle args = new Bundle();
+ args.putInt(ARG_PARAM1, appType);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ appType = getArguments().getInt(ARG_PARAM1);
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+
+ binding = FragmentMyBinding.inflate(getLayoutInflater());
+
+ adapterAllApp = new AdapterAllApp(requireContext());
+ binding.listApp.setAdapter(adapterAllApp);
+ binding.listApp.setLayoutManager(new LinearLayoutManager(requireContext()));
+
+ MyThread.runIO(() -> {
+ List data;
+ if (appType == 1) {
+ data = MyDataBase.getInstance().getRoomDao().findByType(true, false);
+ } else if (appType == 2) {
+ data = MyDataBase.getInstance().getRoomDao().findByType(false, false);
+ } else if (appType == 3) {
+ data = MyDataBase.getInstance().getRoomDao().findByLock(true);
+ } else {
+ data = new ArrayList<>();
+ }
+
+ MyThread.runUI(() -> {
+ adapterAllApp.updateSyStemApp(data);
+ });
+ });
+
+ return binding.getRoot();
+ }
+ public void filter(String query) {
+ if (adapterAllApp != null) {
+ adapterAllApp.filter(query);
+ }
+ }
+
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/customerview/CustomBundle.kt b/app/src/main/java/com/tool/app/protectorpro/customerview/CustomBundle.kt
new file mode 100644
index 0000000..e8bd318
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/customerview/CustomBundle.kt
@@ -0,0 +1,19 @@
+package com.tool.app.protectorpro.customerview
+
+import android.graphics.drawable.Drawable
+
+class CustomBundle {
+ @JvmField
+ var textColor = 0
+ @JvmField
+ var textSize = 0
+
+
+ var isShowDeleteButton = false
+ @JvmField
+ var buttonSize = 0
+ @JvmField
+ var backgroundDrawable: Drawable? = null
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tool/app/protectorpro/customerview/LockSpace.java b/app/src/main/java/com/tool/app/protectorpro/customerview/LockSpace.java
new file mode 100644
index 0000000..8a3faf3
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/customerview/LockSpace.java
@@ -0,0 +1,45 @@
+package com.tool.app.protectorpro.customerview;
+
+import android.graphics.Rect;
+import android.view.View;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+public class LockSpace extends RecyclerView.ItemDecoration {
+
+ private final int HSpace;
+
+ private final int mSpanCount;
+ private final boolean mInclude;
+ private final int mVSpace;
+
+ public LockSpace(int horizontalSpaceWidth, int verticalSpaceHeight, int spanCount, boolean includeEdge) {
+ this.HSpace = horizontalSpaceWidth;
+ this.mVSpace = verticalSpaceHeight;
+ this.mSpanCount = spanCount;
+ this.mInclude = includeEdge;
+ }
+
+ @Override
+ public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
+
+ int position = parent.getChildAdapterPosition(view);
+ int 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;
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/customerview/MyDots.java b/app/src/main/java/com/tool/app/protectorpro/customerview/MyDots.java
new file mode 100644
index 0000000..b257cab
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/customerview/MyDots.java
@@ -0,0 +1,102 @@
+package com.tool.app.protectorpro.customerview;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.LinearLayout;
+
+import androidx.core.view.ViewCompat;
+
+import com.tool.app.protectorpro.R;
+import com.tool.app.protectorpro.tools.Common;
+
+
+public class MyDots extends LinearLayout {
+
+
+ private static final int DEFAULT_PIN_LENGTH = 4;
+ private int mPinLength;
+
+
+ private int mPreviousLength;
+ private int mDotDiameter;
+ private int mDotSpacing;
+ private int mFillDrawable;
+ private int mEmptyDrawable;
+
+ private void initView(Context context) {
+ ViewCompat.setLayoutDirection(this, ViewCompat.LAYOUT_DIRECTION_LTR);
+ for (int i = 0; i < mPinLength; i++) {
+ View dot = new View(context);
+ emptyDot(dot);
+
+ LayoutParams params = new LayoutParams(mDotDiameter,
+ mDotDiameter);
+ params.setMargins(mDotSpacing, 0, mDotSpacing, 0);
+ dot.setLayoutParams(params);
+
+ addView(dot);
+ }
+
+ }
+
+ public MyDots(Context context) {
+ this(context, null);
+ }
+
+ public MyDots(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public MyDots(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+
+ TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyLock);
+
+ try {
+ mDotDiameter = (int) typedArray.getDimension(R.styleable.MyLock_dotDiameter, Common.getPx(getContext(), R.dimen.default_dot_diameter));
+ mDotSpacing = (int) typedArray.getDimension(R.styleable.MyLock_dotSpacing, Common.getPx(getContext(), R.dimen.default_dot_spacing));
+ mFillDrawable = typedArray.getResourceId(R.styleable.MyLock_dotFilledBackground,
+ R.drawable.oval_black);
+ mEmptyDrawable = typedArray.getResourceId(R.styleable.MyLock_dotEmptyBackground,
+ R.drawable.pwd_bg);
+ mPinLength = typedArray.getInt(R.styleable.MyLock_pinLength, DEFAULT_PIN_LENGTH);
+ } finally {
+ typedArray.recycle();
+ }
+
+ initView(context);
+ }
+
+
+ private void emptyDot(View dot) {
+ dot.setBackgroundResource(mEmptyDrawable);
+ dot.animate().scaleX(1.0f).scaleY(1.0f).setDuration(100).start();
+ }
+
+ private void fillDot(View dot) {
+ dot.setBackgroundResource(mFillDrawable);
+ dot.animate().scaleX(1.2f).scaleY(1.2f).setDuration(100).start();
+ }
+
+
+ void updateDot(int length) {
+ if (length > 0) {
+ if (length > mPreviousLength) {
+ fillDot(getChildAt(length - 1));
+ } else {
+ emptyDot(getChildAt(length));
+ }
+ mPreviousLength = length;
+ } else {
+ for (int i = 0; i < getChildCount(); i++) {
+ View v = getChildAt(i);
+ emptyDot(v);
+ }
+ mPreviousLength = 0;
+ }
+
+ }
+
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/customerview/MyLockView.java b/app/src/main/java/com/tool/app/protectorpro/customerview/MyLockView.java
new file mode 100644
index 0000000..e2ab51c
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/customerview/MyLockView.java
@@ -0,0 +1,226 @@
+package com.tool.app.protectorpro.customerview;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.GridLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.tool.app.protectorpro.MyApplication;
+import com.tool.app.protectorpro.R;
+import com.tool.app.protectorpro.listadapter.AdapterLockView;
+import com.tool.app.protectorpro.listener.ListenerLock;
+import com.tool.app.protectorpro.tools.Common;
+
+public class MyLockView extends RecyclerView {
+ private String mPin = "";
+ private int mPinLength;
+ private int mHorizontalSpacing, mVerticalSpacing;
+ private int mTextColor;
+ private int mTextSize, mButtonSize;
+ private Drawable mButtonBgDraw;
+ private AdapterLockView mAdapter;
+ private ListenerLock mPinLockListener;
+ private CustomBundle mCustomBundle;
+
+ private boolean mShowDelete;
+ private static final int DEFAULT_PWD_LENGTH = 4;
+ private MyDots mMyDots;
+
+
+ private AdapterLockView.OnNumberClickListener numberClickListener
+ = new AdapterLockView.OnNumberClickListener() {
+ @Override
+ public void onNumberClicked(int keyValue) {
+
+
+ if (mPinLockListener != null) {
+ mPinLockListener.onNumberClickComplete(String.valueOf(keyValue));
+ }
+
+ if (mPin.length() < getPinLength()) {
+ mPin = mPin.concat(String.valueOf(keyValue));
+
+ if (isIndicatorDotsAttached()) {
+ mMyDots.updateDot(mPin.length());
+
+ }
+
+ if (mPin.length() == 1) {
+ mAdapter.setPinLength(mPin.length());
+ mAdapter.notifyItemChanged(mAdapter.getItemCount() - 1);
+ }
+
+ if (mPinLockListener != null) {
+ if (mPin.length() == mPinLength) {
+ mPinLockListener.onInPutComplete(mPin);
+ } else {
+
+ }
+ }
+ } else {
+ if (!isShowDeleteButton()) {
+ resetPinLockView();
+ mPin = mPin.concat(String.valueOf(keyValue));
+
+ if (isIndicatorDotsAttached()) {
+ mMyDots.updateDot(mPin.length());
+ }
+
+ if (mPinLockListener != null) {
+// mPinLockListener.onPinChange(mPin.length(), mPin);
+ }
+
+ } else {
+ if (mPinLockListener != null) {
+ mPinLockListener.onInPutComplete(mPin);
+ }
+ }
+ }
+ }
+ };
+
+ private AdapterLockView.OnDeleteClickListener mOnDeleteClickListener
+ = new AdapterLockView.OnDeleteClickListener() {
+ @Override
+ public void onDeleteClicked() {
+ Log.d("key_delete", mPin.length() + "...");
+
+ if (!mPin.isEmpty()) {
+ mPinLockListener.onKeyBordDelete(mPin.length());
+
+ mPin = mPin.substring(0, mPin.length() - 1);
+
+ if (isIndicatorDotsAttached()) {
+ mMyDots.updateDot(mPin.length());
+
+ }
+
+ if (mPin.length() == 0) {
+ mAdapter.setPinLength(mPin.length());
+ mAdapter.notifyItemChanged(mAdapter.getItemCount() - 1);
+ }
+
+ if (mPinLockListener != null) {
+ if (mPin.length() == 0) {
+// mPinLockListener.onEmpty();
+ clearInternalPin();
+ } else {
+// mPinLockListener.onPinChange(mPin.length(), mPin);
+ }
+ }
+ } else {
+ if (mPinLockListener != null) {
+
+
+
+ }
+ }
+ }
+
+ };
+
+ public MyLockView(Context context) {
+ super(context);
+ init(null, 0);
+ }
+
+ public MyLockView(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ init(attrs, 0);
+ }
+
+ public MyLockView(Context context, @Nullable AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(attrs, defStyle);
+ }
+
+ private void init(AttributeSet attributeSet, int defStyle) {
+
+ TypedArray typedArray = getContext().obtainStyledAttributes(attributeSet, R.styleable.MyLock);
+
+ try {
+ mPinLength = typedArray.getInt(R.styleable.MyLock_pinLength, DEFAULT_PWD_LENGTH);
+ mHorizontalSpacing = (int) typedArray.getDimension(R.styleable.MyLock_keypadHorizontalSpacing, Common.getPx(getContext(), R.dimen.default_horizontal_spacing));
+ mVerticalSpacing = (int) typedArray.getDimension(R.styleable.MyLock_keypadVerticalSpacing, Common.getPx(getContext(), R.dimen.default_vertical_spacing));
+ mTextColor = typedArray.getColor(R.styleable.MyLock_keypadTextColor, Common.getColor(getContext(), R.color.color_keyboard_num));
+ mTextSize = (int) typedArray.getDimension(R.styleable.MyLock_keypadTextSize, Common.getPx(getContext(), R.dimen.default_text_size));
+ mButtonSize = (int) typedArray.getDimension(R.styleable.MyLock_keypadButtonSize, Common.getPx(getContext(), R.dimen.default_button_size));
+ mButtonBgDraw = typedArray.getDrawable(R.styleable.MyLock_keypadButtonBackgroundDrawable);
+
+ mShowDelete = typedArray.getBoolean(R.styleable.MyLock_keypadShowDeleteButton, true);
+ } finally {
+ typedArray.recycle();
+ }
+
+ mCustomBundle = new CustomBundle();
+ mCustomBundle.textColor = mTextColor;
+ mCustomBundle.textSize = mTextSize;
+ mCustomBundle.buttonSize = mButtonSize;
+ mCustomBundle.backgroundDrawable = mButtonBgDraw;
+ mCustomBundle.setShowDeleteButton(mShowDelete);
+
+
+ initView();
+ }
+
+ private void initView() {
+ mAdapter = new AdapterLockView();
+ setLayoutManager(new GridLayoutManager(getContext(), 3));
+
+
+ mAdapter.setOnItemClickListener(numberClickListener);
+ mAdapter.setOnDeleteClickListener(mOnDeleteClickListener);
+ mAdapter.setCustomizationOptions(mCustomBundle);
+ setAdapter(mAdapter);
+
+ addItemDecoration(new LockSpace(mHorizontalSpacing, mVerticalSpacing, 3, false));
+ setOverScrollMode(OVER_SCROLL_NEVER);
+ }
+
+
+ public void setPinLockListener(ListenerLock pinLockListener) {
+ this.mPinLockListener = pinLockListener;
+ }
+
+ public int getPinLength() {
+ return mPinLength;
+ }
+
+ public boolean isShowDeleteButton() {
+ return mShowDelete;
+ }
+
+ private void clearInternalPin() {
+ mPin = "";
+ }
+
+
+ public void resetPinLockView() {
+ clearInternalPin();
+ mAdapter.setPinLength(mPin.length());
+ mAdapter.notifyItemChanged(mAdapter.getItemCount() - 1);
+
+ if (mMyDots != null) {
+ mMyDots.updateDot(mPin.length());
+ }
+ }
+
+ public boolean isIndicatorDotsAttached() {
+ return mMyDots != null;
+ }
+
+
+ public void setPinLength(){
+
+
+ }
+
+ public void attachIndicatorDots(MyDots mMyDots) {
+ this.mMyDots = mMyDots;
+ }
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/customerview/MyPasswordInputView.java b/app/src/main/java/com/tool/app/protectorpro/customerview/MyPasswordInputView.java
new file mode 100644
index 0000000..60067c8
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/customerview/MyPasswordInputView.java
@@ -0,0 +1,85 @@
+package com.tool.app.protectorpro.customerview;
+
+import android.content.Context;
+import android.text.InputFilter;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+import androidx.annotation.Nullable;
+
+import com.tool.app.protectorpro.R;
+
+public class MyPasswordInputView extends LinearLayout {
+
+ private EditText[] mEditTexts = new EditText[4];
+
+ public MyPasswordInputView(Context context) {
+ this(context, null);
+ }
+
+ public MyPasswordInputView(Context context, @Nullable AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public MyPasswordInputView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ LayoutInflater.from(context).inflate(R.layout.custom_password_input_view, this, true);
+ mEditTexts[0] = findViewById(R.id.et1);
+ mEditTexts[1] = findViewById(R.id.et2);
+ mEditTexts[2] = findViewById(R.id.et3);
+ mEditTexts[3] = findViewById(R.id.et4);
+ setupEditTexts();
+ }
+
+ private void setupEditTexts() {
+ for (EditText editText : mEditTexts) {
+ editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(1)});
+ }
+ }
+
+
+ public void appendInput(String input) {
+ String currentInput = getInput();
+ String newInput = currentInput + input;
+
+ clearInput();
+
+ for (int i = 0; i < newInput.length() && i < mEditTexts.length; i++) {
+ mEditTexts[i].setText(String.valueOf(newInput.charAt(i)));
+ }
+ }
+
+ public void deleteLastInput() {
+ for (int i = mEditTexts.length - 1; i >= 0; i--) {
+ EditText editText = mEditTexts[i];
+ if (editText.getText().length() > 0) {
+ editText.setText("");
+ break;
+ }
+ }
+ }
+
+ public String getInput() {
+ StringBuilder stringBuilder = new StringBuilder();
+ for (EditText editText : mEditTexts) {
+ stringBuilder.append(editText.getText().toString());
+ }
+ return stringBuilder.toString();
+ }
+
+ public void clearInput() {
+ for (EditText editText : mEditTexts) {
+ editText.setText("");
+ }
+ }
+
+ // 新增一个方法来设置输入内容
+ public void setInput(StringBuilder input) {
+ clearInput();
+ for (int i = 0; i < input.length() && i < mEditTexts.length; i++) {
+ mEditTexts[i].setText(String.valueOf(input.charAt(i)));
+ }
+ }
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/listadapter/AdapterAllApp.java b/app/src/main/java/com/tool/app/protectorpro/listadapter/AdapterAllApp.java
new file mode 100644
index 0000000..52ef817
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/listadapter/AdapterAllApp.java
@@ -0,0 +1,134 @@
+package com.tool.app.protectorpro.listadapter;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+import android.util.Log;
+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.annotation.NonNull;
+import androidx.appcompat.widget.SwitchCompat;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.tool.app.protectorpro.R;
+import com.tool.app.protectorpro.mydb.DataApp;
+import com.tool.app.protectorpro.mydb.MyDataBase;
+import com.tool.app.protectorpro.tools.MyThread;
+
+import java.util.ArrayList;
+import java.util.List;
+public class AdapterAllApp extends RecyclerView.Adapter {
+
+ private List list = new ArrayList<>();
+ private List filterList = new ArrayList<>();
+ private Context mContext;
+ private PackageManager packageManager;
+
+ public AdapterAllApp(Context context) {
+ mContext = context;
+ packageManager = context.getPackageManager();
+ }
+
+ public void updateSyStemApp(List infoList) {
+ list.clear();
+ filterList.clear();
+ if (infoList != null && !infoList.isEmpty()) {
+ list.addAll(infoList);
+ filterList.addAll(list);
+ Log.d("AdapterAllApp", "List updated, size: " + list.size());
+ } else {
+ Log.d("AdapterAllApp", "Received empty or null list");
+ }
+ notifyDataSetChanged();
+ }
+
+ public void filter(String query) {
+ filterList.clear();
+ if (query.isEmpty()) {
+ filterList.addAll(list);
+ if (!list.isEmpty()) {
+ Log.d("AdapterAllApp", "List size: " + list.size());
+ Log.d("AdapterAllApp", "First item: " + list.get(0).getAppName());
+ } else {
+ Log.d("AdapterAllApp", "List is empty");
+ }
+ } else {
+ for (DataApp item : list) {
+ if (item.getAppName().toLowerCase().contains(query.toLowerCase())) {
+ filterList.add(item);
+ Log.d("AdapterAllApp", "Filtered item: " + item.getAppName());
+ }
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ @NonNull
+ @Override
+ public AppViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ AppViewHolder appViewHolder = new AppViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_systapp, parent, false));
+ return appViewHolder;
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull AppViewHolder holder, int position) {
+ holder.switchCompat.setOnCheckedChangeListener(null);
+ DataApp dataApp = filterList.get(position); // 使用filterList
+ String appName = dataApp.getAppName();
+ boolean lock = dataApp.isLock();
+ holder.switchCompat.setChecked(lock);
+ holder.switchCompat.setOnCheckedChangeListener((CompoundButton buttonView, boolean isChecked) -> {
+ MyThread.runIO(() -> {
+ dataApp.setLock(isChecked);
+ MyDataBase.getInstance().getRoomDao().updateData(dataApp);
+ });
+ String format;
+ 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();
+ });
+
+ try {
+ Drawable appLogo = getLogo(dataApp.getPackageName());
+ holder.imageView.setImageDrawable(appLogo);
+ } catch (PackageManager.NameNotFoundException e) {
+ // Handle exception
+ }
+
+ holder.textView.setText(appName);
+ }
+
+ private Drawable getLogo(String packageName) throws PackageManager.NameNotFoundException {
+ ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
+ return packageManager.getApplicationIcon(appInfo);
+ }
+
+ @Override
+ public int getItemCount() {
+ return filterList.size(); // 使用filterList
+ }
+
+ public static class AppViewHolder extends RecyclerView.ViewHolder {
+
+ private ImageView imageView;
+ private TextView textView;
+ private SwitchCompat switchCompat;
+
+ public AppViewHolder(@NonNull View itemView) {
+ super(itemView);
+ imageView = itemView.findViewById(R.id.logo);
+ textView = itemView.findViewById(R.id.name);
+ switchCompat = itemView.findViewById(R.id.app_switch);
+ }
+ }
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/listadapter/AdapterLockView.java b/app/src/main/java/com/tool/app/protectorpro/listadapter/AdapterLockView.java
new file mode 100644
index 0000000..e8dc6c9
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/listadapter/AdapterLockView.java
@@ -0,0 +1,186 @@
+package com.tool.app.protectorpro.listadapter;
+
+
+
+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 android.widget.TextView;
+
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.tool.app.protectorpro.R;
+import com.tool.app.protectorpro.customerview.CustomBundle;
+import com.tool.app.protectorpro.customerview.CustomBundle;
+
+public class AdapterLockView extends RecyclerView.Adapter {
+
+ private static final int TYPE_NUMBER = 0;
+
+ private OnNumberClickListener mOnNumberListener;
+ private OnDeleteClickListener mOnDeleteListener;
+
+ private static final int VIEW_TYPE_DELETE = 1;
+ private CustomBundle mCustomBundle;
+ private int mCurLength;
+
+ private int[] mKeyValues;
+
+ @Override
+ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ RecyclerView.ViewHolder viewHolder;
+ LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+
+ if (viewType == TYPE_NUMBER) {
+ View view = inflater.inflate(R.layout.item_number, parent, false);
+ viewHolder = new NumberViewHolder(view);
+ } else {
+ View view = inflater.inflate(R.layout.item_delete, parent, false);
+ viewHolder = new DeleteViewHolder(view);
+ }
+ return viewHolder;
+ }
+ public AdapterLockView() {
+ this.mKeyValues = getKeyValues(new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 0});
+ }
+
+
+ @Override
+ public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
+ if (holder.getItemViewType() == TYPE_NUMBER) {
+ NumberViewHolder vh1 = (NumberViewHolder) holder;
+ setNumberBtn(vh1, position);
+ }
+ }
+
+ private void setNumberBtn(NumberViewHolder holder, int position) {
+ if (holder != null) {
+ if (position == 9) {
+ holder.mNumberButton.setVisibility(View.GONE);
+ } else {
+ holder.mNumberButton.setText(String.valueOf(mKeyValues[position]));
+ holder.mNumberButton.setVisibility(View.VISIBLE);
+ holder.mNumberButton.setTag(mKeyValues[position]);
+ }
+
+ if (mCustomBundle != null) {
+ holder.mNumberButton.setTextColor(mCustomBundle.textColor);
+ if (mCustomBundle.backgroundDrawable != null) {
+ holder.mNumberButton.setBackground(mCustomBundle.backgroundDrawable);
+ }
+ holder.mNumberButton.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ mCustomBundle.textSize);
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+ mCustomBundle.buttonSize,
+ mCustomBundle.buttonSize);
+ holder.mNumberButton.setLayoutParams(params);
+ }
+ }
+ }
+
+
+
+ @Override
+ public int getItemCount() {
+ return 12;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ if (position == getItemCount() - 1) {
+ return VIEW_TYPE_DELETE;
+ }
+ return TYPE_NUMBER;
+ }
+
+
+
+ public void setPinLength(int pinLength) {
+ this.mCurLength = pinLength;
+ }
+
+
+
+ private int[] getKeyValues(int[] keyValues) {
+ int[] adjustedKeyValues = new int[keyValues.length + 1];
+ for (int i = 0; i < keyValues.length; i++) {
+ if (i < 9) {
+ adjustedKeyValues[i] = keyValues[i];
+ } else {
+ adjustedKeyValues[i] = -1;
+ adjustedKeyValues[i + 1] = keyValues[i];
+ }
+ }
+ return adjustedKeyValues;
+ }
+
+
+
+ public void setOnItemClickListener(OnNumberClickListener onNumberClickListener) {
+ this.mOnNumberListener = onNumberClickListener;
+ }
+
+
+
+ public void setOnDeleteClickListener(OnDeleteClickListener onDeleteClickListener) {
+ this.mOnDeleteListener = onDeleteClickListener;
+ }
+
+
+
+ public void setCustomizationOptions(CustomBundle customBundle) {
+ this.mCustomBundle = customBundle;
+ }
+
+ public class NumberViewHolder extends RecyclerView.ViewHolder {
+ TextView mNumberButton;
+
+ public NumberViewHolder(final View itemView) {
+ super(itemView);
+ mNumberButton = (TextView) itemView.findViewById(R.id.deleteLayout);
+ mNumberButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mOnNumberListener != null) {
+ mOnNumberListener.onNumberClicked((Integer) v.getTag());
+ }
+ }
+ });
+ }
+ }
+ public interface OnNumberClickListener {
+ void onNumberClicked(int keyValue);
+ }
+
+ public interface OnDeleteClickListener {
+ void onDeleteClicked();
+ }
+ public class DeleteViewHolder extends RecyclerView.ViewHolder {
+ LinearLayout mDeleteLayout;
+ ImageView mDeleteImage;
+
+ public DeleteViewHolder(final View itemView) {
+ super(itemView);
+ mDeleteLayout = (LinearLayout) itemView.findViewById(R.id.deleteLayout);
+ mDeleteImage = (ImageView) itemView.findViewById(R.id.deleteImage);
+
+ if (mCustomBundle.isShowDeleteButton() && mCurLength > 0) {
+ mDeleteLayout.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mOnDeleteListener != null) {
+ mOnDeleteListener.onDeleteClicked();
+ }
+ }
+ });
+
+ }
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/listener/ListenerDao.kt b/app/src/main/java/com/tool/app/protectorpro/listener/ListenerDao.kt
new file mode 100644
index 0000000..b3e66eb
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/listener/ListenerDao.kt
@@ -0,0 +1,33 @@
+package com.tool.app.protectorpro.listener
+
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.OnConflictStrategy
+import androidx.room.Query
+import androidx.room.Update
+import com.tool.app.protectorpro.mydb.DataApp
+
+@Dao
+interface ListenerDao {
+ @Delete
+ fun deleteData(dataApp: DataApp)
+
+ @Query("select * from DataApp where packageName=:packName")
+ fun findByPackName(packName: String): DataApp?
+
+ @Query("select * from DataApp where isSyStem=:system AND isRecommend = :recommend")
+ fun findByType(system: Boolean, recommend: Boolean): List?
+
+ @Update
+ fun updateData(dataApp: DataApp)
+
+ @Insert(onConflict = OnConflictStrategy.IGNORE)
+ fun insertData(dataApp: DataApp)
+
+ @Query("select * from DataApp")
+ fun findApp(): List?
+
+ @Query("select * from DataApp where isLock =:isLock")
+ fun findByLock(isLock: Boolean): List?
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/tool/app/protectorpro/listener/ListenerLock.java b/app/src/main/java/com/tool/app/protectorpro/listener/ListenerLock.java
new file mode 100644
index 0000000..8d57e46
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/listener/ListenerLock.java
@@ -0,0 +1,12 @@
+package com.tool.app.protectorpro.listener;
+
+
+public interface ListenerLock {
+
+
+ void onInPutComplete(String pin);
+
+ void onNumberClickComplete(String keyValue);
+
+ void onKeyBordDelete( int pin);
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/listener/onPermssionListener.java b/app/src/main/java/com/tool/app/protectorpro/listener/onPermssionListener.java
new file mode 100644
index 0000000..8fa52e5
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/listener/onPermssionListener.java
@@ -0,0 +1,8 @@
+package com.tool.app.protectorpro.listener;
+
+
+public interface onPermssionListener {
+
+ void onToSetting();
+
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/mydb/DataApp.java b/app/src/main/java/com/tool/app/protectorpro/mydb/DataApp.java
new file mode 100644
index 0000000..4958a7f
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/mydb/DataApp.java
@@ -0,0 +1,74 @@
+package com.tool.app.protectorpro.mydb;
+
+import androidx.room.Entity;
+import androidx.room.Index;
+import androidx.room.PrimaryKey;
+
+import com.tool.app.protectorpro.MyApplication;
+
+
+@Entity(tableName = MyApplication.Table_Name,indices = {@Index(value = {"packageName"}, unique = true)})
+public class DataApp {
+
+ @PrimaryKey(autoGenerate = true)
+ private int id;
+ private String packageName;
+
+ private String appName;
+
+ private boolean isLock = false;
+
+ private boolean isSyStem ;
+
+ private boolean isRecommend = false;
+
+ public boolean isRecommend() {
+ return isRecommend;
+ }
+
+ public void setRecommend(boolean recommend) {
+ isRecommend = recommend;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public void setSyStem(boolean syStem) {
+ isSyStem = syStem;
+ }
+
+ public boolean isSyStem() {
+ return isSyStem;
+ }
+
+
+ public void setAppName(String appName) {
+ this.appName = appName;
+ }
+
+ public void setLock(boolean lock) {
+ isLock = lock;
+ }
+
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ }
+
+
+ public String getAppName() {
+ return appName;
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public boolean isLock() {
+ return isLock;
+ }
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/mydb/MyDataBase.java b/app/src/main/java/com/tool/app/protectorpro/mydb/MyDataBase.java
new file mode 100644
index 0000000..dab0607
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/mydb/MyDataBase.java
@@ -0,0 +1,28 @@
+package com.tool.app.protectorpro.mydb;
+
+import androidx.room.Database;
+import androidx.room.Room;
+import androidx.room.RoomDatabase;
+
+import com.tool.app.protectorpro.MyApplication;
+import com.tool.app.protectorpro.listener.ListenerDao;
+
+@Database(
+ entities = {DataApp.class},
+ version = MyApplication.DB_Version,
+ exportSchema = false
+)
+public abstract class MyDataBase extends RoomDatabase {
+
+ private static MyDataBase INSTANCE;
+
+ public static synchronized MyDataBase getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE = Room.databaseBuilder(MyApplication.appContext, MyDataBase.class, MyApplication.DB_Name).build();
+ }
+ return INSTANCE;
+ }
+
+ public abstract ListenerDao getRoomDao();
+
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/service/LockService.java b/app/src/main/java/com/tool/app/protectorpro/service/LockService.java
new file mode 100644
index 0000000..e2112da
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/service/LockService.java
@@ -0,0 +1,65 @@
+package com.tool.app.protectorpro.service;
+
+import android.app.IntentService;
+import android.content.Intent;
+
+import androidx.annotation.Nullable;
+
+import com.tool.app.protectorpro.mydb.DataApp;
+import com.tool.app.protectorpro.mydb.MyDataBase;
+import com.tool.app.protectorpro.tools.LockManager;
+import com.tool.app.protectorpro.tools.Common;
+import com.tool.app.protectorpro.tools.MyThread;
+
+import java.util.Objects;
+
+public class LockService extends IntentService {
+
+ private String lastLockPackName = "";
+ private LockManager instance;
+ private Boolean checkTop = true;
+
+ @Override
+ protected void onHandleIntent(@Nullable Intent intent) {
+ instance = LockManager.getInstance(this);
+ while (checkTop) {
+ String packageName = Common.checkUsageStats(this);
+ if(Objects.equals(packageName, "")){
+ continue;
+ }
+ DataApp dataApp = MyDataBase.getInstance().getRoomDao().findByPackName(packageName);
+ if(dataApp == null){
+ MyThread.runUI(()->{
+ instance.unLock();
+ });
+ lastLockPackName = packageName;
+
+ continue;
+ }
+ if(Objects.equals(packageName, lastLockPackName)){
+ continue;
+ }
+ if (dataApp.isLock() ) {
+ if(!Objects.equals(packageName, lastLockPackName)){
+ MyThread.runUI(()->{
+ instance.showLockView();
+ });
+ }else {
+ }
+ }else {
+
+ MyThread.runUI(()->{
+ instance.unLock();
+ });
+ }
+ lastLockPackName = packageName;
+ }
+
+ }
+ public LockService() {
+ super("");
+ }
+
+
+
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/tools/Common.java b/app/src/main/java/com/tool/app/protectorpro/tools/Common.java
new file mode 100644
index 0000000..f71241e
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/tools/Common.java
@@ -0,0 +1,219 @@
+package com.tool.app.protectorpro.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.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.os.Build;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+import androidx.annotation.ColorRes;
+import androidx.annotation.DimenRes;
+import androidx.core.content.ContextCompat;
+
+import com.tool.app.protectorpro.mydb.DataApp;
+import com.tool.app.protectorpro.mydb.MyDataBase;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+
+public class Common {
+ public static float getPx(Context context, @DimenRes int id) {
+ return context.getResources().getDimension(id);
+ }
+
+ private static void addDb(List list, boolean isSystem, boolean isUpdate) {
+// HashSet randomIndex = getRandomIndex(list.size());
+
+ for (int i = 0; i < list.size(); i++) {
+ DataApp dataApp = list.get(i);
+ dataApp.setSyStem(isSystem);
+ if (isUpdate) {
+ DataApp dataApp1 = MyDataBase.getInstance().getRoomDao().findByPackName(dataApp.getPackageName());
+ if (dataApp1 == null) {
+ MyDataBase.getInstance().getRoomDao().insertData(dataApp);
+
+ }
+ } else {
+// boolean contains = randomIndex.contains(i);
+ dataApp.setRecommend(false);
+ MyDataBase.getInstance().getRoomDao().insertData(dataApp);
+
+ }
+ }
+ }
+
+ public static List getAppList(Context context, boolean isUpdate) {
+ PackageManager packageManager = context.getPackageManager();
+ Intent intent = new Intent(Intent.ACTION_MAIN, null);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ List resolveInfos = packageManager.queryIntentActivities(intent, 0);
+
+ List systemAppList = new ArrayList<>();
+ List threeAppList = new ArrayList<>();
+
+ for (int i = 0; i < resolveInfos.size(); i++) {
+ ResolveInfo resolveInfo = resolveInfos.get(i);
+ String packageName = resolveInfo.activityInfo.packageName;
+ if (Objects.equals(packageName, context.getPackageName())) {
+ continue;
+ }
+ ApplicationInfo appInfo;
+ try {
+ appInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
+ String appName = packageManager.getApplicationLabel(appInfo).toString();
+
+ DataApp dataApp = new DataApp();
+ dataApp.setPackageName(packageName);
+ dataApp.setAppName(appName);
+ boolean systemApp = checkSystemApp(context, packageName);
+ if (systemApp) {
+ systemAppList.add(dataApp);
+ } else {
+ threeAppList.add(dataApp);
+ }
+ } catch (PackageManager.NameNotFoundException nameNotFoundException) {
+
+ }
+
+
+ }
+
+ List uniqueSystemList = removeDuplApp(systemAppList);
+ List uniqueThreeList = removeDuplApp(threeAppList);
+
+
+ MyThread.runIO(() -> {
+ addDb(uniqueSystemList, true, isUpdate);
+ addDb(uniqueThreeList, false, isUpdate);
+
+ });
+
+ return uniqueThreeList;
+
+
+ }
+
+
+ public static int getColor(Context context, @ColorRes int id) {
+ return ContextCompat.getColor(context, id);
+ }
+
+
+// private static HashSet getRandomIndex(int size) {
+// Random random = new Random();
+// HashSet uniqueNumbers = new HashSet<>();
+// while (uniqueNumbers.size() < 4) {
+// int randomNumber = random.nextInt(size + 1);
+// uniqueNumbers.add(randomNumber);
+// }
+// return uniqueNumbers;
+//
+// }
+
+ private static boolean checkSystemApp(Context context, String packageName) {
+
+ try {
+ PackageInfo info = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+ if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ return true;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+
+ public static List removeDuplApp(List list) {
+ HashMap hashMap = new HashMap<>();
+ for (DataApp dataApp : list) {
+ if (!hashMap.containsKey(dataApp.getPackageName())) {
+ hashMap.put(dataApp.getPackageName(), dataApp);
+ }
+ }
+ List data = new ArrayList<>();
+ for (HashMap.Entry entry : hashMap.entrySet()) {
+ data.add(entry.getValue());
+ }
+ return data;
+ }
+
+
+ public static String checkUsageStats(Context context) {
+ UsageStatsManager sUsageStatsManager = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
+ long endTime = System.currentTimeMillis();
+ long beginTime = endTime - 10000;
+ String result = "";
+ UsageEvents.Event event = new UsageEvents.Event();
+ UsageEvents usageEvents = sUsageStatsManager.queryEvents(beginTime, endTime);
+ while (usageEvents.hasNextEvent()) {
+ usageEvents.getNextEvent(event);
+ if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
+ result = event.getPackageName();
+ }
+ }
+ if (!TextUtils.isEmpty(result)) {
+ return result;
+ } else {
+ return "";
+ }
+ }
+
+ public static Boolean delUnInstallApp(Context context, String packName) {
+ PackageManager packageManager = context.getPackageManager();
+ try {
+ packageManager.getApplicationInfo(packName, PackageManager.GET_UNINSTALLED_PACKAGES);
+ return false;
+ } catch (PackageManager.NameNotFoundException nameNotFoundException) {
+ return true;
+ }
+ }
+
+
+ public static boolean checkPermission(Context context) {
+
+ // 检查当前应用是否具有 "android:get_usage_stats" 权限
+ AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+ int mode = 0;
+ mode = appOps.checkOpNoThrow("android:get_usage_stats", android.os.Process.myUid(), context.getPackageName());
+ return mode == AppOpsManager.MODE_ALLOWED;
+ }
+
+ public static void goDrawOverlays(Activity activity, int requestCode) {
+ Intent intent = new 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
+ Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
+ intent.setData(uri);
+// intent.setData(Uri.parse("package:" + activity.getPackageName()));
+ }
+ activity.startActivityForResult(intent, requestCode);
+ }
+
+
+ public static void toSetUsagePermission(Activity context, int requestCode) {
+ Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
+// Uri uri = Uri.fromParts("package", context.getPackageName(), null);
+// intent.setData(uri);
+ context.startActivityForResult(intent, requestCode);
+ }
+
+ public static boolean getCanDrawOverlays(Context context) {
+ return Settings.canDrawOverlays(context);
+ }
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/tools/LockManager.java b/app/src/main/java/com/tool/app/protectorpro/tools/LockManager.java
new file mode 100644
index 0000000..fe4a54e
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/tools/LockManager.java
@@ -0,0 +1,168 @@
+package com.tool.app.protectorpro.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 android.widget.FrameLayout;
+import android.widget.TextView;
+
+
+import com.google.android.material.snackbar.Snackbar;
+import com.tool.app.protectorpro.MyApplication;
+import com.tool.app.protectorpro.R;
+import com.tool.app.protectorpro.customerview.MyDots;
+import com.tool.app.protectorpro.listener.ListenerLock;
+import com.tool.app.protectorpro.customerview.MyLockView;
+
+import java.util.Objects;
+
+public class LockManager {
+
+ private static LockManager lockManager;
+ private Context mContext;
+
+ private View mView;
+
+ private WindowManager windowManager;
+
+
+ private WindowManager.LayoutParams layoutParams;
+
+ private MyLockView lockView;
+
+ public LockManager(Context context) {
+ mContext = context;
+ mView = LayoutInflater.from(context).inflate(R.layout.float_view, null, false);
+ windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+
+
+ initView();
+
+ MyDots dots = mView.findViewById(R.id.indicator_dots);
+ lockView = mView.findViewById(R.id.pin_lock_view);
+ lockView.attachIndicatorDots(dots);
+ lockView.setPinLockListener(new ListenerLock() {
+ @Override
+ public void onNumberClickComplete(String keyValue) {
+
+ }
+
+ @Override
+ public void onKeyBordDelete(int pin) {
+
+ }
+
+ @Override
+ public void onInPutComplete(String pin) {
+
+ String pwd = MyApplication.getPwd();
+ if (Objects.equals(pin, pwd)) {
+ unLock();
+ } else {
+ lockView.resetPinLockView();
+
+ // Toast.makeText(mContext,"Password error",Toast.LENGTH_SHORT).show();
+
+ // showCustomSnackbar(mView, "Password error", Color.argb(1, 224, 224, 224));
+
+ }
+ }
+ });
+ }
+
+ public static LockManager getInstance(Context context) {
+ if (lockManager == null) {
+ lockManager = new LockManager(context);
+ }
+ return lockManager;
+
+ }
+
+ private void showCustomSnackbar(View view, String message, int backgroundColor) {
+ Snackbar snackbar = Snackbar.make(view, "", Snackbar.LENGTH_LONG);
+
+ // 获取Snackbar的View
+ View snackbarView = snackbar.getView();
+
+ // 获取Snackbar的父布局
+ ViewGroup snackbarLayout = (ViewGroup) snackbarView.findViewById(com.google.android.material.R.id.snackbar_text).getParent();
+
+ // 移除默认的TextView
+ snackbarLayout.removeAllViews();
+
+ // 自定义布局
+ LayoutInflater inflater = LayoutInflater.from(view.getContext());
+ View customView = inflater.inflate(R.layout.custom_float_snackbar, null);
+
+ // 设置背景颜色
+ snackbarView.setBackgroundColor(backgroundColor);
+
+ // 设置描述文字
+ TextView snackbarText = customView.findViewById(R.id.snackbar_text);
+ snackbarText.setText(message);
+
+ // 将自定义布局添加到Snackbar的布局中
+ snackbarLayout.addView(customView);
+
+ // 设置居中
+ FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) snackbarView.getLayoutParams();
+ params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+ snackbarView.setLayoutParams(params);
+
+ snackbar.show();
+ }
+
+ private void initView() {
+ int type = 0;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+ } else {
+ type = WindowManager.LayoutParams.TYPE_PHONE;
+ }
+ DisplayMetrics displayMetrics = new DisplayMetrics();
+ windowManager.getDefaultDisplay().getMetrics(displayMetrics);
+ layoutParams = new 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 |
+ WindowManager.LayoutParams.FLAG_FULLSCREEN |
+ WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
+ WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
+ WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+
+ layoutParams.gravity = Gravity.START | Gravity.TOP;
+
+ Point screenSize = new Point();
+ windowManager.getDefaultDisplay().getRealSize(screenSize);
+ layoutParams.width = screenSize.x;
+ layoutParams.height = screenSize.y;
+ }
+
+
+ public void showLockView() {
+ lockView.resetPinLockView();
+ windowManager.addView(mView, layoutParams);
+
+ }
+
+
+ public void unLock() {
+ try {
+ windowManager.removeView(mView);
+ } catch (Exception exception) {
+
+ }
+ }
+
+
+}
diff --git a/app/src/main/java/com/tool/app/protectorpro/tools/MyThread.java b/app/src/main/java/com/tool/app/protectorpro/tools/MyThread.java
new file mode 100644
index 0000000..da6e8b0
--- /dev/null
+++ b/app/src/main/java/com/tool/app/protectorpro/tools/MyThread.java
@@ -0,0 +1,35 @@
+package com.tool.app.protectorpro.tools;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class MyThread {
+
+ private static Handler mMainHandler;
+
+ private static ExecutorService executorService;
+
+ private static Handler getmMainHandler() {
+ if (mMainHandler == null) {
+ mMainHandler = new Handler(Looper.getMainLooper());
+ }
+ return mMainHandler;
+ }
+ public static void runIO(Runnable task) {
+ getExecutorService().execute(task);
+ }
+
+ private static ExecutorService getExecutorService() {
+ if (executorService == null) {
+ executorService = Executors.newSingleThreadExecutor();
+ }
+ return executorService;
+ }
+
+ public static void runUI(Runnable task) {
+ getmMainHandler().post(task);
+ }
+}
diff --git a/app/src/main/res/color/selector_text_color.xml b/app/src/main/res/color/selector_text_color.xml
new file mode 100644
index 0000000..8422370
--- /dev/null
+++ b/app/src/main/res/color/selector_text_color.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/back.xml b/app/src/main/res/drawable/back.xml
new file mode 100644
index 0000000..dc8f6b1
--- /dev/null
+++ b/app/src/main/res/drawable/back.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/app/src/main/res/drawable/bg_12_white.xml b/app/src/main/res/drawable/bg_12_white.xml
new file mode 100644
index 0000000..0221b83
--- /dev/null
+++ b/app/src/main/res/drawable/bg_12_white.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_30_green.xml b/app/src/main/res/drawable/bg_30_green.xml
new file mode 100644
index 0000000..bc5f204
--- /dev/null
+++ b/app/src/main/res/drawable/bg_30_green.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_36_4cd080.xml b/app/src/main/res/drawable/bg_36_4cd080.xml
new file mode 100644
index 0000000..abcf023
--- /dev/null
+++ b/app/src/main/res/drawable/bg_36_4cd080.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_36_b1dbff.xml b/app/src/main/res/drawable/bg_36_b1dbff.xml
new file mode 100644
index 0000000..7ad006f
--- /dev/null
+++ b/app/src/main/res/drawable/bg_36_b1dbff.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_dia_step.xml b/app/src/main/res/drawable/bg_dia_step.xml
new file mode 100644
index 0000000..2d53532
--- /dev/null
+++ b/app/src/main/res/drawable/bg_dia_step.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_fragment.xml b/app/src/main/res/drawable/bg_fragment.xml
new file mode 100644
index 0000000..5f61309
--- /dev/null
+++ b/app/src/main/res/drawable/bg_fragment.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_sw.xml b/app/src/main/res/drawable/bg_sw.xml
new file mode 100644
index 0000000..bbc42e5
--- /dev/null
+++ b/app/src/main/res/drawable/bg_sw.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_tab_lock.xml b/app/src/main/res/drawable/bg_tab_lock.xml
new file mode 100644
index 0000000..17b773e
--- /dev/null
+++ b/app/src/main/res/drawable/bg_tab_lock.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_tab_sys.xml b/app/src/main/res/drawable/bg_tab_sys.xml
new file mode 100644
index 0000000..c0f35d7
--- /dev/null
+++ b/app/src/main/res/drawable/bg_tab_sys.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bg_tab_three.xml b/app/src/main/res/drawable/bg_tab_three.xml
new file mode 100644
index 0000000..2aa5817
--- /dev/null
+++ b/app/src/main/res/drawable/bg_tab_three.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/bottom_sheet_bg.xml b/app/src/main/res/drawable/bottom_sheet_bg.xml
new file mode 100644
index 0000000..bf88b17
--- /dev/null
+++ b/app/src/main/res/drawable/bottom_sheet_bg.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/delete.xml b/app/src/main/res/drawable/delete.xml
new file mode 100644
index 0000000..5fd9940
--- /dev/null
+++ b/app/src/main/res/drawable/delete.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/dia_choose.xml b/app/src/main/res/drawable/dia_choose.xml
new file mode 100644
index 0000000..546a80b
--- /dev/null
+++ b/app/src/main/res/drawable/dia_choose.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/main_pwd.xml b/app/src/main/res/drawable/main_pwd.xml
new file mode 100644
index 0000000..1945262
--- /dev/null
+++ b/app/src/main/res/drawable/main_pwd.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
diff --git a/app/src/main/res/drawable/oval_black.xml b/app/src/main/res/drawable/oval_black.xml
new file mode 100644
index 0000000..48b0b70
--- /dev/null
+++ b/app/src/main/res/drawable/oval_black.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/oval_gray.xml b/app/src/main/res/drawable/oval_gray.xml
new file mode 100644
index 0000000..82c89fc
--- /dev/null
+++ b/app/src/main/res/drawable/oval_gray.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/oval_white.xml b/app/src/main/res/drawable/oval_white.xml
new file mode 100644
index 0000000..522eb16
--- /dev/null
+++ b/app/src/main/res/drawable/oval_white.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/pwd_bg.xml b/app/src/main/res/drawable/pwd_bg.xml
new file mode 100644
index 0000000..4db3876
--- /dev/null
+++ b/app/src/main/res/drawable/pwd_bg.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/tab_bg.xml b/app/src/main/res/drawable/tab_bg.xml
new file mode 100644
index 0000000..0221b83
--- /dev/null
+++ b/app/src/main/res/drawable/tab_bg.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/thumb_sw.xml b/app/src/main/res/drawable/thumb_sw.xml
new file mode 100644
index 0000000..198a7fc
--- /dev/null
+++ b/app/src/main/res/drawable/thumb_sw.xml
@@ -0,0 +1,16 @@
+
+
+ -
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/track_sw_green.xml b/app/src/main/res/drawable/track_sw_green.xml
new file mode 100644
index 0000000..eb9915d
--- /dev/null
+++ b/app/src/main/res/drawable/track_sw_green.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/track_sw_white.xml b/app/src/main/res/drawable/track_sw_white.xml
new file mode 100644
index 0000000..1c4da3d
--- /dev/null
+++ b/app/src/main/res/drawable/track_sw_white.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/font/inter.ttf b/app/src/main/res/font/inter.ttf
new file mode 100644
index 0000000..2348f6b
Binary files /dev/null and b/app/src/main/res/font/inter.ttf differ
diff --git a/app/src/main/res/layout/activity_complete.xml b/app/src/main/res/layout/activity_complete.xml
new file mode 100644
index 0000000..bbac82d
--- /dev/null
+++ b/app/src/main/res/layout/activity_complete.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main_layout.xml b/app/src/main/res/layout/activity_main_layout.xml
new file mode 100644
index 0000000..974472c
--- /dev/null
+++ b/app/src/main/res/layout/activity_main_layout.xml
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_set_pwd.xml b/app/src/main/res/layout/activity_set_pwd.xml
new file mode 100644
index 0000000..ffb200c
--- /dev/null
+++ b/app/src/main/res/layout/activity_set_pwd.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_wel.xml b/app/src/main/res/layout/activity_wel.xml
new file mode 100644
index 0000000..37b9d25
--- /dev/null
+++ b/app/src/main/res/layout/activity_wel.xml
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/custom_float_snackbar.xml b/app/src/main/res/layout/custom_float_snackbar.xml
new file mode 100644
index 0000000..b835b2a
--- /dev/null
+++ b/app/src/main/res/layout/custom_float_snackbar.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/custom_password_input_view.xml b/app/src/main/res/layout/custom_password_input_view.xml
new file mode 100644
index 0000000..1804caf
--- /dev/null
+++ b/app/src/main/res/layout/custom_password_input_view.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_permis.xml b/app/src/main/res/layout/dialog_permis.xml
new file mode 100644
index 0000000..e2471f1
--- /dev/null
+++ b/app/src/main/res/layout/dialog_permis.xml
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/float_view.xml b/app/src/main/res/layout/float_view.xml
new file mode 100644
index 0000000..d4dd306
--- /dev/null
+++ b/app/src/main/res/layout/float_view.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_my.xml b/app/src/main/res/layout/fragment_my.xml
new file mode 100644
index 0000000..1c137f9
--- /dev/null
+++ b/app/src/main/res/layout/fragment_my.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_delete.xml b/app/src/main/res/layout/item_delete.xml
new file mode 100644
index 0000000..e2fd72a
--- /dev/null
+++ b/app/src/main/res/layout/item_delete.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_number.xml b/app/src/main/res/layout/item_number.xml
new file mode 100644
index 0000000..248f0dc
--- /dev/null
+++ b/app/src/main/res/layout/item_number.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_systapp.xml b/app/src/main/res/layout/item_systapp.xml
new file mode 100644
index 0000000..15f697b
--- /dev/null
+++ b/app/src/main/res/layout/item_systapp.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/set_bottom_sheet_layout.xml b/app/src/main/res/layout/set_bottom_sheet_layout.xml
new file mode 100644
index 0000000..be7a2ad
--- /dev/null
+++ b/app/src/main/res/layout/set_bottom_sheet_layout.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/tab_view.xml b/app/src/main/res/layout/tab_view.xml
new file mode 100644
index 0000000..1e72600
--- /dev/null
+++ b/app/src/main/res/layout/tab_view.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 0000000..c209e78
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..b2dfe3d
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 0000000..4f0f1d6
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..62b611d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 0000000..948a307
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..1b9a695
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..28d4b77
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9287f50
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/float_snack_ic.png b/app/src/main/res/mipmap-xxxhdpi/float_snack_ic.png
new file mode 100644
index 0000000..eb2ab1c
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/float_snack_ic.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_backspace.png b/app/src/main/res/mipmap-xxxhdpi/ic_backspace.png
new file mode 100644
index 0000000..a1709f9
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_backspace.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_change.png b/app/src/main/res/mipmap-xxxhdpi/ic_change.png
new file mode 100644
index 0000000..c5797a4
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_change.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_close.png b/app/src/main/res/mipmap-xxxhdpi/ic_close.png
new file mode 100644
index 0000000..7877486
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_close.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_dia_step1.png b/app/src/main/res/mipmap-xxxhdpi/ic_dia_step1.png
new file mode 100644
index 0000000..f276042
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_dia_step1.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_dia_step2.png b/app/src/main/res/mipmap-xxxhdpi/ic_dia_step2.png
new file mode 100644
index 0000000..31facf6
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_dia_step2.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 0000000..aa7d642
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 0000000..9126ae3
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_next.png b/app/src/main/res/mipmap-xxxhdpi/ic_next.png
new file mode 100644
index 0000000..f77e035
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_next.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_plaicy.png b/app/src/main/res/mipmap-xxxhdpi/ic_plaicy.png
new file mode 100644
index 0000000..31f855a
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_plaicy.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/logo.png b/app/src/main/res/mipmap-xxxhdpi/logo.png
new file mode 100644
index 0000000..8024a8e
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/logo.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/main_tab_lock_def.png b/app/src/main/res/mipmap-xxxhdpi/main_tab_lock_def.png
new file mode 100644
index 0000000..7e967ad
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/main_tab_lock_def.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/main_tab_lock_en.png b/app/src/main/res/mipmap-xxxhdpi/main_tab_lock_en.png
new file mode 100644
index 0000000..8c0b8f8
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/main_tab_lock_en.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/main_tab_sys_def.png b/app/src/main/res/mipmap-xxxhdpi/main_tab_sys_def.png
new file mode 100644
index 0000000..1e2bace
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/main_tab_sys_def.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/main_tab_sys_en.png b/app/src/main/res/mipmap-xxxhdpi/main_tab_sys_en.png
new file mode 100644
index 0000000..f0a0fad
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/main_tab_sys_en.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/main_tab_three_def.png b/app/src/main/res/mipmap-xxxhdpi/main_tab_three_def.png
new file mode 100644
index 0000000..00e917f
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/main_tab_three_def.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/main_tab_three_en.png b/app/src/main/res/mipmap-xxxhdpi/main_tab_three_en.png
new file mode 100644
index 0000000..a30a719
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/main_tab_three_en.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/track_sw_green_ic.png b/app/src/main/res/mipmap-xxxhdpi/track_sw_green_ic.png
new file mode 100644
index 0000000..d73507d
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/track_sw_green_ic.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/track_sw_white_ic.png b/app/src/main/res/mipmap-xxxhdpi/track_sw_white_ic.png
new file mode 100644
index 0000000..2df03b2
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/track_sw_white_ic.png differ
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..e2e7d52
--- /dev/null
+++ b/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,16 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..f53b0cf
--- /dev/null
+++ b/app/src/main/res/values/attrs.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..c5215ff
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,27 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+ #FFF5F6F7
+ #FF3700B3
+ #FF0fa934
+ #66000000
+ #E5E5E5
+ #FF72716F
+ #00000000
+ #FFF4FAFF
+ #282638
+ #FF0582EF
+ #FFB1DBFF
+ #1a8ee04e
+ #5aa2f1
+ #FFFFFFFF
+ #1F1D2B
+ #FF3A3938
+ #FF0582EF
+ #FF2A343D
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/dimmens.xml b/app/src/main/res/values/dimmens.xml
new file mode 100644
index 0000000..f5e3f8b
--- /dev/null
+++ b/app/src/main/res/values/dimmens.xml
@@ -0,0 +1,9 @@
+
+
+ 16sp
+ 60dp
+ 32dp
+ 0dp
+ 8dp
+ 8dp
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..881e0b7
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,39 @@
+
+ AppLocker pro
+ Continue
+ Password
+ Rate Us
+ Share
+ Change Password
+ Confirm Password
+ Please enter your new 4-digit password
+ Please confirm your 4-digit password
+ Save
+ Your APP
+ Protect your privacy by locking apps with one click
+ locked: %s
+ Unlocked: %s
+ Congratulations, your password has been changed successfully
+ For normal use, please grant relevant permissions
+ permissions
+For normal use App Lock, please grant the following
+ Usage access
+ Enables the system to capture and analyze your application\'s usage data.
+ Display on top of other apps
+ Enable that the application window or interface will be displayed on top of all other open applications.
+ come back home and enjoy the use of the features available for your problems
+ System App
+ Third APP
+ Lock APP
+ Set Passcode
+ Your initial password is required for first use
+ Back Home
+ please input complete
+ please sure input complete
+ Step 1 : Select
+ Step 2:Enabled
+ Please enter password
+ Settings
+ Change password
+ Privacy Policy
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..63374a0
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..fa0f996
--- /dev/null
+++ b/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..9ee9997
--- /dev/null
+++ b/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/test/java/com/tool/app/protectorpro/ExampleUnitTest.kt b/app/src/test/java/com/tool/app/protectorpro/ExampleUnitTest.kt
new file mode 100644
index 0000000..2f9cb79
--- /dev/null
+++ b/app/src/test/java/com/tool/app/protectorpro/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.tool.app.protectorpro
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit protectorpro, 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)
+ }
+}
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000..1bc1d16
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,5 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id("com.android.application") version "8.1.3" apply false
+ id("org.jetbrains.kotlin.android") version "1.9.0" apply false
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..3c5031e
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/gradle/applockpro1 b/gradle/applockpro1
new file mode 100644
index 0000000..7090055
Binary files /dev/null and b/gradle/applockpro1 differ
diff --git a/gradle/jks_pass b/gradle/jks_pass
new file mode 100644
index 0000000..6a859a4
--- /dev/null
+++ b/gradle/jks_pass
@@ -0,0 +1,5 @@
+
+
+alids:key_lockpro
+
+pass:12345600
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..7bc2c1c
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Mar 28 10:58:04 CST 2024
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100644
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..107acd3
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 0000000..2e83b9d
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,19 @@
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ maven (url ="https://jitpack.io" )
+ }
+}
+
+rootProject.name = "MyAppLock"
+include(":app")
+
\ No newline at end of file