Android 배경 시 뮬 레이 션 클릭 탐색(소스 코드 첨부)
한 번 의 탐색 을 통 해 모두 두 가지 다른 방안 을 정리 했다.Accessibility Service 와 adb shell 명령 은 독자 가 스스로 적당 한 장면 을 선택 할 수 있다.
AccessibilityService
무장 애 모드 는 제 가 먼저 생각 한 방안 입 니 다.안 드 로 이 드 무장 애 모드 를 모 르 는 경우 자체 바 이 두 를 사용 할 수 있 습 니 다.여기 서 간단하게 설명 하 자 면 Accessibility Service 는 Android 가 장애인 에 게 제공 하 는 친근 한 기능 이다.예 를 들 어 현재 페이지 에 어떤 버튼 이 있 는 지 알려 줄 수 있다.공식 적 으로 제공 하 는 열 API 를 사용 하면 우 리 는 자동 으로 실행 되 는'블랙 테 크 놀 로 지'작업 도 완성 할 수 있 습 니 다.예 를 들 어 몇 년 전의 보너스 플러그 인,위 챗 자동 답장 플러그 인,자동 좋아요 플러그 인 등 입 니 다.
이 방안 의 원 리 는 비교적 간단 하 다.현재 페이지 의 View 트 리 를 스 캔 하고 목표 컨트롤 을 찾 아 클릭 조작 을 모 의 한 다음 에 상세 하 게 논술 한다.
프로필 추가
우선 res 디 렉 터 리 에 프로필 을 만들어 야 합 니 다:access bleservice_config.xml,이름 마음대로 지 으 세 요.
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service
xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagReportViewIds"
android:canRetrieveWindowContent="true"
android:notificationTimeout="100"
android:description="@string/description"
android:packageNames=" "/>
accessibilityEventTypes:응답 이벤트 의 종 류 를 설정 합 니 다.typeAllMask 를 설정 하면 모든 종류의 이벤트 에 응답 합 니 다.accessibility Feedback Type:사용자 에 게 피드백 하 는 방식 을 설정 하고 음성 방송 과 진동 이 있 으 며 여 기 는 일반적인 유형 을 사용 합 니 다.
notificationTimeout:응답 시간 을 설정 합 니 다.
packageNames:대상 패키지 이름,예 를 들 어 보너스 플러그 인 은 위 챗 패키지 이름 을 설정 해 야 합 니 다.패키지 이름 을 어떻게 가 져 오 는 지 에 대해 다음 글 에서 언급 할 것 입 니 다.
AccessibilityService 인 코딩 계승
이어서 우 리 는 AccessibilityService 의 새로운 AutoClickAccessibilityService 를 계승 하여 onAccessibilityEvent(AccessibilityEvent event)를 다시 씁 니 다.
public class AutoClickAccessibilityService extends AccessibilityService {
private static final String TAG = "GK";
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
ztLog("===start===");
try {
//
AccessibilityNodeInfo rootInfo = getRootInActiveWindow();
if (rootInfo == null) {
return;
// , ,
if (rootInfo.getChildCount() != 0) {
……
}
} catch (Exception e) {
ztLog("Exception:" + e.getMessage(), true);
}
}
뿌리 노드 를 얻 은 후에 우 리 는 두 가지 방식 으로 목표 노드 를 찾기 시작 했다.findAccessibility NodeInfosByViewId 를 사용 하여 목 표를 찾 습 니 다.
우 리 는 find Accessibility NodeInfos ByViewId()를 사용 할 수 있 습 니 다.id 를 통 해 목표 노드 를 찾 을 수 있 습 니 다.View id 에 대해 서 는 DDMS 의 Dump View Hierarchy for UI Automator 를 사용 할 수 있 습 니 다.바로 아래 그림 단 추 를 누 르 는 것 입 니 다.
잠시 만 기 다 려 주세요.화면 스냅 샷 을 만 들 고 View 트 리 를 분석 하면 오른쪽 아래 속성 상자 에서 id 를 찾 을 수 있 습 니 다.그리고 자세히 보면 가방 이름 도 얻 을 수 있 습 니 다~
목표 apk 혼동 이 심해 서 id 를 읽 지 못 할 수도 있 습 니 다.예 를 들 어?그럼 두 번 째 방법 을 시도 해 보 세 요.
findAccessibility NodeInfosByText 를 사용 하여 목 표를 찾 습 니 다.
find Accessibility NodeInfosByText('가장 뜨 거 운 뮤 직 비디오')를 사용 하 는 것 은 말 그대로 문안 에 따라 컨트롤 을 찾 는 것 이다.
컨트롤 을 찾 으 면 클릭 동작 을 수행 할 수 있 습 니 다.하지만 잠시 만 요.여기 구덩이 가 있 습 니 다.
여기 view 트 리 를 잘 봐 서:
우리 가 id 든 문안 이 든 찾 은 것 은 TextView 나 Button 일 수 있 습 니 다.그러나 우리 의 일상적인 경험 에 따 르 면 우 리 는 아버지의 레이아웃 에 설정 한 클릭 이벤트,즉 이곳 의 LinearLayout 또는 FrameLayout 입 니 다.
그래서 제 방안 은 View 트 리 의 구조 에 따라 자체 적 으로 옮 겨 다 니 는 것 입 니 다.예 를 들 어 이곳 의 View 트 리 구 조 는 다음 과 같다.
나 는 먼저 깊이 를 해서 GridView 를 찾 은 다음 에 칼럼 이라는 TextView 를 찾 을 때 까지 모든 아이들 을 옮 겨 다 녔 다.왜 나 는 DFS 에서 칼럼 을 찾 지 않 았 을 까?나 는 그의 아버지 노드,심지어 할아버지 노드 를 기록 해 야 하기 때문에 다음 에 클릭 조작 을 편리 하 게 할 수 있다.
만약 에 이런 방안 을 사용 하 는 학생 이 있다 면 실제 View 트 리 의 구조 에 따라 스스로 찾 아 보 는 것 을 권장 합 니 다.제 코드 는 다음 과 같 습 니 다.
/**
*
*/
private void DFS(AccessibilityNodeInfo rootInfo) {
if (rootInfo == null || TextUtils.isEmpty(rootInfo.getClassName())) {
return;
}
if (!"android.widget.GridView".equals(rootInfo.getClassName())) {
ztLog(rootInfo.getClassName().toString());
for (int i = 0; i < rootInfo.getChildCount(); i++) {
DFS(rootInfo.getChild(i));
}
} else {
ztLog("==find gridView==");
final AccessibilityNodeInfo GridViewInfo = rootInfo;
for (int i = 0; i < GridViewInfo.getChildCount(); i++) {
final AccessibilityNodeInfo frameLayoutInfo = GridViewInfo.getChild(i);
// , View ,
// FrameLayout LinearLayout, TextView,
// , ……
final AccessibilityNodeInfo childInfo = frameLayoutInfo.getChild(0);
String text = childInfo.getText().toString();
if (text.equals(" ")) {
performClick(frameLayoutInfo);
} else {
ztLog(text);
}
}
}
}
private void performClick(AccessibilityNodeInfo targetInfo) {
targetInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
}
AndroidManifest 파일 에 서비스 설정 추가Accessibility Service 도 Servcie 이기 때문에 AndroidManifest 에 설정 해 야 합 니 다.
<service
android:name=".AutoClickService"
android:exported="false"
<!-- label , -->
android:label=" Demo"
<!-- android:permission service !! -->
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" >
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<!-- -->
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessible_service_config" />
</service>
이로써 무장 애 모드 방안 은 끝 났 습 니 다.실행 한 후에 핸드폰 설정 에 있 는 무장 애 에서 해당 하 는 스위치 를 켜 야 합 니 다.열 면 자동 클릭 기능 이 자동 으로 배경 에서 실 행 됩 니 다.사용 하고 싶 지 않 을 때 위의 그림 스위치 에서 닫 으 면 됩 니 다.
이후 앱 을 먼저 실행 하고 스위치 를 켜 고 기능 을 켜 야 한다.
무장 애 모드 는 사용 하기에 매우 편 하지만 많은 업 체 의 시스템 에서 이미 열 린 무장 애 모드 는 일정 시간 간격 으로 자동 으로 꺼 집 니 다.예 를 들 어 MIUI 시스템 에서 App 에 켜 져 실행 할 수 있 는 권한 을 부여 해 야 합 니 다.
한편,제조 업 체 가 가지 고 있 는 무장 애 는 괜 찮 습 니 다.시스템 에 처리 가 내장 되 어 있 을 것 이 라 고 추측 합 니 다.이것 도 무장 애 모델 의 구덩이 입 니 다.
작은 매듭
마지막 으로 요약 하면 Accessibility Service 는 매우 재 미 있 는 기능 으로 상상력 을 발휘 하면 많은 일 을 할 수 있 지만 구 덩이 를 밟 지 않도록 조심해 야 한다.
adb 는 우리 가 직접 효율 적 인 조작 기 를 편리 하 게 할 수 있 습 니 다.예 를 들 어 apk 를 설치 하고 apk 를 대량으로 설치 하 며 파일 을 복사 하 는 등 아 날로 그 클릭 사건 도 adb 명령 을 통 해 완성 할 수 있 습 니 다.
나 는 얼마 전에 인터넷 에 떠 도 는'위 챗 점프'의 보조 가 python+adb 로 완성 되 었 다 는 것 을 갑자기 생각 했다.
원 리 는 adb 가 캡 처 를 담당 하고 python 은 이미지 인식 픽 셀 로 거 리 를 계산 하 며 마지막 으로 adb 가 모 의 클릭 하 는 것 이다.
만약 우리 가 클릭 해 야 할 목표,좌표 가 상대 적 으로 확정 된다 면,우 리 는 코드 에서 adb 명령 을 실행 하여 아 날로 그 클릭 을 하면 된다.
실험
우 리 는 먼저 USB 로 실제 컴퓨터 를 연결 합 니 다.cmd 명령 행 도구 에서:
adb shell
shell@PRO6:/ $ input tap 125 521
shell@PRO6:/ $
화면 에 있 는(x,y)=(125,521)곳 을 클릭 한 다 는 뜻 이다.역시 휴대 전화 가 호응 했다.단점 은 응답 시간 이 약간 길 어 1 초 정도 된 것 같다 는 것 이다.다른 손짓 으로 도 완성 할 수 있 습 니 다.여 기 는 상세 하 게 설명 하지 않 고 관심 있 는 것 은 스스로 검색 할 수 있 습 니 다.
다음 에 우리 가 해 야 할 일 은 코드 에서 상술 한 조작 을 완성 하고 배경 에서 계속 실행 할 수 있 는 것 이다.이곳 은 나 도 무수 한 구 덩이 를 밟 았 으 니,내 가 천천히 말 하 는 것 을 들 어 라.
배경 에서 adb 명령 을 실행 할 방안 을 찾 습 니 다.
ProcessBuilder ― OUT
할 말 이 없 으 니 코드 를 직접 보 세 요.
int x = 0, y = 0;
String[] order = { "input", "tap", " ", x + "", y + "" };
try {
new ProcessBuilder(order).start();
} catch (IOException e) {
Log.i("GK", e.getMessage());
e.printStackTrace();
}
이런 버 전 은 Activity 에서 가능 하지만 배경 을 자 르 면 안 됩 니 다..........................................................Instrumentation ― OUT
try {
Instrumentation inst = new Instrumentation();
inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, x, y, 0));
inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0));
Log.i("GK", " " + x + ", " + y);
} catch (Exception e) {
Log.e("Exception when sendPointerSync", e.toString());
}
이런 판본 은 이전 판본 과 똑 같 아서 백 스테이지 가 안 돼,혹평!!구세주 런 타임 등장
private OutputStream os;
/**
* ADB : input tap 125 340
*/
private final void exec(String cmd) {
try {
if (os == null) {
os = Runtime.getRuntime().exec("su").getOutputStream();
}
os.write(cmd.getBytes());
os.flush();
} catch (Exception e) {
e.printStackTrace();
Log.e("GK", e.getMessage());
}
}
백 스테이지 문제 가 쉽게 풀리다!적절 한 타 이 밍 추가
현재 우리 가 핵심 기능 을 다 했 으 니 마지막 으로 해 야 할 일 은 적당 한 시 기 를 찾 아 조작 을 하 는 것 이다.
우선,우리 의 용 기 는 Service 일 것 입 니 다.그리고 배경 에서 현재 app 이 목표 app 인지 아 닌 지 를 계속 판단 합 니 다.만약 그렇다면 자동 클릭 작업 을 수행 합 니 다.
그래서 현재 프론트 데스크 톱 app 의 가방 이름 이나 Activity 의 이름 이 우리 의 목표 인지 판단 해 야 합 니 다.
/**
* APP apk
*/
private boolean isCurrentAppIsTarget() {
String name = getForegroundAppPackageName();
if (!TextUtils.isEmpty(name) && PACKAGE_NAME.equalsIgnoreCase(name)) {
return true;
}
return false;
}
/**
*
*/
public String getForegroundAppPackageName() {
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> lr = am.getRunningAppProcesses();
if (lr == null) {
return null;
}
for (RunningAppProcessInfo ra : lr) {
if (ra.importance == RunningAppProcessInfo.IMPORTANCE_VISIBLE || ra.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
Log.i("GK", ra.processName);
return ra.processName;
}
}
return "";
}
이상 은 adb 셸 방안 입 니 다.이런 방안 의 결함 도 비교적 뚜렷 합 니 다.즉,자동 클릭 을 요구 하 는 위 치 는 바 꿀 수 없습니다.클릭 위치의 좌 표를 가 져 오 는 방법 에 대해 개발 자 옵션 의 포인터 위 치 를 열 수 있 습 니 다.
좌 표를 직접 보다.
총결산
이런 요 구 를 모 의 클릭 하면 우 리 는 일반적으로 사용 하지 않 고 잘못된 뜻 도 있다.그러나 어떤 수요 든 중간의 탐색 과정 이 가장 소중 하 다.기술 도 사람 이다.매번 말 만 하면 하 겠 다 는 결심 과 용기 가 있 는 것 이 아니 라 호기심 을 가지 고 매번 탐색 하 는 기 회 를 소 중 히 여 기 며 배 운 것 도 있 고 얻 은 것 도 있 으 며 자신 을 인정 하 는 것 도 아니다.
마지막 으로 소스 코드 를 동봉 합 니 다AutoClickService
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.