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);
 }
}

뿌리 노드 를 얻 은 후에 우 리 는 두 가지 방식 으로 목표 노드 를 찾기 시작 했다.
  • View id:findAccessibility NodeInfosByViewId 에 따라
  • 컨트롤 문안 에 따 르 면 find Accessibility NodeInfosByText
  • 여기 서 우 리 는 매력 적 인 핸드폰 이 가지 고 있 는 음악 App 을 예 로 들 어 다음 그림 의 칼럼 을 자동 으로 클릭 해 야 한다 면:

    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 는 매우 재 미 있 는 기능 으로 상상력 을 발휘 하면 많은 일 을 할 수 있 지만 구 덩이 를 밟 지 않도록 조심해 야 한다.
  • find Accessibility NodeInfos ByViewId 또는 find Accessibility NodeInfos ByText 를 통 해 찾 은 대상 컨트롤 이 꼭 원 하 는 클릭 컨트롤 이 아 닙 니 다
  • 4.567917.각 업 체 시스템 은 무장 애 모델 에 대해 차단 처 리 를 내 장 했 을 수 있 습 니 다adb 셸 명령
    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
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기