package com.zellyy.finance; import android.os.Build; import android.util.Log; import com.getcapacitor.JSObject; import com.getcapacitor.Plugin; import com.getcapacitor.PluginMethod; import com.getcapacitor.annotation.CapacitorPlugin; import com.getcapacitor.PluginCall; /** * 애플리케이션 빌드 정보를 제공하는 Capacitor 플러그인 */ @CapacitorPlugin(name = "BuildInfo") public class BuildInfoPlugin extends Plugin { private static final String TAG = "BuildInfoPlugin"; /** * 빌드 정보를 가져오는 메서드 * @param call 플러그인 호출 정보 */ @PluginMethod public void getBuildInfo(PluginCall call) { // 오류가 발생하더라도 앱이 강제종료되지 않도록 전체 try-catch 블록 사용 try { Log.d(TAG, "빌드 정보 요청 수신됨"); JSObject ret = new JSObject(); String versionName = ""; int versionCode = 0; int buildNumber = 0; // 모든 필드 접근에 각각 try-catch 적용하여 실패하더라도 기본값 사용 try { // Class.forName으로 BuildConfig 클래스 안전하게 접근 Class buildConfigClass = null; try { buildConfigClass = Class.forName("com.zellyy.finance.BuildConfig"); Log.d(TAG, "BuildConfig 클래스 로드 성공"); } catch (ClassNotFoundException e) { Log.e(TAG, "BuildConfig 클래스를 찾을 수 없음", e); } if (buildConfigClass != null) { // VERSION_NAME 필드 접근 try { Object versionNameObj = buildConfigClass.getField("VERSION_NAME").get(null); if (versionNameObj != null) { versionName = versionNameObj.toString(); Log.d(TAG, "VERSION_NAME 로드 성공: " + versionName); } } catch (Exception e) { Log.e(TAG, "VERSION_NAME 필드 접근 오류", e); } // VERSION_CODE 필드 접근 try { Object versionCodeObj = buildConfigClass.getField("VERSION_CODE").get(null); if (versionCodeObj != null) { versionCode = Integer.parseInt(versionCodeObj.toString()); Log.d(TAG, "VERSION_CODE 로드 성공: " + versionCode); } } catch (Exception e) { Log.e(TAG, "VERSION_CODE 필드 접근 오류", e); } // BUILD_NUMBER 필드 접근 try { Object buildNumberObj = buildConfigClass.getField("BUILD_NUMBER").get(null); if (buildNumberObj != null) { buildNumber = Integer.parseInt(buildNumberObj.toString()); Log.d(TAG, "BUILD_NUMBER 로드 성공: " + buildNumber); } } catch (Exception e) { Log.e(TAG, "BUILD_NUMBER 필드 접근 오류, 버전 코드로 대체", e); // 빌드 넘버 필드가 없으면 버전 코드와 동일하게 설정 buildNumber = versionCode; } } } catch (Exception e) { Log.e(TAG, "BuildConfig 접근 중 예기치 않은 오류", e); } // 버전 정보가 유효하지 않을 경우 version.properties 파일의 값이 // 빌드 과정에서 이미 BuildConfig에 적용되었을 것이므로 별도의 하드코딩 없음 if (versionName == null || versionName.isEmpty()) { Log.w(TAG, "버전명이 비어있음, BuildConfig에서 값을 가져오지 못함"); } if (versionCode <= 0) { Log.w(TAG, "버전 코드가 유효하지 않음, BuildConfig에서 값을 가져오지 못함"); } if (buildNumber <= 0) { Log.w(TAG, "빌드 번호가 유효하지 않음, BuildConfig에서 값을 가져오지 못함"); } // 디버깅을 위한 로그 출력 Log.d(TAG, "최종 버전명: " + versionName); Log.d(TAG, "최종 버전 코드: " + versionCode); Log.d(TAG, "최종 빌드 번호: " + buildNumber); String packageName = ""; try { packageName = getContext().getPackageName(); Log.d(TAG, "패키지명: " + packageName); } catch (Exception e) { Log.e(TAG, "패키지명 가져오기 오류", e); packageName = "com.zellyy.finance"; } // 결과 객체에 값 설정 ret.put("versionName", versionName); ret.put("versionCode", versionCode); ret.put("buildNumber", buildNumber); ret.put("packageName", packageName); ret.put("androidVersion", Build.VERSION.RELEASE); ret.put("androidSDK", Build.VERSION.SDK_INT); ret.put("platform", "android"); // 현재 날짜를 디버깅 정보로 추가 ret.put("timestamp", System.currentTimeMillis()); // 성공 응답 call.resolve(ret); } catch (Exception e) { // 오류 로깅 강화 Log.e(TAG, "빌드 정보 가져오기 오류", e); // 오류 발생 시에도 정보 반환하여 앱 중단 방지 // build.gradle에서 설정한 기본값이 BuildConfig에 이미 적용되었을 것이므로 // 별도의 하드코딩 없이 기본적인 정보만 포함 JSObject fallbackResult = new JSObject(); fallbackResult.put("platform", "android-fallback"); fallbackResult.put("error", e.getMessage()); fallbackResult.put("androidVersion", Build.VERSION.RELEASE); fallbackResult.put("androidSDK", Build.VERSION.SDK_INT); try { fallbackResult.put("packageName", getContext().getPackageName()); } catch (Exception ex) { fallbackResult.put("packageName", "com.zellyy.finance"); } // 응답 해결 call.resolve(fallbackResult); } } }