改机失败重新执行任务

This commit is contained in:
Administrator 2025-07-09 15:51:23 +08:00
parent f6b4de5838
commit 6667d0babd
8 changed files with 339 additions and 109 deletions

View File

@ -66,6 +66,14 @@
android:name="android.accessibilityservice" android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" /> android:resource="@xml/accessibility_service_config" />
</service> </service>
<service android:name="com.example.studyapp.job.StartJobService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE"/>
<service android:name="com.example.studyapp.job.ScriptJobService"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_JOB_SERVICE"/>
</application> </application>
<queries> <queries>

View File

@ -36,11 +36,13 @@ import androidx.work.WorkManager;
import com.example.studyapp.autoJS.AutoJsUtil; import com.example.studyapp.autoJS.AutoJsUtil;
import com.example.studyapp.device.ChangeDeviceInfoUtil; import com.example.studyapp.device.ChangeDeviceInfoUtil;
import com.example.studyapp.job.StartJobService;
import com.example.studyapp.proxy.ClashUtil; import com.example.studyapp.proxy.ClashUtil;
import com.example.studyapp.service.MyAccessibilityService; import com.example.studyapp.service.MyAccessibilityService;
import com.example.studyapp.task.TaskUtil; import com.example.studyapp.task.TaskUtil;
import com.example.studyapp.update.ChangeCallBack; import com.example.studyapp.update.ChangeCallBack;
import com.example.studyapp.update.UpdateUtil; import com.example.studyapp.update.UpdateUtil;
import com.example.studyapp.utils.CountryCode;
import com.example.studyapp.utils.IpUtil; import com.example.studyapp.utils.IpUtil;
import com.example.studyapp.utils.LogFileUtil; import com.example.studyapp.utils.LogFileUtil;
import com.example.studyapp.utils.ShellUtils; import com.example.studyapp.utils.ShellUtils;
@ -86,19 +88,6 @@ public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity"; private static final String TAG = "MainActivity";
private static final String PACKAGE_SCHEME = "package:"; private static final String PACKAGE_SCHEME = "package:";
private static final int DEVICE_TYPE = 2;
// 定义支持的国家代码常量
private static final class CountryCode {
static final String US = "US";
static final String RU = "RU";
// 默认使用美国
static final String DEFAULT = US;
}
// 当前使用的国家代码
private String currentCountry = CountryCode.DEFAULT;
// 初始化 ExecutorService // 初始化 ExecutorService
private void initializeExecutorService() { private void initializeExecutorService() {
@ -189,16 +178,6 @@ public class MainActivity extends AppCompatActivity {
WorkManager.getInstance(this).enqueue(workRequest); WorkManager.getInstance(this).enqueue(workRequest);
} }
// 添加切换国家的方法
private String switchCountry() {
currentCountry = currentCountry.equals(CountryCode.US) ?
CountryCode.RU : CountryCode.US;
LogFileUtil.logAndWrite(Log.INFO, TAG,
"Switched country to: " + currentCountry, null);
return currentCountry;
}
private void initializeButtons() { private void initializeButtons() {
LogFileUtil.logAndWrite(Log.INFO, TAG, "onCreate: Setting up UI components", null); LogFileUtil.logAndWrite(Log.INFO, TAG, "onCreate: Setting up UI components", null);
String androidId = getAndroidId(this); String androidId = getAndroidId(this);
@ -209,7 +188,7 @@ public class MainActivity extends AppCompatActivity {
})); }));
setupButton(R.id.disconnectVpnButton, v -> ClashUtil.stopProxy(this)); setupButton(R.id.disconnectVpnButton, v -> ClashUtil.stopProxy(this));
setupButton(R.id.switchVpnButton, v -> { setupButton(R.id.switchVpnButton, v -> {
ClashUtil.switchProxyGroup("GLOBAL", switchCountry(), "http://127.0.0.1:6170"); ClashUtil.switchProxyGroup("GLOBAL", CountryCode.switchCountry(), "http://127.0.0.1:6170");
}); });
setupButton(R.id.resetDeviceInfoButton, setupButton(R.id.resetDeviceInfoButton,
v -> ChangeDeviceInfoUtil.resetChangedDeviceInfo(getPackageName(), this)); v -> ChangeDeviceInfoUtil.resetChangedDeviceInfo(getPackageName(), this));
@ -274,9 +253,10 @@ public class MainActivity extends AppCompatActivity {
if (!isNetworkAvailable(this)) { if (!isNetworkAvailable(this)) {
return; return;
} }
AutoJsUtil.registerScriptResultReceiver(this);
initializeExecutorService(); StartJobService.Companion.onEvent(this);
executorService.submit(() -> processMainTask(androidId, taskId)); // initializeExecutorService();
// executorService.submit(() -> processMainTask(androidId, taskId));
} }
private void processMainTask(String androidId, String taskId) { private void processMainTask(String androidId, String taskId) {
@ -284,91 +264,91 @@ public class MainActivity extends AppCompatActivity {
ShellUtils.execRootCmdAndGetResult("pm grant com.example.studyapp android.permission.INTERACT_ACROSS_USERS"); ShellUtils.execRootCmdAndGetResult("pm grant com.example.studyapp android.permission.INTERACT_ACROSS_USERS");
ShellUtils.execRootCmdAndGetResult("pm grant com.example.studyapp android.permission.WRITE_SECURE_SETTINGS"); ShellUtils.execRootCmdAndGetResult("pm grant com.example.studyapp android.permission.WRITE_SECURE_SETTINGS");
ShellUtils.execRootCmdAndGetResult("pm setenforce 0"); ShellUtils.execRootCmdAndGetResult("pm setenforce 0");
initializeDeviceAndRunScript(); // initializeDeviceAndRunScript();
processScriptResults(androidId, taskId); // processScriptResults(androidId, taskId);
} catch (Exception e) { } catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Unexpected task error", e); LogFileUtil.logAndWrite(Log.ERROR, TAG, "Unexpected task error", e);
} }
} }
private void initializeDeviceAndRunScript() { // private void initializeDeviceAndRunScript() {
ChangeDeviceInfoUtil.getAddDeviceInfo(currentCountry.toUpperCase(), DEVICE_TYPE, // ChangeDeviceInfoUtil.getAddDeviceInfo(currentCountry.toUpperCase(), DEVICE_TYPE,
(bigoDevice, afDevice) -> { // (bigoDevice, afDevice) -> {
startProxyVpn(this); // startProxyVpn(this);
UpdateUtil.INSTANCE.changeDevice(getPackageName(), bigoDevice, afDevice, new ChangeCallBack() { // UpdateUtil.INSTANCE.changeDevice(getPackageName(), bigoDevice, afDevice, new ChangeCallBack() {
@Override // @Override
public void changeSuccess() { // public void changeSuccess() {
AutoJsUtil.runAutojsScript(MainActivity.this); // AutoJsUtil.runAutojsScript(MainActivity.this);
} // }
//
@Override // @Override
public void changeFailed() { // public void changeFailed() {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Change device failed", null); // LogFileUtil.logAndWrite(Log.ERROR, TAG, "Change device failed", null);
} // }
}); // });
// ChangeDeviceInfoUtil.changeDeviceInfo(getPackageName(), this, //// ChangeDeviceInfoUtil.changeDeviceInfo(getPackageName(), this,
// bigoDevice, afDevice); //// bigoDevice, afDevice);
// AutoJsUtil.runAutojsScript(this); //// AutoJsUtil.runAutojsScript(this);
}); // });
AutoJsUtil.registerScriptResultReceiver(this); // AutoJsUtil.registerScriptResultReceiver(this);
} // }
private void processScriptResults(String androidId, String taskId) { // private void processScriptResults(String androidId, String taskId) {
while (isRunning) { // while (isRunning) {
try { // try {
String currentScriptResult = scriptResultQueue.take(); // String currentScriptResult = scriptResultQueue.take();
if (!isRunning) { // if (!isRunning) {
break; // break;
} // }
//
processScriptResult(androidId, taskId, currentScriptResult); // processScriptResult(androidId, taskId, currentScriptResult);
LogFileUtil.logAndWrite(Log.DEBUG, TAG, "Script result processed: " + currentScriptResult, null); // LogFileUtil.logAndWrite(Log.DEBUG, TAG, "Script result processed: " + currentScriptResult, null);
} catch (InterruptedException e) { // } catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Thread.currentThread().interrupt();
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Thread interrupted while waiting", e); // LogFileUtil.logAndWrite(Log.ERROR, TAG, "Thread interrupted while waiting", e);
break; // break;
} catch (Exception e) { // } catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Error processing script result", e); // LogFileUtil.logAndWrite(Log.ERROR, TAG, "Error processing script result", e);
} // }
} // }
} // }
//
private void processScriptResult(String androidId, String taskId, String result) { // private void processScriptResult(String androidId, String taskId, String result) {
//
ChangeDeviceInfoUtil.getAddDeviceInfo(currentCountry.toUpperCase(), DEVICE_TYPE, // ChangeDeviceInfoUtil.getAddDeviceInfo(currentCountry.toUpperCase(), DEVICE_TYPE,
(bigoDevice, afDevice) -> { // (bigoDevice, afDevice) -> {
try { // try {
updateDeviceAndExecuteTask(androidId, taskId, result, bigoDevice, afDevice); // updateDeviceAndExecuteTask(androidId, taskId, result, bigoDevice, afDevice);
} catch (Exception e) { // } catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Device info change error", e); // LogFileUtil.logAndWrite(Log.ERROR, TAG, "Device info change error", e);
} // }
}); // });
} // }
//
//
private void updateDeviceAndExecuteTask(String androidId, String taskId, // private void updateDeviceAndExecuteTask(String androidId, String taskId,
String result, JSONObject bigoDevice, JSONObject afDevice) { // String result, JSONObject bigoDevice, JSONObject afDevice) {
startProxyVpn(this); // startProxyVpn(this);
UpdateUtil.INSTANCE.changeDevice(result, bigoDevice, afDevice,new ChangeCallBack() { // UpdateUtil.INSTANCE.changeDevice(result, bigoDevice, afDevice,new ChangeCallBack() {
@Override // @Override
public void changeSuccess() { // public void changeSuccess() {
AutoJsUtil.runAutojsScript(MainActivity.this); // AutoJsUtil.runAutojsScript(MainActivity.this);
//
TaskUtil.execSaveTask(MainActivity.this, androidId, taskId, result, IpUtil.fetchGeoInfo()); // TaskUtil.execSaveTask(MainActivity.this, androidId, taskId, result, IpUtil.fetchGeoInfo());
try { // try {
infoUpload(MainActivity.this, androidId, result); // infoUpload(MainActivity.this, androidId, result);
} catch (IOException e) { // } catch (IOException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} // }
} // }
@Override // @Override
public void changeFailed() { // public void changeFailed() {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Change device failed", null); // LogFileUtil.logAndWrite(Log.ERROR, TAG, "Change device failed", null);
} // }
}); // });
} // }
public static final LinkedBlockingQueue<String> scriptResultQueue = new LinkedBlockingQueue<>(1); public static final LinkedBlockingQueue<String> scriptResultQueue = new LinkedBlockingQueue<>(1);
@ -384,7 +364,7 @@ public class MainActivity extends AppCompatActivity {
try { try {
ClashUtil.startProxy(context); ClashUtil.startProxy(context);
ClashUtil.switchProxyWithPort(switchCountry()); ClashUtil.switchProxyWithPort(CountryCode.switchCountry());
ClashUtil.switchProxyGroup("PROXY", "my-socks5-proxy", "http://127.0.0.1:6170"); ClashUtil.switchProxyGroup("PROXY", "my-socks5-proxy", "http://127.0.0.1:6170");
} catch (Exception e) { } catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "startProxyVpn: Failed to start VPN", e); LogFileUtil.logAndWrite(Log.ERROR, TAG, "startProxyVpn: Failed to start VPN", e);

View File

@ -16,6 +16,7 @@ import android.widget.Toast;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import com.example.studyapp.MainActivity; import com.example.studyapp.MainActivity;
import com.example.studyapp.job.ScriptJobService;
import com.example.studyapp.utils.LogFileUtil; import com.example.studyapp.utils.LogFileUtil;
import com.example.studyapp.utils.ShellUtils; import com.example.studyapp.utils.ShellUtils;
import java.io.File; import java.io.File;
@ -71,11 +72,15 @@ public class AutoJsUtil {
LogFileUtil.logAndWrite(android.util.Log.DEBUG, "MainActivity", "----脚本运行结束通知一次------; 当前线程:" + Thread.currentThread().getName(), null); LogFileUtil.logAndWrite(android.util.Log.DEBUG, "MainActivity", "----脚本运行结束通知一次------; 当前线程:" + Thread.currentThread().getName(), null);
String scriptResult = intent.getStringExtra(SCRIPT_RESULT_KEY); String scriptResult = intent.getStringExtra(SCRIPT_RESULT_KEY);
try { try {
MainActivity.scriptResultQueue.put(scriptResult); // 将结果加入队列 if (scriptResult == null){
scriptResult = "";
}
ScriptJobService.Companion.onEvent(context, scriptResult);
// MainActivity.scriptResultQueue.put(scriptResult); // 将结果加入队列
LogFileUtil.logAndWrite(android.util.Log.DEBUG, "MainActivity", "----收到result------;" + scriptResult, null); LogFileUtil.logAndWrite(android.util.Log.DEBUG, "MainActivity", "----收到result------;" + scriptResult, null);
// AutoJsUtil.flag = true; // 唤醒 // AutoJsUtil.flag = true; // 唤醒
// taskLock.notifyAll(); // taskLock.notifyAll();
} catch (InterruptedException e) { } catch (Exception e) {
Thread.currentThread().interrupt(); // 处理中断 Thread.currentThread().interrupt(); // 处理中断
} }
} }

