version:2.2.2
bugfixes:优化自动拨号和自动接听 update:
This commit is contained in:
@@ -19,14 +19,15 @@ import android.view.WindowManager;
|
|||||||
import android.view.accessibility.AccessibilityEvent;
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
import android.view.accessibility.AccessibilityNodeInfo;
|
import android.view.accessibility.AccessibilityNodeInfo;
|
||||||
import android.view.accessibility.AccessibilityWindowInfo;
|
import android.view.accessibility.AccessibilityWindowInfo;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.hjq.toast.Toaster;
|
import com.hjq.toast.Toaster;
|
||||||
import com.tencent.mmkv.MMKV;
|
import com.tencent.mmkv.MMKV;
|
||||||
import com.vscool.os.bean.Contact;
|
import com.vscool.os.bean.Contact;
|
||||||
import com.vscool.os.config.CommonConfig;
|
import com.vscool.os.config.CommonConfig;
|
||||||
import com.vscool.os.utils.ForegroundAppUtil;
|
import com.vscool.os.utils.ForegroundAppUtil;
|
||||||
|
import com.vscool.os.utils.ToastUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
@@ -70,7 +71,7 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
public static final int TYPE_VOICE = 0;
|
public static final int TYPE_VOICE = 0;
|
||||||
public static final int TYPE_VIDEO = 1;
|
public static final int TYPE_VIDEO = 1;
|
||||||
|
|
||||||
private static final int WAIT_TIME = 1300;
|
private static final int WAIT_TIME = 1600;
|
||||||
|
|
||||||
private int mCallType = TYPE_VOICE;
|
private int mCallType = TYPE_VOICE;
|
||||||
|
|
||||||
@@ -198,15 +199,8 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
case WAITING:
|
case WAITING:
|
||||||
mAutoAccept = mMMKV.decodeBool(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, false);
|
mAutoAccept = mMMKV.decodeBool(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, false);
|
||||||
Log.e(TAG, "_onAccessibilityEvent: mAutoAccept = " + mAutoAccept);
|
Log.e(TAG, "_onAccessibilityEvent: mAutoAccept = " + mAutoAccept);
|
||||||
if (!mAutoAccept) {
|
if (mAutoAccept) {
|
||||||
return;
|
autoAccept();
|
||||||
}
|
|
||||||
if (stepAnswer(Property.DESCRIPTION, RECEIVE_DESCRIPTION)) {
|
|
||||||
mCurrentStep = Step.WECHAT_HANDS_FREE;
|
|
||||||
Toast.makeText(this, "已自动接听视频/语音", Toast.LENGTH_LONG).show();
|
|
||||||
} else {
|
|
||||||
mCurrentStep = Step.WAITING;
|
|
||||||
// clickAnswer();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WECHAT_HANDS_FREE:
|
case WECHAT_HANDS_FREE:
|
||||||
@@ -245,6 +239,13 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
stepCall(Property.TEXT, PARENT_VIDEO_TEXT);
|
stepCall(Property.TEXT, PARENT_VIDEO_TEXT);
|
||||||
// clickVideoCall();
|
// clickVideoCall();
|
||||||
break;
|
break;
|
||||||
|
case CLICK_CALL://打视频或者电话
|
||||||
|
if (mCallType == TYPE_VIDEO) {
|
||||||
|
step(Property.TEXT, VIDEO_TEXT, Step.WAITING);
|
||||||
|
} else if (mCallType == TYPE_VOICE) {
|
||||||
|
step(Property.TEXT, CALL_TEXT, Step.WAITING);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case CLICK_CONTACT://进入通讯录界面
|
case CLICK_CONTACT://进入通讯录界面
|
||||||
if (stepHome(Property.TEXT, CONTACT_TEXT, Step.FIND_TAG)) {
|
if (stepHome(Property.TEXT, CONTACT_TEXT, Step.FIND_TAG)) {
|
||||||
@@ -271,17 +272,11 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
case CLICK_INFO://进入个人信息页面
|
case CLICK_INFO://进入个人信息页面
|
||||||
stepCallDialog(Property.TEXT, DIALER_TEXT, Step.CLICK_CALL);
|
stepCallDialog(Property.TEXT, DIALER_TEXT, Step.CLICK_CALL);
|
||||||
break;
|
break;
|
||||||
case CLICK_CALL://打视频或者电话
|
|
||||||
if (mCallType == TYPE_VIDEO) {
|
|
||||||
step(Property.TEXT, VIDEO_TEXT, Step.WAITING);
|
|
||||||
} else if (mCallType == TYPE_VOICE) {
|
|
||||||
step(Property.TEXT, CALL_TEXT, Step.WAITING);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
// case CLICK_VIDEO_CALL:
|
// case CLICK_VIDEO_CALL:
|
||||||
// if (step(Property.TEXT, VIDEO_TEXT)) {
|
// if (step(Property.TEXT, VIDEO_TEXT)) {
|
||||||
// Log.d(TAG, "finish, now: " + mCurrentStep);
|
// Log.d(TAG, "finish, now: " + mCurrentStep);
|
||||||
// Toast.makeText(this, "成功发起视频聊天", Toast.LENGTH_LONG).show();
|
// ToastUtils.show("成功发起视频聊天");
|
||||||
// }
|
// }
|
||||||
// break;
|
// break;
|
||||||
default:
|
default:
|
||||||
@@ -316,6 +311,95 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void autoAccept() {
|
||||||
|
if (stepAnswer(Property.DESCRIPTION, RECEIVE_DESCRIPTION)) {
|
||||||
|
mCurrentStep = Step.WECHAT_HANDS_FREE;
|
||||||
|
ToastUtils.show("已自动接听视频/语音");
|
||||||
|
} else if (clickNode("com.tencent.mm:id/kfp", false)) {
|
||||||
|
mCurrentStep = Step.WECHAT_HANDS_FREE;
|
||||||
|
ToastUtils.show("已自动接听视频/语音");
|
||||||
|
} else {
|
||||||
|
mCurrentStep = Step.WAITING;
|
||||||
|
// clickAnswer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param text 对应文本
|
||||||
|
* @param simulate 是否通过坐标模拟点击
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean clickNode(String text, boolean simulate) {
|
||||||
|
findFloatWindowNode(text);
|
||||||
|
List<AccessibilityNodeInfo> nodeInfos = findNodesByViewId(text);
|
||||||
|
Optional<AccessibilityNodeInfo> optional = nodeInfos.stream().findAny();
|
||||||
|
if (optional.isPresent()) {
|
||||||
|
AccessibilityNodeInfo node = optional.get();
|
||||||
|
if (node.isClickable()) {
|
||||||
|
boolean performAction = node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
|
||||||
|
Log.e(TAG, "clickNode: performAction = " + performAction);
|
||||||
|
node.recycle();
|
||||||
|
return performAction;
|
||||||
|
} else {
|
||||||
|
if (simulate) {
|
||||||
|
Point point = getPointtByNode(node);
|
||||||
|
Log.e(TAG, "clickNode: " + point);
|
||||||
|
clickByPoint(point.x, point.y);
|
||||||
|
Log.e(TAG, "clickNode: mCurrentStep " + mCurrentStep + " done");
|
||||||
|
} else {
|
||||||
|
clickNode(findClickableNode(node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "clickNode: not found");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private AccessibilityNodeInfo findClickableNode(AccessibilityNodeInfo node) {
|
||||||
|
if (node == null) {
|
||||||
|
Log.e(TAG, "findClickableNode: node is null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (node.isClickable()) {
|
||||||
|
return node;
|
||||||
|
} else {
|
||||||
|
return findClickableNode(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void findFloatWindowNode(String id) {
|
||||||
|
List<AccessibilityWindowInfo> windows = getWindows();
|
||||||
|
for (AccessibilityWindowInfo window : windows) {
|
||||||
|
// 筛选悬浮窗窗口
|
||||||
|
if (isFloatingWindow(window)) {
|
||||||
|
AccessibilityNodeInfo rootNode = window.getRoot();
|
||||||
|
// 处理悬浮窗节点
|
||||||
|
traverseNode(rootNode);
|
||||||
|
rootNode.recycle(); // 释放资源
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isFloatingWindow(AccessibilityWindowInfo window) {
|
||||||
|
Log.e(TAG, "isFloatingWindow: " + window.getType());
|
||||||
|
// 根据窗口类型或标题筛选
|
||||||
|
return window.getType() == AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void traverseNode(AccessibilityNodeInfo node) {
|
||||||
|
if (node == null) return;
|
||||||
|
// 提取节点信息(如文本、ID等)
|
||||||
|
String text = node.getText() != null ? node.getText().toString() : "";
|
||||||
|
String id = node.getViewIdResourceName();
|
||||||
|
// 递归遍历子节点
|
||||||
|
for (int i = 0; i < node.getChildCount(); i++) {
|
||||||
|
traverseNode(node.getChild(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
private void clickAnswer() {
|
private void clickAnswer() {
|
||||||
String className = ForegroundAppUtil.getForegroundActivityName(SelectToSpeakService.this);
|
String className = ForegroundAppUtil.getForegroundActivityName(SelectToSpeakService.this);
|
||||||
@@ -325,7 +409,7 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
boolean successful = clickByPoint(595, 1376);
|
boolean successful = clickByPoint(595, 1376);
|
||||||
Log.e(TAG, "clickAnswer: " + successful);
|
Log.e(TAG, "clickAnswer: " + successful);
|
||||||
if (successful) {
|
if (successful) {
|
||||||
Toast.makeText(this, "已自动接听视频/语音", Toast.LENGTH_LONG).show();
|
ToastUtils.show("已自动接听视频/语音");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.e(TAG, "clickAnswer: Not in the answering interface");
|
Log.e(TAG, "clickAnswer: Not in the answering interface");
|
||||||
@@ -433,13 +517,19 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
clickNode(nodeInfo);
|
clickNode(nodeInfo);
|
||||||
mCurrentStep = nextStep;
|
mCurrentStep = nextStep;
|
||||||
} else {
|
} else {
|
||||||
Toaster.show("没有找到搜索按钮");
|
// Toaster.show("没有找到搜索按钮");
|
||||||
|
step(Property.DESCRIPTION, SEARCH_TEXT, Step.CLICK_SEARCH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AccessibilityNodeInfo> findNodesByViewId(String id) {
|
private List<AccessibilityNodeInfo> findNodesByViewId(String id) {
|
||||||
List<AccessibilityNodeInfo> accessibilityNodeInfos = getRootInActiveWindow().findAccessibilityNodeInfosByViewId(id);
|
AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
|
||||||
return accessibilityNodeInfos;
|
if (nodeInfo != null) {
|
||||||
|
List<AccessibilityNodeInfo> accessibilityNodeInfos = nodeInfo.findAccessibilityNodeInfosByViewId(id);
|
||||||
|
return accessibilityNodeInfos;
|
||||||
|
} else {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private AccessibilityNodeInfo findNodeByText(AccessibilityNodeInfo root, String text) {
|
private AccessibilityNodeInfo findNodeByText(AccessibilityNodeInfo root, String text) {
|
||||||
@@ -478,7 +568,7 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
} else {
|
} else {
|
||||||
if (mFindCount == mMaxCount) {
|
if (mFindCount == mMaxCount) {
|
||||||
Log.e("stepCallDialog", "mCurrentStep: max");
|
Log.e("stepCallDialog", "mCurrentStep: max");
|
||||||
Toast.makeText(this, "没有找到联系人", Toast.LENGTH_LONG).show();
|
ToastUtils.show("没有找到联系人");
|
||||||
mCurrentStep = Step.WAITING;
|
mCurrentStep = Step.WAITING;
|
||||||
mFindCount = 0;
|
mFindCount = 0;
|
||||||
return false;
|
return false;
|
||||||
@@ -522,7 +612,7 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
} else {
|
} else {
|
||||||
if (mFindCount == mMaxCount) {
|
if (mFindCount == mMaxCount) {
|
||||||
Log.e("findContact", "mCurrentStep: max");
|
Log.e("findContact", "mCurrentStep: max");
|
||||||
Toast.makeText(this, "没有找到联系人", Toast.LENGTH_LONG).show();
|
ToastUtils.show("没有找到联系人");
|
||||||
mCurrentStep = Step.WAITING;
|
mCurrentStep = Step.WAITING;
|
||||||
mFindCount = 0;
|
mFindCount = 0;
|
||||||
return false;
|
return false;
|
||||||
@@ -583,6 +673,10 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
|
|
||||||
|
|
||||||
private void clickNode(AccessibilityNodeInfo node) {
|
private void clickNode(AccessibilityNodeInfo node) {
|
||||||
|
if (node == null) {
|
||||||
|
Log.e(TAG, "clickNode: node is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Log.e(TAG, "clickNode: getText = " + node.getText());
|
Log.e(TAG, "clickNode: getText = " + node.getText());
|
||||||
Log.e(TAG, "clickNode: isClickable = " + node.isClickable());
|
Log.e(TAG, "clickNode: isClickable = " + node.isClickable());
|
||||||
@@ -811,29 +905,30 @@ public class SelectToSpeakService extends AccessibilityService {
|
|||||||
WECHAT_HANDS_FREE,
|
WECHAT_HANDS_FREE,
|
||||||
//电话免提
|
//电话免提
|
||||||
DIALER_HANDS_FREE,
|
DIALER_HANDS_FREE,
|
||||||
//微信主页找用户名
|
|
||||||
|
//1-1微信主页找用户名
|
||||||
CLICK_HOME,
|
CLICK_HOME,
|
||||||
//进入搜索界面
|
//2-2进入搜索界面
|
||||||
CLICK_SEARCH,
|
CLICK_SEARCH,
|
||||||
//是否弹出了联系人列表
|
//2-3是否弹出了联系人列表
|
||||||
CLICK_SEARCH_CONTACT,
|
CLICK_SEARCH_CONTACT,
|
||||||
//聊天界面+号
|
//1-2 2-4聊天界面+号
|
||||||
CLICK_QUICK_WECHAT_CALL,
|
CLICK_QUICK_WECHAT_CALL,
|
||||||
//更多里面视频通话
|
//1-3 2-5更多里面视频通话
|
||||||
CLICK_TARGET,
|
CLICK_TARGET,
|
||||||
|
/*1-4 语音通话*/
|
||||||
|
CLICK_CALL,
|
||||||
|
|
||||||
|
|
||||||
//主页点击导航栏通讯录
|
//主页点击导航栏通讯录
|
||||||
CLICK_CONTACT,
|
CLICK_CONTACT,
|
||||||
|
|
||||||
FIND_CONTACT,
|
FIND_CONTACT,
|
||||||
//通讯录页面点击标签
|
//通讯录页面点击标签
|
||||||
FIND_TAG,
|
FIND_TAG,
|
||||||
//点击对应的标签名
|
//点击对应的标签名
|
||||||
CLICK_TAG,
|
CLICK_TAG,
|
||||||
|
|
||||||
CLICK_NAME,
|
CLICK_NAME,
|
||||||
CLICK_INFO,
|
CLICK_INFO,
|
||||||
|
|
||||||
CLICK_CALL,
|
|
||||||
CLICK_VIDEO_CALL;
|
CLICK_VIDEO_CALL;
|
||||||
|
|
||||||
private Step next() {
|
private Step next() {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package com.vscool.os.base;
|
package com.vscool.os.base;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -36,9 +38,20 @@ import com.vscool.os.utils.Utils;
|
|||||||
public class BaseApplication extends Application {
|
public class BaseApplication extends Application {
|
||||||
private static final String TAG = "BaseApplication";
|
private static final String TAG = "BaseApplication";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ViewModel中因为经常旋转导致弱引用为空
|
||||||
|
*/
|
||||||
|
@SuppressLint("StaticFieldLeak")
|
||||||
|
private static Context context;
|
||||||
|
|
||||||
|
public static Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
context = getApplicationContext();
|
||||||
if (!BuildConfig.DEBUG) {
|
if (!BuildConfig.DEBUG) {
|
||||||
catchException();
|
catchException();
|
||||||
}
|
}
|
||||||
|
|||||||
28
app/src/main/java/com/vscool/os/utils/ToastUtils.java
Normal file
28
app/src/main/java/com/vscool/os/utils/ToastUtils.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package com.vscool.os.utils;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.vscool.os.base.BaseApplication;
|
||||||
|
|
||||||
|
public class ToastUtils {
|
||||||
|
|
||||||
|
public static void show(String msg) {
|
||||||
|
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||||
|
new Thread(() -> {
|
||||||
|
mainHandler.post(() -> {
|
||||||
|
Toast.makeText(BaseApplication.getContext(), msg, Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showLong(String msg) {
|
||||||
|
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||||
|
new Thread(() -> {
|
||||||
|
mainHandler.post(() -> {
|
||||||
|
Toast.makeText(BaseApplication.getContext(), msg, Toast.LENGTH_LONG).show();
|
||||||
|
});
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
|
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:accessibilityEventTypes="typeAllMask|typeViewClicked|typeViewFocused|typeWindowStateChanged|typeWindowsChanged|typeContextClicked|typeWindowContentChanged"
|
android:accessibilityEventTypes="typeAllMask"
|
||||||
android:accessibilityFeedbackType="feedbackAllMask|feedbackGeneric|feedbackSpoken"
|
android:accessibilityFeedbackType="feedbackAllMask"
|
||||||
android:accessibilityFlags="flagDefault|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"
|
android:accessibilityFlags="flagDefault|flagReportViewIds|flagRetrieveInteractiveWindows|flagIncludeNotImportantViews"
|
||||||
android:canPerformGestures="true"
|
android:canPerformGestures="true"
|
||||||
android:canRetrieveWindowContent="true"
|
android:canRetrieveWindowContent="true"
|
||||||
android:description="@string/accessibility_service_description"
|
android:description="@string/accessibility_service_description"
|
||||||
|
|||||||
16
build.gradle
16
build.gradle
@@ -4,11 +4,13 @@ buildscript {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
// mavenCentral()
|
||||||
maven { url "https://jitpack.io" }
|
maven { url "https://jitpack.io" }
|
||||||
maven { url 'https://developer.huawei.com/repo/' }
|
maven { url 'https://developer.huawei.com/repo/' }
|
||||||
maven { url 'https://maven.aliyun.com/repository/public/' }
|
maven { url 'https://maven.aliyun.com/repository/central' }
|
||||||
maven { url 'https://maven.aliyun.com/repository/central/' }
|
maven { url "https://maven.aliyun.com/repository/jcenter" }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/public' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/google' }
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.6.4'
|
classpath 'com.android.tools.build:gradle:3.6.4'
|
||||||
@@ -26,11 +28,13 @@ allprojects {
|
|||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
// mavenCentral()
|
||||||
maven { url "https://jitpack.io" }
|
maven { url "https://jitpack.io" }
|
||||||
maven { url 'https://developer.huawei.com/repo/' }
|
maven { url 'https://developer.huawei.com/repo/' }
|
||||||
maven { url 'https://maven.aliyun.com/repository/public/' }
|
maven { url 'https://maven.aliyun.com/repository/central' }
|
||||||
maven { url 'https://maven.aliyun.com/repository/central/' }
|
maven { url "https://maven.aliyun.com/repository/jcenter" }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/public' }
|
||||||
|
maven { url 'https://maven.aliyun.com/repository/google' }
|
||||||
}
|
}
|
||||||
gradle.projectsEvaluated {
|
gradle.projectsEvaluated {
|
||||||
tasks.withType(JavaCompile) {
|
tasks.withType(JavaCompile) {
|
||||||
|
|||||||
Reference in New Issue
Block a user