This commit is contained in:
Administrator 2025-07-08 22:16:46 +08:00
parent b504984268
commit fc62906c0e
18 changed files with 403 additions and 230 deletions

View File

@ -4,6 +4,14 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2025-07-07T06:37:35.266033300Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="Default" identifier="serial=8.217.74.194:8924;connection=1af33e42" />
</handle>
</Target>
</DropdownSelection>
<DialogSelection />
</SelectionState> </SelectionState>
</selectionStates> </selectionStates>
</component> </component>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings"> <component name="GradleSettings">
<option name="linkedExternalProjectsSettings"> <option name="linkedExternalProjectsSettings">
<GradleProjectSettings> <GradleProjectSettings>

View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">

View File

@ -9,8 +9,7 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BIND_VPN_SERVICE" <uses-permission android:name="android.permission.BIND_VPN_SERVICE"
tools:ignore="ProtectedPermissions" /> tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VPN_SERVICE" /> <uses-permission android:name="android.permission.VPN_SERVICE" />

View File

@ -3,6 +3,7 @@ package com.android.grape
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels import androidx.activity.viewModels
@ -11,11 +12,11 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import com.android.grape.databinding.ActivityMainBinding import com.android.grape.databinding.ActivityMainBinding
import com.android.grape.job.MonitorService
import com.android.grape.util.ClashUtil import com.android.grape.util.ClashUtil
import com.android.grape.util.NotificationPermissionHandler import com.android.grape.util.NotificationPermissionHandler
import com.android.grape.util.ScriptUtil import com.android.grape.util.ScriptUtil
import com.android.grape.util.StoragePermissionHelper import com.android.grape.util.StoragePermissionHelper
import com.blankj.utilcode.util.LogUtils
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private val viewModel by viewModels<MainViewModel>() private val viewModel by viewModels<MainViewModel>()
@ -34,21 +35,22 @@ class MainActivity : AppCompatActivity() {
checkPermission() checkPermission()
ScriptUtil.registerScriptResultReceiver() ScriptUtil.registerScriptResultReceiver()
viewBinding.start.setOnClickListener { viewBinding.start.setOnClickListener {
try { MonitorService.onEvent(MainApplication.instance)
ClashUtil.startProxy(this) // try {
ClashUtil.switchProxyGroup( // ClashUtil.startProxy(this)
"GLOBAL", // ClashUtil.switchProxyGroup(
ClashUtil.getRandomLocale(), // "GLOBAL",
"http://127.0.0.1:6170" // ClashUtil.getRandomLocale(),
) // "http://127.0.0.1:6170"
} catch (e: Exception) { // )
LogUtils.e("startProxyVpn: Failed to start VPN", e) // } catch (e: Exception) {
Toast.makeText( // LogUtils.e("startProxyVpn: Failed to start VPN", e)
this, // Toast.makeText(
"Failed to start VPN: " + (if (e.message != null) e.message else "Unknown error"), // this,
Toast.LENGTH_SHORT // "Failed to start VPN: " + (if (e.message != null) e.message else "Unknown error"),
).show() // Toast.LENGTH_SHORT
} // ).show()
// }
} }
viewBinding.stop.setOnClickListener { viewBinding.stop.setOnClickListener {
ClashUtil.stopProxy(this) ClashUtil.stopProxy(this)
@ -63,6 +65,7 @@ class MainActivity : AppCompatActivity() {
} }
private fun checkPermission() { private fun checkPermission() {
Log.d("TAG", "checkPermission: ")
permissionHandler = NotificationPermissionHandler(this) { result -> permissionHandler = NotificationPermissionHandler(this) { result ->
handlePermissionResult(result) handlePermissionResult(result)
} }

View File

@ -3,6 +3,7 @@ package com.android.grape
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.work.PeriodicWorkRequest import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager import androidx.work.WorkManager
import com.android.grape.job.MonitorService
import com.android.grape.service.MyAccessibilityService import com.android.grape.service.MyAccessibilityService
import com.android.grape.work.CheckAccessibilityWorker import com.android.grape.work.CheckAccessibilityWorker
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -21,6 +22,5 @@ class MainViewModel:ViewModel() {
.build() .build()
WorkManager.getInstance(MainApplication.instance).enqueue(workRequest) WorkManager.getInstance(MainApplication.instance).enqueue(workRequest)
} }
} }
} }

View File