View File

@ -64,10 +64,9 @@ public class ChangeDeviceInfoUtil {
JSONObject bigoDeviceObject = new JSONObject(bigoJson).optJSONObject("device"); JSONObject bigoDeviceObject = new JSONObject(bigoJson).optJSONObject("device");
JSONObject afDeviceObject = new JSONObject(afJson).optJSONObject("device"); JSONObject afDeviceObject = new JSONObject(afJson).optJSONObject("device");
callback.onLoadDeviceInfo(bigoDeviceObject, afDeviceObject); callback.onLoadDeviceInfo(bigoDeviceObject, afDeviceObject);
} catch (IOException | JSONException e) {
LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Error occurred during initialization", e);
} catch (Exception e) { } catch (Exception e) {
LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Error occurred during initialization", e); LogFileUtil.logAndWrite(android.util.Log.ERROR, LOG_TAG, "Error occurred during initialization", e);
callback.onLoadDeviceError("Error occurred during initialization");
} }
}); });
} }

View File

@ -4,4 +4,5 @@ import org.json.JSONObject;
public interface LoadDeviceCallback{ public interface LoadDeviceCallback{
void onLoadDeviceInfo(JSONObject bigoDevice, JSONObject afDevice); void onLoadDeviceInfo(JSONObject bigoDevice, JSONObject afDevice);
void onLoadDeviceError(String error);
} }

