改机失败重新执行任务

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:resource="@xml/accessibility_service_config" />
</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>
<queries>

View File

@ -36,11 +36,13 @@ import androidx.work.WorkManager;
import com.example.studyapp.autoJS.AutoJsUtil;
import com.example.studyapp.device.ChangeDeviceInfoUtil;
import com.example.studyapp.job.StartJobService;
import com.example.studyapp.proxy.ClashUtil;
import com.example.studyapp.service.MyAccessibilityService;
import com.example.studyapp.task.TaskUtil;
import com.example.studyapp.update.ChangeCallBack;
import com.example.studyapp.update.UpdateUtil;
import com.example.studyapp.utils.CountryCode;
import com.example.studyapp.utils.IpUtil;
import com.example.studyapp.utils.LogFileUtil;
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 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
private void initializeExecutorService() {
@ -189,16 +178,6 @@ public class MainActivity extends AppCompatActivity {
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() {
LogFileUtil.logAndWrite(Log.INFO, TAG, "onCreate: Setting up UI components", null);
String androidId = getAndroidId(this);
@ -209,7 +188,7 @@ public class MainActivity extends AppCompatActivity {
}));
setupButton(R.id.disconnectVpnButton, v -> ClashUtil.stopProxy(this));
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,
v -> ChangeDeviceInfoUtil.resetChangedDeviceInfo(getPackageName(), this));
@ -274,9 +253,10 @@ public class MainActivity extends AppCompatActivity {
if (!isNetworkAvailable(this)) {
return;
}
initializeExecutorService();
executorService.submit(() -> processMainTask(androidId, taskId));
AutoJsUtil.registerScriptResultReceiver(this);
StartJobService.Companion.onEvent(this);
// initializeExecutorService();
// executorService.submit(() -> processMainTask(androidId, 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.WRITE_SECURE_SETTINGS");
ShellUtils.execRootCmdAndGetResult("pm setenforce 0");
initializeDeviceAndRunScript();
processScriptResults(androidId, taskId);
// initializeDeviceAndRunScript();
// processScriptResults(androidId, taskId);
} catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Unexpected task error", e);
}
}
private void initializeDeviceAndRunScript() {
ChangeDeviceInfoUtil.getAddDeviceInfo(currentCountry.toUpperCase(), DEVICE_TYPE,
(bigoDevice, afDevice) -> {
startProxyVpn(this);
UpdateUtil.INSTANCE.changeDevice(getPackageName(), bigoDevice, afDevice, new ChangeCallBack() {
@Override
public void changeSuccess() {
AutoJsUtil.runAutojsScript(MainActivity.this);
}
@Override
public void changeFailed() {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Change device failed", null);
}
});
// ChangeDeviceInfoUtil.changeDeviceInfo(getPackageName(), this,
// bigoDevice, afDevice);
// AutoJsUtil.runAutojsScript(this);
});
AutoJsUtil.registerScriptResultReceiver(this);
}
// private void initializeDeviceAndRunScript() {
// ChangeDeviceInfoUtil.getAddDeviceInfo(currentCountry.toUpperCase(), DEVICE_TYPE,
// (bigoDevice, afDevice) -> {
// startProxyVpn(this);
// UpdateUtil.INSTANCE.changeDevice(getPackageName(), bigoDevice, afDevice, new ChangeCallBack() {
// @Override
// public void changeSuccess() {
// AutoJsUtil.runAutojsScript(MainActivity.this);
// }
//
// @Override
// public void changeFailed() {
// LogFileUtil.logAndWrite(Log.ERROR, TAG, "Change device failed", null);
// }
// });
//// ChangeDeviceInfoUtil.changeDeviceInfo(getPackageName(), this,
//// bigoDevice, afDevice);
//// AutoJsUtil.runAutojsScript(this);
// });
// AutoJsUtil.registerScriptResultReceiver(this);
// }
private void processScriptResults(String androidId, String taskId) {
while (isRunning) {
try {
String currentScriptResult = scriptResultQueue.take();
if (!isRunning) {
break;
}
processScriptResult(androidId, taskId, currentScriptResult);
LogFileUtil.logAndWrite(Log.DEBUG, TAG, "Script result processed: " + currentScriptResult, null);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Thread interrupted while waiting", e);
break;
} catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Error processing script result", e);
}
}
}
private void processScriptResult(String androidId, String taskId, String result) {
ChangeDeviceInfoUtil.getAddDeviceInfo(currentCountry.toUpperCase(), DEVICE_TYPE,
(bigoDevice, afDevice) -> {
try {
updateDeviceAndExecuteTask(androidId, taskId, result, bigoDevice, afDevice);
} catch (Exception e) {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Device info change error", e);
}
});
}
private void updateDeviceAndExecuteTask(String androidId, String taskId,
String result, JSONObject bigoDevice, JSONObject afDevice) {
startProxyVpn(this);
UpdateUtil.INSTANCE.changeDevice(result, bigoDevice, afDevice,new ChangeCallBack() {
@Override
public void changeSuccess() {
AutoJsUtil.runAutojsScript(MainActivity.this);
TaskUtil.execSaveTask(MainActivity.this, androidId, taskId, result, IpUtil.fetchGeoInfo());
try {
infoUpload(MainActivity.this, androidId, result);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void changeFailed() {
LogFileUtil.logAndWrite(Log.ERROR, TAG, "Change device failed", null);
}
});
}
// private void processScriptResults(String androidId, String taskId) {
// while (isRunning) {
// try {
// String currentScriptResult = scriptResultQueue.take();
// if (!isRunning) {
// break;
// }
//
// processScriptResult(androidId, taskId, currentScriptResult);
// LogFileUtil.logAndWrite(Log.DEBUG, TAG, "Script result processed: " + currentScriptResult, null);
// } catch (InterruptedException e) {
// Thread.currentThread().interrupt();
// LogFileUtil.logAndWrite(Log.ERROR, TAG, "Thread interrupted while waiting", e);
// break;
// } catch (Exception e) {
// LogFileUtil.logAndWrite(Log.ERROR, TAG, "Error processing script result", e);
// }
// }
// }
//
// private void processScriptResult(String androidId, String taskId, String result) {
//
// ChangeDeviceInfoUtil.getAddDeviceInfo(currentCountry.toUpperCase(), DEVICE_TYPE,
// (bigoDevice, afDevice) -> {
// try {
// updateDeviceAndExecuteTask(androidId, taskId, result, bigoDevice, afDevice);
// } catch (Exception e) {
// LogFileUtil.logAndWrite(Log.ERROR, TAG, "Device info change error", e);
// }
// });
// }
//
//
// private void updateDeviceAndExecuteTask(String androidId, String taskId,
// String result, JSONObject bigoDevice, JSONObject afDevice) {
// startProxyVpn(this);
// UpdateUtil.INSTANCE.changeDevice(result, bigoDevice, afDevice,new ChangeCallBack() {
// @Override
// public void changeSuccess() {
// AutoJsUtil.runAutojsScript(MainActivity.this);
//
// TaskUtil.execSaveTask(MainActivity.this, androidId, taskId, result, IpUtil.fetchGeoInfo());
// try {
// infoUpload(MainActivity.this, androidId, result);
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
// }
// @Override
// public void changeFailed() {
// LogFileUtil.logAndWrite(Log.ERROR, TAG, "Change device failed", null);
// }
// });
// }
public static final LinkedBlockingQueue<String> scriptResultQueue = new LinkedBlockingQueue<>(1);
@ -384,7 +364,7 @@ public class MainActivity extends AppCompatActivity {
try {
ClashUtil.startProxy(context);
ClashUtil.switchProxyWithPort(switchCountry());
ClashUtil.switchProxyWithPort(CountryCode.switchCountry());
ClashUtil.switchProxyGroup("PROXY", "my-socks5-proxy", "http://127.0.0.1:6170");
} catch (Exception 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 com.example.studyapp.MainActivity;
import com.example.studyapp.job.ScriptJobService;
import com.example.studyapp.utils.LogFileUtil;
import com.example.studyapp.utils.ShellUtils;
import java.io.File;
@ -71,11 +72,15 @@ public class AutoJsUtil {
LogFileUtil.logAndWrite(android.util.Log.DEBUG, "MainActivity", "----脚本运行结束通知一次------; 当前线程:" + Thread.currentThread().getName(), null);
String scriptResult = intent.getStringExtra(SCRIPT_RESULT_KEY);
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);
// AutoJsUtil.flag = true; // 唤醒
// taskLock.notifyAll();
} catch (InterruptedException e) {
} catch (Exception e) {
Thread.currentThread().interrupt(); // 处理中断
}
}

View File

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