IT_Programming/Android_Java

[펌] 안드로이드 앱이 동작하는 폼 팩터(Form Factor) 확인 방법

JJun ™ 2019. 2. 8. 21:21



 * 출처

 : http://sjava.net/2019/01/안드로이드-앱이-동작하는-폼-팩터-확인-방법/




폼 팩터(Form Factor)의 정의를 위키피디아에서 살펴보면 아래와 같다.

컴퓨터 시스템의 각 부품의 물리적 치수의 형태를 의미한다.

즉, 소프트웨어가 동작하는 기기의 형태를 말하는 것이다. 
안드로이드 적용범위가 확대되면서, 안드로이드 앱이 실행할 수 있는 하드웨어 기기가 많아졌다.
예로, 크롬북이나 TV등을 예로 들 수 있다.

최근에 안드로이드 앱을 크롬북과 삼성 덱스(DEX)의 UI/UX에 어울리도록 작업을 하면서 특정 기능(키보드 등)은 모바일/태블릿에서만 필요하다. 그래서 앱이 동작하는 기기의 정보를 확인해야 했고, 아래의 코드로 해결을 했다.

아래 코드는 구글 TalkBack 깃헙 사이트의 https://github.com/google/talkback/blob/master/utils/src/main/java/FormFactorUtils.java 코드에 삼성 덱스(DEX)를 확인하는 코드를 추가했다.

아래의 ARC는 App Runtime for Chrome의 줄임말으로 폼 팩터가 크롬북이라는 것을 알 수 있다.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import android.app.UiModeManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Build;
 
public class FormFactorUtils {
    private static final int FORM_FACTOR_PHONE_OR_TABLET = 0;
    private static final int FORM_FACTOR_WATCH = 1;
    private static final int FORM_FACTOR_TV = 2;
    private static final int FORM_FACTOR_ARC = 3;
 
    private static final int FORM_FACTOR_SAMSUNG_DEX = 100;
 
    private static final String ARC_DEVICE_PATTERN = ".+_cheets|cheets_.+";
 
    private static FormFactorUtils sInstance;
 
    private final int mFormFactor;
    private final boolean mHasAccessibilityShortcut;
 
    private FormFactorUtils(final Context context) {
        // Find device type.
        if (context.getApplicationContext()
                .getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_WATCH)) {
            mFormFactor = FORM_FACTOR_WATCH;
        } else if (isContextTelevision(context)) {
            mFormFactor = FORM_FACTOR_TV;
        } else if (Build.DEVICE != null && Build.DEVICE.matches(ARC_DEVICE_PATTERN)) {
            mFormFactor = FORM_FACTOR_ARC;
        } else if(isContextDex(context)) {
            mFormFactor = FORM_FACTOR_SAMSUNG_DEX;
        } else {
            mFormFactor = FORM_FACTOR_PHONE_OR_TABLET;
        }
 
        // Find whether device supports accessibility shortcut.
        mHasAccessibilityShortcut = (BuildVersionUtils.isAtLeastO() && mFormFactor == FORM_FACTOR_PHONE_OR_TABLET);
    }
 
    /** @return an instance of this Singleton. */
    public static synchronized FormFactorUtils getInstance(final Context context) {
        if (sInstance == null) {
            sInstance = new FormFactorUtils(context);
        }
        return sInstance;
    }
 
    /** Return the cached version of the isWatch. */
    public boolean isWatch() {
        return mFormFactor == FORM_FACTOR_WATCH;
    }
 
    public boolean isArc() {
        return mFormFactor == FORM_FACTOR_ARC;
    }
 
    public boolean isTv() {
        return mFormFactor == FORM_FACTOR_TV;
    }
 
    public boolean isPhoneOrTablet() {
        return mFormFactor == FORM_FACTOR_PHONE_OR_TABLET;
    }
 
    public boolean isDex() {
        return mFormFactor == FORM_FACTOR_SAMSUNG_DEX;
    }
 
    public boolean hasAccessibilityShortcut() {
        return mHasAccessibilityShortcut;
    }
 
    public static boolean useSpeakPasswordsServicePref() {
        return BuildVersionUtils.isAtLeastO();
    }
 
    public static boolean isContextTelevision(Context context) {
        if (context == null) {
            return false;
        }
 
        UiModeManager modeManager = (UiModeManager) context.getSystemService(Context.UI_MODE_SERVICE);
        return modeManager != null
                && modeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION;
    }
 
    private static boolean isContextDex(Context context) {
        if (context == null) {
            return false;
        }
 
        try {
            Configuration config = context.getResources().getConfiguration();
            Class configClass = config.getClass();
            if (configClass.getField("SEM_DESKTOP_MODE_ENABLED").getInt(configClass)
                    == configClass.getField("semDesktopModeEnabled").getInt(config)) {
                return true;
            }
        } catch (Exception e) {
            // ignore
        }
 
        return false;
    }
}