View File

@ -0,0 +1,104 @@
package com.example.studyapp.job
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.core.app.JobIntentService
import com.example.studyapp.autoJS.AutoJsUtil
import com.example.studyapp.device.ChangeDeviceInfoUtil
import com.example.studyapp.device.LoadDeviceCallback
import com.example.studyapp.proxy.ClashUtil
import com.example.studyapp.task.TaskUtil
import com.example.studyapp.update.ChangeCallBack
import com.example.studyapp.update.UpdateUtil.changeDevice
import com.example.studyapp.utils.CountryCode
import com.example.studyapp.utils.IpUtil
import com.example.studyapp.utils.LogFileUtil
import org.json.JSONObject
import java.util.Locale
import java.util.UUID
class ScriptJobService : JobIntentService() {
override fun onHandleWork(intent: Intent) {
execute(callback = object : JobCallback {
override fun onJobFailed() {
Handler(Looper.getMainLooper()).postDelayed({
StartJobService.onEvent(applicationContext)
}, 1000 * 60 * 5)
}
})
}
fun execute(callback: JobCallback) {
val taskId = UUID.randomUUID().toString()
runCatching {
ChangeDeviceInfoUtil.getAddDeviceInfo(
CountryCode.currentCountry.uppercase(Locale.getDefault()), CountryCode.DEVICE_TYPE,
object :LoadDeviceCallback {
override fun onLoadDeviceInfo(
bigoDevice: JSONObject?,
afDevice: JSONObject?
) {
ClashUtil.startProxy(applicationContext)
ClashUtil.switchProxyWithPort(CountryCode.switchCountry())
ClashUtil.switchProxyGroup("PROXY", "my-socks5-proxy", "http://127.0.0.1:6170")
changeDevice(packageName, bigoDevice, afDevice, object : ChangeCallBack {
override fun changeSuccess() {
runCatching {
AutoJsUtil.runAutojsScript(applicationContext)
TaskUtil.execSaveTask(
applicationContext,
androidId,
taskId,
name,
IpUtil.fetchGeoInfo()
)
TaskUtil.infoUpload(applicationContext, androidId, name)
}.onFailure {
callback.onJobFailed()
}
}
override fun changeFailed() {
LogFileUtil.logAndWrite(
Log.ERROR,
TAG,
"Change device failed",
null
)
callback.onJobFailed()
}
})
}
override fun onLoadDeviceError(error: String?) {
callback.onJobFailed()
}
})
}.onFailure {
callback.onJobFailed()
}
}
companion object {
private const val TAG = "ScriptJobService"
private const val jobId = 102
private const val androidId = "FyZqWrStUvOpKlMn"
private var name = ""
fun onEvent(context: Context, packageName: String) {
name = packageName
enqueueWork(
context,
ScriptJobService::class.java, jobId, Intent(
context,
ScriptJobService::class.java
)
)
}
}
}

