version:2.2.1

bugfixes:优化自动拨号和权限问题
update:
This commit is contained in:
2025-07-28 09:42:34 +08:00
parent 6d44cb8b7a
commit a992e40182
3 changed files with 115 additions and 47 deletions

View File

@@ -18,8 +18,8 @@ android {
minSdkVersion 24
targetSdkVersion 29
versionCode 220
versionName "2.2.0"
versionCode 221
versionName "2.2.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -12,7 +12,6 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -31,9 +30,17 @@ import com.vscool.os.utils.ForegroundAppUtil;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.functions.Consumer;
/**
* 通过微信标签最高支持8.0.498.0.50 获取不到数据
* 8.0.54 可以获取
* 通过 {@link AccessibilityService#getWindows}和修改accessibility-service 配置能遍历屏幕元素
*/
public class SelectToSpeakService extends AccessibilityService {
@@ -63,7 +70,7 @@ public class SelectToSpeakService extends AccessibilityService {
public static final int TYPE_VOICE = 0;
public static final int TYPE_VIDEO = 1;
private static final int WAIT_TIME = 1200;
private static final int WAIT_TIME = 1300;
private int mCallType = TYPE_VOICE;
@@ -72,17 +79,12 @@ public class SelectToSpeakService extends AccessibilityService {
private String mName = "";//微信昵称
private String mTagName = "";//微信联系人标签名
private boolean mAutoAccept = false;
private boolean finished = true;
private Handler handler = null;
private AccessibilityEvent input = null;
private Runnable runnable = new Runnable() {
@Override
public void run() {
_onAccessibilityEvent(input);
finished = true;
}
};
public interface AccessibilityEventCallback {
void onAccessibilityEventCallback(AccessibilityEvent accessibilityEvent);
}
private AccessibilityEventCallback mAccessibilityEventCallback;
@Override
public void onCreate() {
@@ -90,10 +92,27 @@ public class SelectToSpeakService extends AccessibilityService {
Log.e(TAG, "onCreate: ");
registerSettingReceiver();
mAutoAccept = mMMKV.decodeBool(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, false);
handler = new Handler();
analysisAccessibilityEvent();
}
private void analysisAccessibilityEvent() {
Observable.create(new ObservableOnSubscribe<AccessibilityEvent>() {
@Override
public void subscribe(@NonNull ObservableEmitter<AccessibilityEvent> emitter) throws Throwable {
mAccessibilityEventCallback = emitter::onNext;
}
}).throttleLast(WAIT_TIME, TimeUnit.MILLISECONDS)
.subscribe(new Consumer<AccessibilityEvent>() {
@Override
public void accept(AccessibilityEvent accessibilityEvent) throws Throwable {
Log.e(TAG, "analysisAccessibilityEvent accept: ");
_onAccessibilityEvent(accessibilityEvent);
}
});
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand: ");
@@ -127,14 +146,7 @@ public class SelectToSpeakService extends AccessibilityService {
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.v(TAG, "onAccessibilityEvent: event = " + event.toString());
checkClassName(event);
if (finished) {
finished = false;
} else {
Log.v(TAG, "bounce");
handler.removeCallbacks(runnable);
}
input = event;
handler.postDelayed(runnable, WAIT_TIME);
mAccessibilityEventCallback.onAccessibilityEventCallback(event);
}
private void checkClassName(AccessibilityEvent event) {
@@ -421,8 +433,7 @@ public class SelectToSpeakService extends AccessibilityService {
clickNode(nodeInfo);
mCurrentStep = nextStep;
} else {
Toaster.show("没有找到控件");
mCurrentStep = Step.WAITING;
Toaster.show("没有找到搜索按钮");
}
}

View File

@@ -85,7 +85,12 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
@Override
public void onToggle(boolean on) {
if (on) {
showFloatingWindow();
boolean permission = checkFloatPermission(SettingActivity.this);
if (permission) {
showFloatingWindow();
} else {
showFloatWindowDialog();
}
} else {
hideFloatingWindow();
}
@@ -221,28 +226,40 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
@Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume: ");
setStatus();
mViewModel.getSystemSettings();
}
private void setStatus() {
boolean showFloatWindow = Settings.Global.getInt(getContentResolver(), CommonConfig.HOVER_HOME, CommonConfig.HOVER_HOME_STATUS) == 1;
Log.e(TAG, "initView: showFloatWindow = " + showFloatWindow);
Log.e(TAG, "setStatus: showFloatWindow = " + showFloatWindow);
mViewDataBinding.tbFloat.setToggleStatu(showFloatWindow);
if (showFloatWindow) {
boolean permission = checkFloatPermission(SettingActivity.this);
if (permission) {
showFloatingWindow();
} else {
showFloatWindowDialog();
}
} else {
hideFloatingWindow();
}
boolean voiceBroadcast = mMMKV.decodeBool(CommonConfig.VOICE_BROADCAST, false);
Log.e(TAG, "initView: voiceBroadcast = " + voiceBroadcast);
Log.e(TAG, "setStatus: voiceBroadcast = " + voiceBroadcast);
mViewDataBinding.tbSms.setToggleStatu(voiceBroadcast);
boolean autoAccept = mMMKV.decodeBool(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, false);
Log.e(TAG, "initView: autoAccept = " + autoAccept);
Log.e(TAG, "setStatus: autoAccept = " + autoAccept);
mViewDataBinding.tbAutoAnswer.setToggleStatu(autoAccept);
if (autoAccept) {
boolean floatWindowEnable = Settings.Global.getInt(getContentResolver(), CommonConfig.HOVER_HOME, CommonConfig.HOVER_HOME_STATUS) == 1;
boolean permission = FloatingWindowUtils.checkFloatPermission(SettingActivity.this);
if (floatWindowEnable && permission) {
boolean accessibility = AccessibilityUtils.isAccessibilitySettingsOn(SettingActivity.this);
if (floatWindowEnable && permission && !accessibility) {
Toast.makeText(SettingActivity.this, "由于系统限制,请先关闭悬浮窗功能,开启自动接听后再打开悬浮窗", Toast.LENGTH_LONG).show();
showFloatWindowDialog();
showFloatHideDialog();
} else {
if (AccessibilityUtils.isAccessibilitySettingsOn(SettingActivity.this)) {
mMMKV.encode(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, 1);
@@ -256,32 +273,32 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
}
boolean wxAutoVideo = mMMKV.decodeInt(CommonConfig.WECHAT_AUTO_CALL_KEY, 0) == 1;
Log.e(TAG, "initView: wxAutoVideo = " + autoAccept);
Log.e(TAG, "setStatus: wxAutoVideo = " + autoAccept);
mViewDataBinding.tbAutoCall.setToggleStatu(wxAutoVideo);
boolean dialTone = mMMKV.decodeBool(CommonConfig.DISABLE_DIAL_TONE_MODIFY, true);
Log.e(TAG, "initView: dialTone = " + dialTone);
Log.e(TAG, "setStatus: dialTone = " + dialTone);
mViewDataBinding.tbDialer.setToggleStatu(dialTone);
int code = Settings.System.getInt(getContentResolver(), CommonConfig.ACTION_STATUS_BAR_STATE, 0);
boolean statusBar = code == 1;
Log.e(TAG, "initView: statusBar = " + statusBar);
Log.e(TAG, "setStatus: statusBar = " + statusBar);
mViewDataBinding.tbStatu.setToggleStatu(statusBar);
boolean hourlyTime = mMMKV.decodeBool(CommonConfig.HOURLY_TIME_SIGNAL_KEY, false);
Log.e(TAG, "initView: hourlyTime = " + hourlyTime);
Log.e(TAG, "setStatus: hourlyTime = " + hourlyTime);
mViewDataBinding.tbHourly.setToggleStatu(hourlyTime);
boolean disableKey = mMMKV.decodeBool(CommonConfig.DISABLE_VOLUME_KEY, false);
Log.e(TAG, "initView: disableKey = " + disableKey);
Log.e(TAG, "setStatus: disableKey = " + disableKey);
mViewDataBinding.tbVolume.setToggleStatu(!disableKey);
boolean contactModify = mMMKV.decodeBool(CommonConfig.DISABLE_CONTACT_MODIFY, false);
Log.e(TAG, "initView: contactModify = " + contactModify);
Log.e(TAG, "setStatus: contactModify = " + contactModify);
mViewDataBinding.tbContact.setToggleStatu(!contactModify);
int clockModify = mMMKV.decodeInt(CommonConfig.ALARM_CLOCK_CTRL, 1);
Log.e(TAG, "initView: clockModify = " + clockModify);
Log.e(TAG, "setStatus: clockModify = " + clockModify);
mViewDataBinding.tbClock.setToggleStatu(clockModify == 1);
}
@@ -390,9 +407,10 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
public void onPositive() {
boolean floatWindowEnable = Settings.Global.getInt(getContentResolver(), CommonConfig.HOVER_HOME, CommonConfig.HOVER_HOME_STATUS) == 1;
boolean permission = FloatingWindowUtils.checkFloatPermission(SettingActivity.this);
if (floatWindowEnable && permission) {
boolean accessibility = AccessibilityUtils.isAccessibilitySettingsOn(SettingActivity.this);
if (floatWindowEnable && permission && !accessibility) {
Toast.makeText(SettingActivity.this, "由于系统限制,请先关闭悬浮窗功能,开启自动接听后再打开悬浮窗", Toast.LENGTH_LONG).show();
showFloatWindowDialog();
showFloatHideDialog();
} else {
showAutoAcceptDialog();
}
@@ -433,7 +451,6 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
// }
}
private PermissionsDialog mFloatWindowDialog;
private void setWechatAutoCall(boolean on) {
if (on) {
@@ -462,6 +479,37 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
}
}
private PermissionsDialog mFloatWindowHideDialog;
private void showFloatHideDialog() {
if (mFloatWindowHideDialog != null) {
mFloatWindowHideDialog.dismiss();
mFloatWindowHideDialog = null;
}
mFloatWindowHideDialog = new PermissionsDialog(SettingActivity.this);
mFloatWindowHideDialog.setTitle("功能说明");
mFloatWindowHideDialog.setContent("由于系统限制,请先关闭悬浮窗功能,开启自动接听后再打开悬浮窗");
mFloatWindowHideDialog.setDeniedtext("取消");
mFloatWindowHideDialog.setGrantedtext("确定");
mFloatWindowHideDialog.setPermissionsCallback(new PermissionsDialog.PermissionsCallback() {
@Override
public void onGranted() {
mFloatWindowHideDialog.dismiss();
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
@Override
public void onDenied() {
mFloatWindowHideDialog.dismiss();
mViewDataBinding.tbAutoAnswer.setToggleStatu(false);
}
});
mFloatWindowHideDialog.show();
}
private PermissionsDialog mFloatWindowDialog;
private void showFloatWindowDialog() {
if (mFloatWindowDialog != null) {
mFloatWindowDialog.dismiss();
@@ -469,21 +517,29 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
}
mFloatWindowDialog = new PermissionsDialog(SettingActivity.this);
mFloatWindowDialog.setTitle("功能说明");
mFloatWindowDialog.setContent("由于系统限制,请先关闭悬浮窗功能,开启自动接听后再打开悬浮窗");
mFloatWindowDialog.setContent("您已开启悬浮窗功能,程序需要授予悬浮窗权限才能使用此功能,是否同意授权");
mFloatWindowDialog.setDeniedtext("取消");
mFloatWindowDialog.setGrantedtext("确定");
mFloatWindowDialog.setPermissionsCallback(new PermissionsDialog.PermissionsCallback() {
@Override
public void onGranted() {
mFloatWindowDialog.dismiss();
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName()));
startActivity(intent);
// 在Activity或Fragment中请求权限
if (!Settings.canDrawOverlays(SettingActivity.this)) {
Toast.makeText(SettingActivity.this, "请先打开悬浮窗权限", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE_DRAW_OVER_OTHER_APPS_PERMISSION);
} else {
showFloatingWindow();
mFloatWindowDialog.dismiss();
}
}
@Override
public void onDenied() {
mFloatWindowDialog.dismiss();
mViewDataBinding.tbAutoAnswer.setToggleStatu(false);
mViewDataBinding.tbFloat.setToggleStatu(false);
Settings.Global.putInt(getContentResolver(), CommonConfig.HOVER_HOME, 0);
}
});
mFloatWindowDialog.show();
@@ -510,10 +566,11 @@ public class SettingActivity extends BaseMvvmActivity<SettingViewModel, Activity
public void onGranted() {
mAutoAcceptDialog.dismiss();
if (AccessibilityUtils.isAccessibilitySettingsOn(SettingActivity.this)) {
mMMKV.encode(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, 1);
Intent intent = new Intent(SelectToSpeakService.SETTING_AUTOMATIC_ANSWER_ACTION);
intent.putExtra("auto_answer", true);
sendBroadcast(intent);
mMMKV.encode(CommonConfig.WECHAT_CALL_AUTO_ACCEPT, 1);
mViewDataBinding.tbAutoAnswer.setToggleStatu(true);
} else {
AccessibilityUtils.openAccessibilitySettings(SettingActivity.this);
}