2

Background

I need to work around a bug that only affects devices running Samsung's One UI.

Question

How can I programmatically detect if a device is running One UI?

What I've tried

I've already tried the following:

  • Inspecting android.os.Build, but I didn't see anything that clearly identified One UI
  • Checking if Build.BRAND == "samsung" && Build.VERSION.SDK_INT >= 28, but this also detects custom ROMs running on Samsung devices, which don't run One UI

Example system info

For reference, here is a dump of android.os.Build on a Samsung Galaxy Tab S4 running Android 9:

Build.BOARD: msm8998
Build.BOOTLOADER: T835XXU4BSJ6
Build.BRAND: samsung
Build.CPU_ABI: arm64-v8a
Build.CPU_ABI2: 
Build.DEVICE: gts4llte
Build.DISPLAY: PPR1.180610.011.T835XXU4BSJ6
Build.FINGERPRINT: samsung/gts4lltexx/gts4llte:9/PPR1.180610.011/T835XXU4BSJ6:user/release-keys
Build.HARDWARE: qcom
Build.HOST: 21HH1G10
Build.ID: PPR1.180610.011
Build.IS_DEBUGGABLE: false
Build.IS_EMULATOR: false
Build.MANUFACTURER: samsung
Build.MODEL: SM-T835
Build.PERMISSIONS_REVIEW_REQUIRED: false
Build.PRODUCT: gts4lltexx
Build.RADIO: unknown
Build.SERIAL: unknown
Build.TAGS: release-keys
Build.TIME: 1572504702000
Build.TYPE: user
Build.UNKNOWN: unknown
Build.USER: dpi
Build.Version.BASE_OS: 
Build.Version.CODENAME: REL
Build.Version.FIRST_SDK_INT: 27
Build.Version.INCREMENTAL: T835XXU4BSJ6
Build.Version.PREVIEW_SDK_INT: 0
Build.Version.RELEASE: 9
Build.Version.RESOURCES_SDK_INT: 28
Build.Version.SDK: 28
Build.Version.SDK_INT: 28
Build.Version.SECURITY_INDEX: 1
Build.Version.SECURITY_PATCH: 2019-11-01
Build.Version.SEM_FIRST_SDK_INT: 27
Build.Version.SEM_INT: 2801
Build.Version.SEM_PLATFORM_INT: 100100

And here's a screenshot of the system info screen on the device: Samsung Galaxy Tab S4 Android 9 System Information

Sam
  • 40,644
  • 36
  • 176
  • 219
  • Did you try this: [Does Android have any way to detect cyanogenmod and its version?](https://stackoverflow.com/q/9800671/295004) – Morrison Chang Feb 07 '20 at 22:48

1 Answers1

4

Taken mostly from Samsung's SecSettings.apk, with some reflections:

public String getOneUiVersion() throws Exception {
    if (!isSemAvailable(getApplicationContext())) {
        return ""; // was "1.0" originally but probably just a dummy value for one UI devices
    }
    Field semPlatformIntField = Build.VERSION.class.getDeclaredField("SEM_PLATFORM_INT");
    int version = semPlatformIntField.getInt(null) - 90000;
    if (version < 0) {
        // not one ui (could be previous Samsung OS)
        return "";
    }
    return (version / 10000) + "." + ((version % 10000) / 100);
}

public boolean isSemAvailable(Context context) {
    return context != null &&
            (context.getPackageManager().hasSystemFeature("com.samsung.feature.samsung_experience_mobile") ||
                    context.getPackageManager().hasSystemFeature("com.samsung.feature.samsung_experience_mobile_lite"));
}

The first condition (isSemAvailable) is problematic with non-Samsung devices so it's probably better to drop it. I tried it with some 1.0 devices and it worked fine without it.

arbuz
  • 2,950
  • 1
  • 18
  • 16
  • Nice work! I ran into this code too, and the `isSemAvailable()` check made it look like early versions of One UI 1.0 were undetectable, so I gave up on doing this altogether. I reckon your code snippet is probably as good as it gets though. – Sam Apr 06 '20 at 22:57
  • Not 100% sure but I think the undetectable devices will still have the `SEM_PLATFORM_INT` field because it exists also in older Samsung ROMs. Maybe `isSemAvailable` is unnecessary and the availability of `Build.VERSION.SEM_PLATFORM_INT` can be used to identify Samsung original ROM and something like `Build.VERSION.SEM_PLATFORM_INT > 90000` to identify One UI. – arbuz Apr 07 '20 at 17:18