View File

@ -0,0 +1,109 @@
package com.example.studyapp.job
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.util.Log
import androidx.core.app.JobIntentService
import com.example.studyapp.autoJS.AutoJsUtil
import com.example.studyapp.device.ChangeDeviceInfoUtil
import com.example.studyapp.device.LoadDeviceCallback
import com.example.studyapp.proxy.ClashUtil
import com.example.studyapp.update.ChangeCallBack
import com.example.studyapp.update.UpdateUtil.changeDevice
import com.example.studyapp.utils.CountryCode
import com.example.studyapp.utils.LogFileUtil
import com.example.studyapp.utils.ShellUtils
import org.json.JSONObject
import java.util.Locale
/**
* 监听任务
*/
interface JobCallback {
fun onJobFailed()
}
class StartJobService : JobIntentService() {
override fun onHandleWork(intent: Intent) {
if (running) {
return
}
setRunning(true)
exec(
callback = object : JobCallback {
override fun onJobFailed() {
Handler(Looper.getMainLooper()).postDelayed({
onEvent(this@StartJobService)
}, 1000 * 5)
}
}
)
}
protected fun exec(callback: JobCallback) {
try {
ShellUtils.execRootCmdAndGetResult("pm grant com.example.studyapp android.permission.INTERACT_ACROSS_USERS")
ShellUtils.execRootCmdAndGetResult("pm grant com.example.studyapp android.permission.WRITE_SECURE_SETTINGS")
ShellUtils.execRootCmdAndGetResult("pm setenforce 0")
ChangeDeviceInfoUtil.getAddDeviceInfo(
CountryCode.currentCountry.uppercase(Locale.getDefault()), CountryCode.DEVICE_TYPE,
object :LoadDeviceCallback{
override fun onLoadDeviceInfo(
bigoDevice: JSONObject?,
afDevice: JSONObject?
) {
ClashUtil.startProxy(applicationContext)
ClashUtil.switchProxyWithPort(CountryCode.switchCountry())
ClashUtil.switchProxyGroup("PROXY", "my-socks5-proxy", "http://127.0.0.1:6170")
changeDevice(packageName, bigoDevice, afDevice, object : ChangeCallBack {
override fun changeSuccess() {
AutoJsUtil.runAutojsScript(applicationContext)
setRunning(false)
}
override fun changeFailed() {
LogFileUtil.logAndWrite(
Log.ERROR,
TAG,
"Change device failed",
null
)
callback.onJobFailed()
setRunning(false)
}
})
}
override fun onLoadDeviceError(error: String?) {
callback.onJobFailed()
setRunning(false)
}
})
} catch (e: Exception) {
e.printStackTrace()
}
}
companion object {
private const val TAG = "StartJobService"
private const val jobId = 101
private var running = false
fun onEvent(context: Context) {
enqueueWork(
context,
StartJobService::class.java, jobId, Intent(
context,
StartJobService::class.java
)
)
}
fun setRunning(runningV: Boolean) {
running = runningV
}
}
}

View File

@ -0,0 +1,24 @@
package com.example.studyapp.utils;
import android.util.Log;
import com.example.studyapp.MainActivity;
public class CountryCode {
public static final int DEVICE_TYPE = 2;
static final String US = "US";
static final String RU = "RU";
// 默认使用美国
static final String DEFAULT = US;
// 当前使用的国家代码
public static String currentCountry = DEFAULT;
public static String switchCountry() {
currentCountry = currentCountry.equals(US) ?
RU : US;
LogFileUtil.logAndWrite(Log.INFO, "TAG",
"Switched country to: " + currentCountry, null);
return currentCountry;
}
}