x1ongzhu 1 год назад
Родитель
Сommit
423e2b8f44

+ 1 - 0
app/src/main/AndroidManifest.xml

@@ -5,6 +5,7 @@
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
+    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
 
     <application
         android:name=".MyApplication"

+ 16 - 17
app/src/main/java/com/example/modifier/MainActivity.kt

@@ -2,26 +2,20 @@ package com.example.modifier
 
 import android.content.DialogInterface
 import android.content.Intent
+import android.net.Uri
 import android.os.Bundle
-import android.os.Handler
-import android.os.Looper
 import android.provider.Settings
 import androidx.activity.enableEdgeToEdge
-import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.app.AppCompatActivity
 import androidx.navigation.fragment.NavHostFragment
 import androidx.navigation.ui.NavigationUI.setupWithNavController
-import com.example.modifier.databinding.ActivityLoginBinding
 import com.example.modifier.databinding.ActivityMainBinding
 import com.google.android.material.dialog.MaterialAlertDialogBuilder
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.GlobalScope
-import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
-import java.util.concurrent.ExecutorService
-import java.util.concurrent.Executors
+import kotlinx.coroutines.withContext
 
 class MainActivity : AppCompatActivity() {
     private lateinit var mBinding: ActivityMainBinding
@@ -36,7 +30,10 @@ class MainActivity : AppCompatActivity() {
             supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
         val controller = navHostFragment.navController
         setupWithNavController(mBinding.nav, controller)
-        CoroutineScope(Dispatchers.Main).launch {
+        CoroutineScope(Dispatchers.IO).launch {
+            if (!Settings.canDrawOverlays(this@MainActivity)) {
+                Utils.enableOverlay()
+            }
             if (Utils.hasRootAccess()) {
                 if (!Utils.isAccessibilityEnabled()) {
                     if (!Utils.enableAccessibility()) {
@@ -48,14 +45,16 @@ class MainActivity : AppCompatActivity() {
                     }
                 }
             } else {
-                MaterialAlertDialogBuilder(this@MainActivity)
-                    .setTitle("No Root Access")
-                    .setMessage("Root access is required to run this app")
-                    .setCancelable(false)
-                    .setPositiveButton("Exit") { _: DialogInterface?, _: Int ->
-                        finish()
-                    }
-                    .show()
+                withContext(Dispatchers.Main) {
+                    MaterialAlertDialogBuilder(this@MainActivity)
+                        .setTitle("No Root Access")
+                        .setMessage("Root access is required to run this app")
+                        .setCancelable(false)
+                        .setPositiveButton("Exit") { _: DialogInterface?, _: Int ->
+                            finish()
+                        }
+                        .show()
+                }
             }
         }
     }

+ 18 - 5
app/src/main/java/com/example/modifier/ModifierService.kt

@@ -21,6 +21,8 @@ import android.widget.FrameLayout
 import com.example.modifier.Global.load
 import com.example.modifier.databinding.FloatingWindowBinding
 import com.google.android.material.color.DynamicColors
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import com.google.android.material.dialog.MaterialDialogs
 import io.socket.client.IO
 import io.socket.client.Socket
 import io.socket.emitter.Emitter
@@ -52,6 +54,9 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
     private lateinit var binding: FloatingWindowBinding
     private var counter = 0
     private var _busy = false
+    private var cleanCount = 0
+    private var lastSend = 0L
+    private var rcsInterval = 0L
     private var busy: Boolean
         get() {
             return _busy
@@ -142,7 +147,11 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
 
     private fun runTask(id: String, data: JSONObject) {
         val config = data.optJSONObject("config")
+        config!!
         val rcsWait = config.optLong("rcsWait", 2000)
+        cleanCount = config.optInt("cleanCount", 20)
+        rcsInterval = config.optLong("rcsInterval", 0)
+        counter = 0
         val tasks = data.optJSONArray("tasks")
         mExecutor.submit {
             busy = true
@@ -203,9 +212,17 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
                                 Log.i(TAG, "Send button not found")
                             } else {
                                 Log.i(TAG, "Clicking send button")
+
+                                val dt = System.currentTimeMillis() - lastSend
+                                if (rcsInterval > 0 && dt < rcsInterval) {
+                                    Log.i(TAG, "Waiting for RCS interval")
+                                    Thread.sleep(rcsInterval - dt)
+                                }
                                 result.sendBtn.performAction(AccessibilityNodeInfo.ACTION_CLICK)
+                                lastSend = System.currentTimeMillis()
                                 counter++
-                                if (counter == 20) {
+                                if (counter >= cleanCount) {
+                                    counter = 0
                                     Thread.sleep(2000)
                                     Global.clearConv();
                                     Thread.sleep(2000)
@@ -363,10 +380,6 @@ class ModifierService : AccessibilityService(), Emitter.Listener {
             canSend = isChecked
             updateDevice("canSend", canSend)
         }
-
-        //        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
-//        PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "RCS:MyWakelockTag");
-//        wakeLock.acquire();
     }
 
     private fun updateDevice(key: String, value: Any) {

+ 8 - 0
app/src/main/java/com/example/modifier/Utils.java

@@ -138,6 +138,14 @@ public class Utils {
         return false;
     }
 
+    public static void enableOverlay() {
+        try {
+            runAsRoot("appops set " + BuildConfig.APPLICATION_ID + " SYSTEM_ALERT_WINDOW allow");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
     public static String getUniqueID() {
         Context context = getContext();
         Objects.requireNonNull(context);

+ 1 - 0
app/src/main/res/layout/floating_window.xml

@@ -52,6 +52,7 @@
                     android:textSize="14sp"
                     app:layout_constraintStart_toStartOf="@id/sw_connect"
                     app:layout_constraintTop_toBottomOf="@id/sw_connect" />
+
             </androidx.constraintlayout.widget.ConstraintLayout>
         </com.google.android.material.card.MaterialCardView>
     </FrameLayout>