ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 서비스 앱 삭제 및 강제종료 방지하기
    안드로이드 2020. 8. 24. 16:04

    일단 기본적으로 꽤 위험할 수 있는 내용이라고 생각한다. 그럼에도 불구하고 부득이하게 이런 기술을 사용해야 하는 경우도 있으므로 내가 구현한 방법에 대해 정리해보려고 한다.

     

    전체적인 루틴은 아래와 같다.

    디바이스 관리자 권한 받음 -> UsageStatsManager를 이용한 현재 최상단의 화면 정보 가져옴 -> 디바이스 관리자 권한 제거 액티비티가 올라왔을 때 화면 전환

     

    * 디바이스 관리자 권한을 얻으면? - 해당 디바이스를 제어할 수 있는 권한을 얻음 - 디바이스 관리자 권한을 받으면 강제종료 버튼이 비활성화 됨

     

    * UsageStatsManager란? - 디바이스의 사용 기록 및 현재 상태에 대한 정보를 가지고 있는 Class - 이를 이용해 현재 최상단에 있는 액티비티의 클래스명을 가져올 수 있음

     

    디바이스 관리자 권한을 획득하는 코드는 아래와 같다.

    DevicePolicyManager mDPM;
    ComponentName mAdminName;
    
    mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);
    mAdminName = new ComponentName(this, AmayalockAdminReceiver.class);
    
    if (!mDPM.isAdminActive(mAdminName)) {
      Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
      intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName);
      intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "안전한 환경을 위해 실행 버튼을 클릭해주세요");
      startActivityForResult(intent, 0);
    }

     

    아래는 현재 최상단에 있는 클래스명을 구하는 메소드이다.

    public String getForegroundPackageNameClassNameByUsageStats() {
      String packageNameByUsageStats = "";
      String classByUsageStats = null;
      if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        @SuppressLint("WrongConstant") UsageStatsManager mUsageStatsManager = (UsageStatsManager)getSystemService("usagestats");
        final long INTERVAL = 1000;
        final long end = System.currentTimeMillis();
        final long begin = end - INTERVAL;
        final UsageEvents usageEvents = mUsageStatsManager.queryEvents(begin, end);
        
        while (usageEvents.hasNextEvent()) {
          UsageEvents.Event event = new UsageEvents.Event();
          usageEvents.getNextEvent(event);
          
          if (event.getEventType() == UsageEvents.Event.MOVE_TO_FOREGROUND) {
            packageNameByUsageStats = event.getPackageName();
            classByUsageStats = event.getClassName();
            Log.d("asdf", "packageNameByUsageStats is " + packageNameByUsageStats + ", classByUsageStats is " + classByUsageStats);
          }
        }
      }
      if(classByUsageStats!= null) {
        if (classByUsageStats.equals("com.android.settings.DeviceAdminAdd")) {
          return "exit";
        }
      }
      else{
        return "null";
      }
    }

    위 코드 23번째 줄에서 보이는 "com.android.settings.DeviceAdminAdd" 가 디바이스 관리자를 해제하는 화면의 클래스명이다.

     

    최초 디바이스 관리자 권한을 부여받고 난 뒤, 해당 앱을 삭제하기 위해선 반드시 디바이스 관리자를 해제한 후 삭제하게 되는데 이 디바이스 관리자 해제 창이 뜨는지 상시 체크한다면 해제 창이 떴을 때 다른 화면으로 전환하는 등의 조치를 통해 앱 삭제를 방지할 수 있다.

    댓글

Designed by Tistory.