@ -23,7 +23,8 @@ class DownloadAppJobService : JobIntentService() {
if (succ) { if (succ) {
errTime = 0L errTime = 0L
StartVpnServerJobService.onEvent(this) InstallService.onEvent(this)
// StartVpnServerJobService.onEvent(this)
// StartVpnPortJobService.onEvent(this) // StartVpnPortJobService.onEvent(this)
} else { } else {
Util.isClickRet = false Util.isClickRet = false

View File

@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.util.Log import android.util.Log
import androidx.core.app.JobIntentService import androidx.core.app.JobIntentService
import com.android.grape.net.ChangeCallBack
import com.android.grape.util.ChangeDeviceInfoUtil import com.android.grape.util.ChangeDeviceInfoUtil
import com.android.grape.util.MockTools import com.android.grape.util.MockTools
import com.android.grape.util.ServiceUtils import com.android.grape.util.ServiceUtils
@ -23,9 +24,9 @@ class OpenAppService : JobIntentService() {
ServiceUtils.setEnableApp("com.android.chrome", true) ServiceUtils.setEnableApp("com.android.chrome", true)
ServiceUtils.setEnableApp("com.UCMobile", true) ServiceUtils.setEnableApp("com.UCMobile", true)
if (Util.isCanAuto && Util.canAutoLc.isNotEmpty()) { if (Util.isCanAuto && Util.canAutoLc.isNotEmpty()) {
MockTools.exec("pm grant org.autojs.autojs android.permission.READ_EXTERNAL_STORAGE") //sdcard权限 MockTools.exec("pm grant ${Util.AUTO_JSPACKAGENAME} android.permission.READ_EXTERNAL_STORAGE") //sdcard权限
MockTools.exec("pm grant org.autojs.autojs android.permission.SYSTEM_ALERT_WINDOW") //悬浮窗权限 MockTools.exec("pm grant ${Util.AUTO_JSPACKAGENAME} android.permission.SYSTEM_ALERT_WINDOW") //悬浮窗权限
MockTools.exec("settings put secure enabled_accessibility_services org.autojs.autojs/com.stardust.autojs.core.accessibility.AccessibilityService") MockTools.exec("settings put secure enabled_accessibility_services ${Util.AUTO_JSPACKAGENAME}/${Util.AUTO_JSPACKAGENAME}.core.accessibility.AccessibilityService")
Util.doScript(this, Util.AUTO_JSPACKAGENAME) //autojs Util.doScript(this, Util.AUTO_JSPACKAGENAME) //autojs
} }
try { try {
@ -37,13 +38,21 @@ class OpenAppService : JobIntentService() {
// Log.d("IOSTQ:", "执行新装任务") // Log.d("IOSTQ:", "执行新装任务")
// Util.setInfo(this) // Util.setInfo(this)
// } // }
ChangeDeviceInfoUtil.changeDeviceInfo() // ChangeDeviceInfoUtil.changeDeviceInfo()
ChangeDeviceInfoUtil.changeDevice(callBack = object : ChangeCallBack {
override fun changeSuccess() {
Util.openRecordApp(this@OpenAppService)
}
override fun changeFailed() {
Util.setFinish(this@OpenAppService)
}
})
} catch (e: IOException) { } catch (e: IOException) {
e.printStackTrace() e.printStackTrace()
} }
// Util.hookOpenApp(this); // Util.hookOpenApp(this);
Util.openRecordApp(this)
} }
companion object { companion object {

View File

@ -0,0 +1,6 @@
package com.android.grape.net
interface ChangeCallBack {
fun changeSuccess()
fun changeFailed()
}

View File

@ -2,22 +2,28 @@ package com.android.grape.net
import android.util.Log import android.util.Log
import com.blankj.utilcode.util.LogUtils import com.blankj.utilcode.util.LogUtils
import com.google.gson.Gson
import okhttp3.* import okhttp3.*
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.logging.HttpLoggingInterceptor
import okhttp3.logging.HttpLoggingInterceptor.Level
import okhttp3.logging.HttpLoggingInterceptor.Logger
import java.io.IOException import java.io.IOException
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
object HttpUtils { object HttpUtils {
const val HOST: String = "https://openapi-hk.armcloud.net"
// OkHttp客户端配置 // OkHttp客户端配置
private val client: OkHttpClient by lazy { private val client: OkHttpClient by lazy {
OkHttpClient.Builder() OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS) .connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS) .readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS) .writeTimeout(15, TimeUnit.SECONDS)
.addInterceptor(LoggingInterceptor()) // 添加日志拦截器 .addInterceptor(HttpLoggingInterceptor().apply {
level = Level.BODY
})
.build() .build()
} }
@ -30,47 +36,6 @@ object HttpUtils {
fun onFailure(error: String, code: Int?) fun onFailure(error: String, code: Int?)
} }
// 日志拦截器
private class LoggingInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val url = request.url.toString()
val method = request.method
// 记录请求信息
LogUtils.d("HTTP_REQUEST", "URL: $url")
LogUtils.d("HTTP_REQUEST", "Method: $method")
if ("POST" == method) {
request.body?.let { body ->
if (body is FormBody) {
val formBody = StringBuilder()
for (i in 0 until body.size) {
formBody.append("${body.name(i)}:${body.value(i)}; ")
}
Log.d("HTTP_REQUEST", "Form Data: $formBody")
} else if (body is MultipartBody) {
Log.d("HTTP_REQUEST", "Multipart Form Data")
} else {
Log.d("HTTP_REQUEST", "Body: ${body.contentType()}")
}
}
}
val response = chain.proceed(request)
val responseBody = response.peekBody(Long.MAX_VALUE)
val responseString = responseBody.string()
// 记录响应信息
LogUtils.d("HTTP_RESPONSE", "Code: ${response.code}")
LogUtils.d("HTTP_RESPONSE", "Response: $responseString")
return response.newBuilder()
.body(responseBody)
.build()
}
}
/** /**
* GET 请求异步 * GET 请求异步
* *
@ -82,10 +47,9 @@ object HttpUtils {
fun getAsync( fun getAsync(
url: String, url: String,
params: Map<String, String>? = null, params: Map<String, String>? = null,
headers: Map<String, String>? = null,
callback: HttpCallback callback: HttpCallback
) { ) {
val request = buildGetRequest(url, params, headers) val request = buildGetRequest(url, params)
executeRequestAsync(request, callback) executeRequestAsync(request, callback)
} }
@ -99,31 +63,10 @@ object HttpUtils {
*/ */
fun postAsync( fun postAsync(
url: String, url: String,
body: String, body: String? = null,
headers: Map<String, String>? = null,
callback: HttpCallback callback: HttpCallback
) { ) {
val requestBody = body.toRequestBody(JSON_MEDIA_TYPE) val request = buildPostRequest(url, body)
val request = buildPostRequest(url, requestBody, headers)
executeRequestAsync(request, callback)
}
/**
* POST Form Data 请求异步
*
* @param url 请求URL
* @param formData 表单数据
* @param headers 请求头可选
* @param callback 回调接口
*/
fun postFormAsync(
url: String,
formData: Map<String, String>,
headers: Map<String, String>? = null,
callback: HttpCallback
) {
val formBody = buildFormBody(formData)
val request = buildPostRequest(url, formBody, headers)
executeRequestAsync(request, callback) executeRequestAsync(request, callback)
} }
@ -138,9 +81,8 @@ object HttpUtils {
fun getSync( fun getSync(
url: String, url: String,
params: Map<String, String>? = null, params: Map<String, String>? = null,
headers: Map<String, String>? = null
): Pair<String?, Int> { ): Pair<String?, Int> {
val request = buildGetRequest(url, params, headers) val request = buildGetRequest(url, params)
return executeRequestSync(request) return executeRequestSync(request)
} }
@ -154,11 +96,9 @@ object HttpUtils {
*/ */
fun postSync( fun postSync(
url: String, url: String,
body: String, body: String? = null
headers: Map<String, String>? = null
): Pair<String?, Int> { ): Pair<String?, Int> {
val requestBody = body.toRequestBody(JSON_MEDIA_TYPE) val request = buildPostRequest(url, body)
val request = buildPostRequest(url, requestBody, headers)
return executeRequestSync(request) return executeRequestSync(request)
} }
@ -172,46 +112,72 @@ object HttpUtils {
// 内部方法 -------------------------------- // 内部方法 --------------------------------
private fun buildGetRequest( private fun buildGetRequest(
url: String, path: String ,
params: Map<String, String>?, params: Map<String, String>?,
headers: Map<String, String>?
): Request { ): Request {
val url = "$HOST$path"
val httpUrlBuilder = url.toHttpUrlOrNull()?.newBuilder() val httpUrlBuilder = url.toHttpUrlOrNull()?.newBuilder()
?: throw IllegalArgumentException("Invalid URL: $url") ?: throw IllegalArgumentException("Invalid URL: $url")
// 添加查询参数 var param = ""
params?.forEach { (key, value) -> params?.forEach { (key, value) ->
httpUrlBuilder.addQueryParameter(key, value) httpUrlBuilder.addQueryParameter(key, value)
param += "&${key}=${value}"
}
if (param.isNotEmpty()){
param = param.substring(1)
} }
val requestBuilder = Request.Builder().url(httpUrlBuilder.build()) val requestBuilder = Request.Builder().url(httpUrlBuilder.build())
// 添加请求头 val authver = "2.0"
addHeaders(requestBuilder, headers) val timestamp = System.currentTimeMillis()
val sign =
ArmCloudSignatureV2.calculateSignature(timestamp.toString(), path, param)
addHeaders(
requestBuilder,
mapOf(
"authver" to authver,
"x-ak" to ArmCloudSignatureV2.SECRET_KEY,
"x-timestamp" to timestamp.toString(),
"x-sign" to sign
)
)
return requestBuilder.build() return requestBuilder.build()
} }
private fun buildPostRequest( private fun buildPostRequest(
url: String, path: String,
body: RequestBody, body: String? = null
headers: Map<String, String>?
): Request { ): Request {
val url = "$HOST$path"
val bodyString = body?:""
val requestBuilder = Request.Builder() val requestBuilder = Request.Builder()
.url(url) .url(url)
.post(body) .post(bodyString.toRequestBody(JSON_MEDIA_TYPE))
val authver = "2.0"
// 添加请求头 val timestamp = System.currentTimeMillis()
addHeaders(requestBuilder, headers) val sign =
ArmCloudSignatureV2.calculateSignature(timestamp.toString(), path, body)
addHeaders(
requestBuilder,
mapOf(
"authver" to authver,
"x-ak" to ArmCloudSignatureV2.SECRET_KEY,
"x-timestamp" to timestamp.toString(),
"x-sign" to sign
)
)
return requestBuilder.build() return requestBuilder.build()
} }
private fun addHeaders( private fun addHeaders(
builder: Request.Builder, builder: Request.Builder,
headers: Map<String, String>? headers: Map<String, String>
) { ) {
headers?.forEach { (key, value) -> headers.forEach { (key, value) ->
builder.addHeader(key, value) builder.addHeader(key, value)
} }
} }
@ -252,13 +218,13 @@ object HttpUtils {
private fun executeRequestSync(request: Request): Pair<String?, Int> { private fun executeRequestSync(request: Request): Pair<String?, Int> {
return try { return try {
val response = client.newCall(request).execute() val response = client.newCall(request).execute()
val responseBody = response.body?.string() val responseBody = response.peekBody(Long.MAX_VALUE).string()
val code = response.code val code = response.code
Log.d("TAG", "executeRequestSync: $responseBody")
if (response.isSuccessful && responseBody != null) { if (response.isSuccessful && responseBody.isNotEmpty()) {
Pair(responseBody, code) Pair(responseBody, code)
} else { } else {
Pair(null, code) Pair(null, -1)
} }
} catch (e: IOException) { } catch (e: IOException) {
Pair(null, -1) // 网络错误状态码 Pair(null, -1) // 网络错误状态码

View File

@ -140,7 +140,7 @@ object MyGet {
httpUrlConnection = url.openConnection() as HttpURLConnection httpUrlConnection = url.openConnection() as HttpURLConnection
httpUrlConnection.allowUserInteraction = true httpUrlConnection.allowUserInteraction = true
httpUrlConnection!!.doOutput = false httpUrlConnection.doOutput = false
httpUrlConnection.doInput = true httpUrlConnection.doInput = true
httpUrlConnection.useCaches = false httpUrlConnection.useCaches = false
httpUrlConnection.instanceFollowRedirects = false httpUrlConnection.instanceFollowRedirects = false

View File

@ -1,5 +0,0 @@
package com.android.grape.net
class NetworkHelper {
}

View File

@ -5,14 +5,168 @@ import android.content.Context
import android.util.Log import android.util.Log
import com.android.grape.MainApplication import com.android.grape.MainApplication
import com.android.grape.data.Device import com.android.grape.data.Device
import com.android.grape.net.Api
import com.android.grape.net.ChangeCallBack
import com.android.grape.util.Util.paramsJson import com.android.grape.util.Util.paramsJson
import com.blankj.utilcode.util.LogUtils import com.blankj.utilcode.util.LogUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import java.lang.reflect.InvocationTargetException import java.lang.reflect.InvocationTargetException
object ChangeDeviceInfoUtil { object ChangeDeviceInfoUtil {
val scope = CoroutineScope(Dispatchers.IO)
fun changeDevice(callBack: ChangeCallBack){
try {
val deviceObject = paramsJson?.getJSONObject("device")
if (deviceObject == null) {
LogUtils.d("ERROR", "ChangeDeviceInfoUtil", "device is null")
return
}
val device = GsonUtils.fromJsonObject(deviceObject.toString(), Device::class.java)
val padCode = ShellUtils.execRootCmdAndGetResult("getprop ro.boot.pad_code")
Log.d("TAG", "changeDevice: $padCode")
val jsonString = JSONObject().apply {
put("padCodes", JSONArray().apply {
put(padCode)
})
put("modemPropertiesList", JSONArray().apply {
put(JSONObject().apply {
put("propertiesName", "MCCMNC")
put("propertiesValue", "${device.mcc},${device.mnc}")
})
})
put("systemPropertiesList", JSONArray().apply {
put(JSONObject().apply {
put("propertiesName", "ro.product.manufacturer")
put("propertiesValue", device.manufactor)
})
put(JSONObject().apply {
put("propertiesName", "ro.product.brand")
put("propertiesValue", device.brand)
})
put(JSONObject().apply {
put("propertiesName", "ro.product.model")
put("propertiesValue", device.model)
})
// put(JSONObject().apply {
// put("propertiesName", "ro.build.id")
// put("propertiesValue", device.buildDisplayId)
// })
put(JSONObject().apply {
put("propertiesName", "ro.build.display.id")
put("propertiesValue", device.buildDisplayId)
})
put(JSONObject().apply {
put("propertiesName", "ro.product.name")
put("propertiesValue", device.product)
})
put(JSONObject().apply {
put("propertiesName", "ro.product.device")
put("propertiesValue", device.device)
})
put(JSONObject().apply {
put("propertiesName", "ro.product.board")
put("propertiesValue", device.expand.board)
})
// put(JSONObject().apply {
// put("propertiesName", "ro.build.tags")
// put("propertiesValue", device.expand)
// })
put(JSONObject().apply {
put("propertiesName", "ro.build.fingerprint")
put("propertiesValue", device.expand.fingerprint)
})
put(JSONObject().apply {
put("propertiesName", "ro.build.date.utc")
put("propertiesValue", device.expand.roBuildDateUtc)
})
put(JSONObject().apply {
put("propertiesName", "ro.build.user")
put("propertiesValue", device.expand.uname)
})
// put(JSONObject().apply {
// put("propertiesName", "ro.build.host")
// put("propertiesValue", device.expand.)
// })
put(JSONObject().apply {
put("propertiesName", "ro.build.description")
put("propertiesValue", device.expand.roBuildDescription)
})
put(JSONObject().apply {
put("propertiesName", "ro.build.version.incremental")
put("propertiesValue", device.expand.incremental)
})
// put(JSONObject().apply {
// put("propertiesName", "ro.build.version.codename")
// put("propertiesValue", device.cod)
// })
})
put("settingPropertiesList", JSONArray().apply {
put(JSONObject().apply {
put("propertiesName", "ssaid/${Util.recordPackageName}")
put("propertiesValue", device.androidId)
})
put(JSONObject().apply {
put("propertiesName", "bt/mac")
put("propertiesValue", device.expand.lyMAC)
})
put(JSONObject().apply {
put("propertiesName", "language")
put("propertiesValue", device.locale.lang)
})
put(JSONObject().apply {
put("propertiesName", "timezone")
put("propertiesValue", device.tzDisplayName)
})
// put(JSONObject().apply {
// put("propertiesName", "systemvolume")
// put("propertiesValue", device.expand.)
// })
})
put("oaidPropertiesList", JSONArray().apply {
put(JSONObject().apply {
put("propertiesName", "AAID")
put("propertiesValue", device.advertiserId)
})
})
}.toString()
val response = Api.updatePad(jsonString)
val dataList = response.data
if (response.isSuccess() && dataList!= null && dataList.isNotEmpty()){
val padTask = dataList[0]
scope.launch {
Log.d("TAG", "changeDevice: $padTask")
var loop = true
while (loop) {
delay(5000)
val result = Api.padTaskDetail(padTask.taskId)
if (result == 3) {
Log.d("ChangeDeviceInfoUtil", "changeDeviceInfo changeDeviceInfo success")
loop = false
callBack.changeSuccess()
} else if (result == -1) {
Log.d("ChangeDeviceInfoUtil", "changeDeviceInfo changeDeviceInfo fail")
loop = false
callBack.changeFailed()
}
}
}
}
} catch (e: JSONException) {
e.printStackTrace()
}
}
fun changeDeviceInfo() { fun changeDeviceInfo() {
try { try {
MockTools.exec("pm grant com.android.grape android.permission.INTERACT_ACROSS_USERS")
MockTools.exec("pm grant com.android.grape android.permission.WRITE_SECURE_SETTINGS")
MockTools.exec("pm setenforce 0")
val deviceObject = paramsJson?.getJSONObject("device") val deviceObject = paramsJson?.getJSONObject("device")
if (deviceObject == null) { if (deviceObject == null) {
LogUtils.d("ERROR", "ChangeDeviceInfoUtil", "device is null") LogUtils.d("ERROR", "ChangeDeviceInfoUtil", "device is null")
@ -51,7 +205,7 @@ object ChangeDeviceInfoUtil {
// **os_ver** // **os_ver**
vcloudsettingsPut(currentPkgName + "_os_ver", device.sdkVer, context) vcloudsettingsPut(currentPkgName + "_os_ver", device.sdkVer, context)
// **tz** (时区) // **tz** (时区)
vcloudsettingsPut(currentPkgName + "_tz", device.tzOffTime.toString(), context) vcloudsettingsPut(currentPkgName + "_tz", TimeZoneUtils.formatTimeZoneOffset(device.tzOffTime), context)
vcloudsettingsPut("$currentPkgName.advertiserId", device.advertiserId, context) vcloudsettingsPut("$currentPkgName.advertiserId", device.advertiserId, context)
vcloudsettingsPut("$currentPkgName.brand", device.brand, context) vcloudsettingsPut("$currentPkgName.brand", device.brand, context)
@ -121,6 +275,9 @@ object ChangeDeviceInfoUtil {
ShellUtils.execRootCmd("setprop persist.sys.cloud.battery.capacity ${device.battery}") ShellUtils.execRootCmd("setprop persist.sys.cloud.battery.capacity ${device.battery}")
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_vendor ${device.expand.glVendor}") ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_vendor ${device.expand.glVendor}")
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_renderer ${device.expand.glRenderer}") ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_renderer ${device.expand.glRenderer}")
ShellUtils.execRootCmd("setprop persist.sys.timezone ${TimeZoneUtils.formatTimeZoneOffset(device.tzOffTime)}")
ShellUtils.execRootCmd("setprop persist.sys.country ${device.country}")
ShellUtils.execRootCmd("setprop persist.sys.language ${device.expand.displayLang}")
// 这个值不能随便改 必须是 OpenGL ES %d.%d 这个格式 // 这个值不能随便改 必须是 OpenGL ES %d.%d 这个格式
ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_version ${device.expand.glVersion}") ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.gl_version ${device.expand.glVersion}")
// ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.egl_vendor $persist_sys_cloud_gpu_egl_vendor") // ShellUtils.execRootCmd("setprop persist.sys.cloud.gpu.egl_vendor $persist_sys_cloud_gpu_egl_vendor")

View File

@ -12,25 +12,26 @@ object MockTools {
fun exec(cmd: String): String { fun exec(cmd: String): String {
var retString = "" var retString = ""
try { try {
//创建socket retString = ShellUtils.execRootCmdAndGetResult(cmd)
val myCmd = "SU|$cmd" // //创建socket
// val myCmd = "SU|$cmd"
val mSocket = Socket() //
val inetSocketAddress = InetSocketAddress("127.0.0.1", 12345) // val mSocket = Socket()
mSocket.connect(inetSocketAddress) // val inetSocketAddress = InetSocketAddress("127.0.0.1", 12345)
val bufferedWriter = BufferedWriter(OutputStreamWriter(mSocket.getOutputStream())) // mSocket.connect(inetSocketAddress)
val bufferedReader = BufferedReader(InputStreamReader(mSocket.getInputStream())) // val bufferedWriter = BufferedWriter(OutputStreamWriter(mSocket.getOutputStream()))
bufferedWriter.write(myCmd + "\r\n") // val bufferedReader = BufferedReader(InputStreamReader(mSocket.getInputStream()))
bufferedWriter.flush() // bufferedWriter.write(myCmd + "\r\n")
val stringBuilder = StringBuilder() // bufferedWriter.flush()
var line: String? = null // val stringBuilder = StringBuilder()
while ((bufferedReader.readLine().also { line = it }) != null) { // var line: String? = null
stringBuilder.append(line + "\n") // while ((bufferedReader.readLine().also { line = it }) != null) {
} // stringBuilder.append(line + "\n")
//retString = bufferedReader.readLine(); // }
retString = stringBuilder.toString() // //retString = bufferedReader.readLine();
bufferedReader.close() // retString = stringBuilder.toString()
bufferedWriter.close() // bufferedReader.close()
// bufferedWriter.close()
} catch (eeeee: Exception) { } catch (eeeee: Exception) {
eeeee.printStackTrace() eeeee.printStackTrace()
} }
@ -40,25 +41,26 @@ object MockTools {
fun execRead(cmd: String): String { fun execRead(cmd: String): String {
var retString = "" var retString = ""
try { try {
//创建socket retString = ShellUtils.execRootCmdAndGetResult(cmd)
val myCmd = "SU_1|$cmd" // //创建socket
// val myCmd = "SU_1|$cmd"
val mSocket = Socket() //
val inetSocketAddress = InetSocketAddress("127.0.0.1", 12345) // val mSocket = Socket()
mSocket.connect(inetSocketAddress) // val inetSocketAddress = InetSocketAddress("127.0.0.1", 12345)
val bufferedWriter = BufferedWriter(OutputStreamWriter(mSocket.getOutputStream())) // mSocket.connect(inetSocketAddress)
val bufferedReader = BufferedReader(InputStreamReader(mSocket.getInputStream())) // val bufferedWriter = BufferedWriter(OutputStreamWriter(mSocket.getOutputStream()))
bufferedWriter.write(myCmd + "\r\n") // val bufferedReader = BufferedReader(InputStreamReader(mSocket.getInputStream()))
bufferedWriter.flush() // bufferedWriter.write(myCmd + "\r\n")
val stringBuilder = StringBuilder() // bufferedWriter.flush()
var line: String? = null // val stringBuilder = StringBuilder()
while ((bufferedReader.readLine().also { line = it }) != null) { // var line: String? = null
stringBuilder.append(line + "\n") // while ((bufferedReader.readLine().also { line = it }) != null) {
} // stringBuilder.append(line + "\n")
retString = stringBuilder.toString() // }
//retString = bufferedReader.readLine(); // retString = stringBuilder.toString()
bufferedReader.close() // //retString = bufferedReader.readLine();
bufferedWriter.close() // bufferedReader.close()
// bufferedWriter.close()
} catch (eeeee: Exception) { } catch (eeeee: Exception) {
eeeee.printStackTrace() eeeee.printStackTrace()
} }

View File

@ -8,6 +8,7 @@ import android.content.pm.PackageManager
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.provider.Settings import android.provider.Settings
import android.util.Log
import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
@ -106,7 +107,7 @@ class NotificationPermissionHandler(
fun requestNotificationPermission() { fun requestNotificationPermission() {
// 保存当前权限状态,用于比较设置后是否发生变化 // 保存当前权限状态,用于比较设置后是否发生变化
lastPermissionState = areNotificationsEnabled() lastPermissionState = areNotificationsEnabled()
Log.d(TAG, "requestNotificationPermission: ")
when { when {
// Android 13+ - 使用运行时权限请求 // Android 13+ - 使用运行时权限请求
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> { Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
@ -198,22 +199,23 @@ class NotificationPermissionHandler(
} }
val activity = context as? AppCompatActivity ?: return val activity = context as? AppCompatActivity ?: return
Log.d(TAG, "requestPermissionApi33: ")
when { when {
// 已经拥有权限 // 已经拥有权限
areNotificationsEnabled() -> { areNotificationsEnabled() -> {
callback(PermissionResult.GRANTED) callback(PermissionResult.GRANTED)
} }
// 需要显示权限解释 // 需要显示权限解释
ActivityCompat.shouldShowRequestPermissionRationale( // ActivityCompat.shouldShowRequestPermissionRationale(
activity, // activity,
Manifest.permission.POST_NOTIFICATIONS // Manifest.permission.POST_NOTIFICATIONS
) -> { // ) -> {
showPermissionRationaleDialog() // showPermissionRationaleDialog()
} // }
// 请求权限 // 请求权限
else -> { else -> {
permissionRequestPending = true permissionRequestPending = true
Log.d(TAG, "requestPermissionApi33: launch")
permissionLauncher?.launch(Manifest.permission.POST_NOTIFICATIONS) permissionLauncher?.launch(Manifest.permission.POST_NOTIFICATIONS)
} }
} }
@ -276,28 +278,36 @@ class NotificationPermissionHandler(
} }
companion object { companion object {
private const val TAG = "NotificationPermissionH"
/** /**
* 快速检查当前设备的通知权限状态 * 快速检查当前设备的通知权限状态
*/ */
@JvmStatic @JvmStatic
fun checkPermissionState(context: Context): PermissionResult { fun checkPermissionState(context: Context): PermissionResult {
Log.d(TAG, "checkPermissionState: --------->")
return when { return when {
// Android 13+ 需要运行时权限 // Android 13+ 需要运行时权限
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> { Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> {
Log.d(TAG, "checkPermissionState: Android 13+")
if (ContextCompat.checkSelfPermission( if (ContextCompat.checkSelfPermission(
context, context,
Manifest.permission.POST_NOTIFICATIONS Manifest.permission.POST_NOTIFICATIONS
) == PackageManager.PERMISSION_GRANTED) { ) == PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, "checkPermissionState: Granted")
PermissionResult.GRANTED PermissionResult.GRANTED
} else { } else {
Log.d(TAG, "checkPermissionState: Denied")
PermissionResult.DENIED PermissionResult.DENIED
} }
} }
// Android 8.0+ 检查通知设置 // Android 8.0+ 检查通知设置
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> { Build.VERSION.SDK_INT >= Build.VERSION_CODES.O -> {
Log.d(TAG, "checkPermissionState: Android 8.0+")
if (NotificationManagerCompat.from(context).areNotificationsEnabled()) { if (NotificationManagerCompat.from(context).areNotificationsEnabled()) {
Log.d(TAG, "checkPermissionState: Granted")
PermissionResult.GRANTED PermissionResult.GRANTED
} else { } else {
Log.d(TAG, "checkPermissionState: Denied")
PermissionResult.NEEDS_SETTINGS PermissionResult.NEEDS_SETTINGS
} }
} }

View File

@ -102,7 +102,7 @@ public class ShellUtils {
} }
public static String execRootCmdAndGetResult(String cmd) { public static String execRootCmdAndGetResult(String cmd) {
Log.d("ShellUtils", "execRootCmdAndGetResult - Started execution for command: " + cmd); // Log.d("ShellUtils", "execRootCmdAndGetResult - Started execution for command: " + cmd);
if (cmd == null || cmd.trim().isEmpty()) { if (cmd == null || cmd.trim().isEmpty()) {
LogUtils.e(Log.ERROR, "ShellUtils", "Unsafe or empty command. Aborting execution.", null); LogUtils.e(Log.ERROR, "ShellUtils", "Unsafe or empty command. Aborting execution.", null);
throw new IllegalArgumentException("Unsafe or empty command."); throw new IllegalArgumentException("Unsafe or empty command.");
@ -116,18 +116,18 @@ public class ShellUtils {
ExecutorService executor = Executors.newFixedThreadPool(2); ExecutorService executor = Executors.newFixedThreadPool(2);
try { try {
Log.d("ShellUtils", "Determining appropriate shell for execution..."); // Log.d("ShellUtils", "Determining appropriate shell for execution...");
if (hasBin("su")) { if (hasBin("su")) {
Log.d("ShellUtils", "'su' binary found, using 'su' shell."); // Log.d("ShellUtils", "'su' binary found, using 'su' shell.");
process = Runtime.getRuntime().exec("su"); process = Runtime.getRuntime().exec("su");
} else if (hasBin("xu")) { } else if (hasBin("xu")) {
Log.d("ShellUtils", "'xu' binary found, using 'xu' shell."); // Log.d("ShellUtils", "'xu' binary found, using 'xu' shell.");
process = Runtime.getRuntime().exec("xu"); process = Runtime.getRuntime().exec("xu");
} else if (hasBin("vu")) { } else if (hasBin("vu")) {
Log.d("ShellUtils", "'vu' binary found, using 'vu' shell."); // Log.d("ShellUtils", "'vu' binary found, using 'vu' shell.");
process = Runtime.getRuntime().exec("vu"); process = Runtime.getRuntime().exec("vu");
} else { } else {
Log.d("ShellUtils", "No specific binary found, using 'sh' shell."); // Log.d("ShellUtils", "No specific binary found, using 'sh' shell.");
process = Runtime.getRuntime().exec("sh"); process = Runtime.getRuntime().exec("sh");
} }
@ -137,7 +137,7 @@ public class ShellUtils {
BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorStream, StandardCharsets.UTF_8))) { BufferedReader errorReader = new BufferedReader(new InputStreamReader(errorStream, StandardCharsets.UTF_8))) {
Log.d("ShellUtils", "Starting separate thread to process error stream..."); // Log.d("ShellUtils", "Starting separate thread to process error stream...");
executor.submit(() -> { executor.submit(() -> {
String line; String line;
try { try {
@ -149,28 +149,28 @@ public class ShellUtils {
} }
}); });
Log.d("ShellUtils", "Writing the command to the shell..."); // Log.d("ShellUtils", "Writing the command to the shell...");
os.write((cmd + "\n").getBytes()); os.write((cmd + "\n").getBytes());
os.write("exit\n".getBytes()); os.write("exit\n".getBytes());
os.flush(); os.flush();
Log.d("ShellUtils", "Command written to shell. Waiting for process to complete."); // Log.d("ShellUtils", "Command written to shell. Waiting for process to complete.");
StringBuilder output = new StringBuilder(); StringBuilder output = new StringBuilder();
String line; String line;
while ((line = br.readLine()) != null) { while ((line = br.readLine()) != null) {
Log.d("ShellUtils", "Shell Output: " + line); // Log.d("ShellUtils", "Shell Output: " + line);
output.append(line).append("\n"); output.append(line).append("\n");
} }
Log.d("ShellUtils", "Awaiting process termination..."); // Log.d("ShellUtils", "Awaiting process termination...");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!process.waitFor(10, TimeUnit.SECONDS)) { if (!process.waitFor(10, TimeUnit.SECONDS)) {
LogUtils.e(Log.ERROR, "ShellUtils", "Process execution timed out. Destroying process.", null); // LogUtils.e(Log.ERROR, "ShellUtils", "Process execution timed out. Destroying process.", null);
process.destroyForcibly(); process.destroyForcibly();
throw new RuntimeException("Shell command execution timeout."); throw new RuntimeException("Shell command execution timeout.");
} }
} else { } else {
Log.d("ShellUtils", "Using manual time tracking method for process termination (API < 26)."); // Log.d("ShellUtils", "Using manual time tracking method for process termination (API < 26).");
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
while (true) { while (true) {
try { try {
@ -178,7 +178,7 @@ public class ShellUtils {
break; break;
} catch (IllegalThreadStateException e) { } catch (IllegalThreadStateException e) {
if (System.currentTimeMillis() - startTime > 10000) { // 10 seconds if (System.currentTimeMillis() - startTime > 10000) { // 10 seconds
LogUtils.e(Log.ERROR, "ShellUtils", "Process execution timed out (manual tracking). Destroying process.", null); // LogUtils.e(Log.ERROR, "ShellUtils", "Process execution timed out (manual tracking). Destroying process.", null);
process.destroy(); process.destroy();
throw new RuntimeException("Shell command execution timeout."); throw new RuntimeException("Shell command execution timeout.");
} }

View File

@ -73,7 +73,7 @@ object Util {
private const val sendRefer = true private const val sendRefer = true
var isNeedRestored: Boolean = false var isNeedRestored: Boolean = false
const val AUTO_PACKAGENAME: String = "com.play4u.luabox" const val AUTO_PACKAGENAME: String = "com.play4u.luabox"
const val AUTO_JSPACKAGENAME: String = "org.autojs.autojs" const val AUTO_JSPACKAGENAME: String = "org.autojs.autojs6"
const val proxy_packagename: String = "com.tunnelworkshop.postern" const val proxy_packagename: String = "com.tunnelworkshop.postern"
const val AUTO_CLASSNAME: String = "com.cyjh.elfin.activity.SplashActivity" const val AUTO_CLASSNAME: String = "com.cyjh.elfin.activity.SplashActivity"
private const val hookPackageName = "com.affsystem.androidhooker" private const val hookPackageName = "com.affsystem.androidhooker"
@ -696,8 +696,8 @@ object Util {
val result: String? = MyPost.postData(" ".toByteArray(charset = Charsets.UTF_8), val result: String? = MyPost.postData(" ".toByteArray(charset = Charsets.UTF_8),
"$url?$params" "$url?$params"
) )
LogUtils.e("IOSTQ:execReloginTask->result:$result")
if (result != null && result.length > 0) { if (result != null && result.isNotEmpty()) {
taskJson = JSONObject(result).apply { taskJson = JSONObject(result).apply {
val code = getInt("code") val code = getInt("code")
if (code == 1) { if (code == 1) {
@ -749,9 +749,9 @@ object Util {
"$url?$params" "$url?$params"
) )
printStr("request result : $result") LogUtils.e("request result : $result")
if (result != null && result.length > 0) { if (result != null && result.isNotEmpty()) {
taskJson = JSONObject(result) taskJson = JSONObject(result)
val code = taskJson!!.getInt("code") val code = taskJson!!.getInt("code")
@ -1045,7 +1045,7 @@ object Util {
val ret: String? = MyPost.postData("".toByteArray(), url) val ret: String? = MyPost.postData("".toByteArray(), url)
Log.i(TAG, "ret:$ret") Log.i(TAG, "ret:$ret")
val jo = JSONObject(ret) val jo = JSONObject(ret?:"")
if (jo.getInt("code") == 1) { if (jo.getInt("code") == 1) {
regEmailJson = jo.getJSONObject("emailInfo") regEmailJson = jo.getJSONObject("emailInfo")
@ -1554,11 +1554,13 @@ object Util {
fun openRecordApp(context: Context) { fun openRecordApp(context: Context) {
if (scriptOpenApp == 0) { if (scriptOpenApp == 0) {
recordPackageName?.let {
execTargetApp( execTargetApp(
context, context,
recordPackageName!! it
) )
} }
}
if (!isCanAuto || canAutoLc.length <= 10) { if (!isCanAuto || canAutoLc.length <= 10) {
Handler(Looper.getMainLooper()).postDelayed(Runnable { Handler(Looper.getMainLooper()).postDelayed(Runnable {
@ -1618,10 +1620,12 @@ object Util {
if (!file.exists()) { if (!file.exists()) {
val parent = file.parentFile val parent = file.parentFile
if (parent!!.exists()) { if (parent?.exists() == true) {
file.mkdir() file.mkdir()
} else { } else {
if (parent != null) {
forceCreteDir(parent) forceCreteDir(parent)
}
file.mkdir() file.mkdir()
} }
} }
@ -1631,7 +1635,8 @@ object Util {
if (!file.exists()) { if (!file.exists()) {
val parent = file.parentFile val parent = file.parentFile
if (!parent!!.exists()) { parent?.exists()?.let {
if (!it) {
MockTools.exec("mkdir $parent") MockTools.exec("mkdir $parent")
forceMakeDir(parent) forceMakeDir(parent)
// file.mkdirs(); // file.mkdirs();
@ -1640,6 +1645,7 @@ object Util {
} }
} }
} }
}
fun writeFile1(context: Context?, dirName: String, fileName: String, contents: String) { fun writeFile1(context: Context?, dirName: String, fileName: String, contents: String) {
val fs = File("$dirName/$fileName") val fs = File("$dirName/$fileName")
@ -1764,7 +1770,11 @@ object Util {
} }
val create_dir = file.parentFile val create_dir = file.parentFile
forceMakeDir(create_dir!!) if (create_dir != null && !create_dir.exists()){
forceMakeDir(create_dir)
}else if (create_dir == null){
return false
}
val fileLength = 0L val fileLength = 0L
@ -1777,7 +1787,7 @@ object Util {
try { try {
conn = url.openConnection() as HttpURLConnection conn = url.openConnection() as HttpURLConnection
`is` = conn!!.inputStream `is` = conn.inputStream
fos = FileOutputStream(file) fos = FileOutputStream(file)
val buf = ByteArray(256) val buf = ByteArray(256)
conn.connect() conn.connect()
@ -1806,15 +1816,15 @@ object Util {
e.printStackTrace() e.printStackTrace()
} finally { } finally {
try { try {
conn!!.disconnect() conn?.disconnect()
} catch (e: Exception) { } catch (e: Exception) {
} }
try { try {
fos!!.close() fos?.close()
} catch (e: Exception) { } catch (e: Exception) {
} }
try { try {
`is`!!.close() `is`?.close()
} catch (e: Exception) { } catch (e: Exception) {
} }
} }
@ -2046,17 +2056,19 @@ object Util {
} }
fun installApks4Tmp(apkName: String?, context: Context?): Boolean { fun installApks4Tmp(apkName: String?, context: Context): Boolean {
var result = MockTools.execRead("pm install-create") var result = MockTools.execRead("pm install-create")
Log.d(TAG, "installApks4Tmp: successMsg $result") Log.d(TAG, "installApks4Tmp: successMsg $result")
val session = result.substring(result.indexOf("[") + 1, result.indexOf("]")) val session = result.substring(result.indexOf("[") + 1, result.indexOf("]"))
Log.d(TAG, "installApks4Tmp: session $session") Log.d(TAG, "installApks4Tmp: session $session")
val file = File("/sdcard/apks/$apkName") val file = File(getRecordDataDirName(context))
Log.d(TAG, "installApks4Tmp: ${file.absolutePath}")
val files = file.listFiles() val files = file.listFiles()
var bool = true var bool = true
var currentApkFile = 1 var currentApkFile = 1
for (f in files) { files?.let {
for (f in it) {
val extraName = f.name.substring(f.name.lastIndexOf('.') + 1) val extraName = f.name.substring(f.name.lastIndexOf('.') + 1)
Log.d( Log.d(
TAG, TAG,
@ -2075,6 +2087,8 @@ object Util {
} }
} }
} }
}
if (bool) { if (bool) {
result = MockTools.execRead("pm install-commit $session") result = MockTools.execRead("pm install-commit $session")
if (!result.contains("Success")) { if (!result.contains("Success")) {
@ -2083,9 +2097,11 @@ object Util {
} else { } else {
result = MockTools.execRead("pm install-abandon $session") result = MockTools.execRead("pm install-abandon $session")
} }
for (f in files) { files?.let {
for (f in it) {
MockTools.execRead("rm -rf $f") MockTools.execRead("rm -rf $f")
} }
}
setInstallRet(bool) setInstallRet(bool)
return bool return bool
} }
@ -2420,7 +2436,7 @@ object Util {
} }
tags = filterStr(tags) tags = filterStr(tags)
// Log.e(TAG, "getCid:*"+tags+"*"); // Log.e(TAG, "getCid:*"+tags+"*");
return tags!! return tags?:""
} }
fun getPropertiesFromAssets(context: Context, fileName: String): Properties { fun getPropertiesFromAssets(context: Context, fileName: String): Properties {

View File

@ -10,6 +10,7 @@ import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import com.android.grape.service.MyAccessibilityService import com.android.grape.service.MyAccessibilityService
import androidx.core.content.edit import androidx.core.content.edit
import com.android.grape.job.MonitorService
class CheckAccessibilityWorker( class CheckAccessibilityWorker(
context: Context, context: Context,