I have a bug which keeps appearing on my Samsung S6 and Nexus 7. I’ve not been able to find a solution online, so I’m documenting my investigation here in case it is useful to others.

The Samsung has the following display specs

640 DPI xxxhdpi
2560 x 1440

Yet, no matter which method I use to get the dimensions in my code in onCreate I get the following :-

getRealMetrics    : width : 1080 : height : 1920
getDefaultDisplay : width : 1080 : height : 1920 : dpi : 480
DisplayMetrics    : width : 1080 : height : 1920 : densityDpi : 480
getDisplayMetrics : width : 1080 : height : 1920 : densityDpi : 480 :

Obviously this is a showstopper. It started in the past month or so and is inconsistent, sometimes it works, sometimes not.

The device has API level 22. (Android 5.1.1) I have a target SDK of 22 and min of 15.

Rebooting device generally gives the correct data on the FIRST run. This is not always the case, however. Occasionally the log :-

I/ActivityThread: Switching default density from 640 to 480
I/ActivityThread: Switching default density from 480 to 320

but usually the first run gives…

metrics.heightPixels : 2560
metrics.widthPixels : 1440
getDefaultDisplay : width : 1440 : height : 2560 : dpi : 640
android.os.Build.VERSION.SDK_INT : 22
getRealMetrics : width : 1440 : height : 2560
getDefaultDisplay : width : 1440 : height : 2560 : dpi : 640
DisplayMetrics width : 1440 : height : 2560 : densityDpi : 640
getDisplayMetrics : width : 1440 : height : 2560 : densityDpi : 640 :

The second run of the app gives the incorrect result.

If I get to the bottom of what might be causing this I will post an update.

Interestingly I have a much older app that does not appear to display this behaviour. It has the same display handling code. In the new app anything after the first run causes the problem.

    1. The app has been reduced to dump out the screen dimensions only in onCreate().
    2. Changing the minSdk levels in order to affect screen compatibility mode has no effect.
    3. Changing anyDensity from the ¬†default of true to false gives (as one might expect)…
    4. <supports-screens android:anyDensity="false" />

      ..on first run

      D/ywam:screenhelper: -------------------------------------------
      D/ywam:screenhelper: obtainMetricsViaResources : width : 360
      D/ywam:screenhelper: obtainMetricsViaResources : height : 360
      D/ywam:screenhelper: -------------------------------------------
      D/ywam:screenhelper: obtainMetricsViaResources : width : 360
      D/ywam:screenhelper: obtainMetricsViaResources : height : 640
      D/ywam:screenhelper: -------------------------------------------
      D/ywam:screenhelper: obtainMetricsViaRealMetrics : width : 1440
      D/ywam:screenhelper: obtainMetricsViaRealMetrics : height : 2560
      D/ywam:screenhelper: -------------------------------------------
      E/ywam:screenhelper: NoSuchMethodException
      D/ywam:screenhelper: obtainMetricsViaReflection : width : 0
      D/ywam:screenhelper: obtainMetricsViaReflection : height : 0

      … on second run

      D/ywam:screenhelper: -------------------------------------------
      D/ywam:screenhelper: obtainMetricsViaResources : width : 270
      D/ywam:screenhelper: obtainMetricsViaResources : height : 270
      D/ywam:screenhelper: -------------------------------------------
      D/ywam:screenhelper: obtainMetricsViaResources : width : 270
      D/ywam:screenhelper: obtainMetricsViaResources : height : 480
      D/ywam:screenhelper: -------------------------------------------
      D/ywam:screenhelper: obtainMetricsViaRealMetrics : width : 1080
      D/ywam:screenhelper: obtainMetricsViaRealMetrics : height : 1920
      D/ywam:screenhelper: -------------------------------------------
      E/ywam:screenhelper: NoSuchMethodException
      D/ywam:screenhelper: obtainMetricsViaReflection : width : 0
      D/ywam:screenhelper: obtainMetricsViaReflection : height : 0
    5. With anyDensity left out of the manifest (the documentation indicates that this will default to true, three runs of the app give :-
      obtainMetricsViaRealSize : width : 1080
      obtainMetricsViaRealSize : height : 1920
      obtainMetricsViaMetrics : width : 1080
      obtainMetricsViaMetrics : height : 1920
      obtainMetricsViaMetrics : localDensityDpi : 480
      obtainMetricsViaMetrics : localDensity : 3.0
      obtainMetricsViaMetrics : xdpi : 435.42822
      obtainMetricsViaMetrics : ydpi : 435.42822
      obtainMetricsViaMetrics : orientation : 1
      orientationString : ORIENTATION_PORTRAIT
      obtainMetricsViaRealSize : width : 720
      obtainMetricsViaRealSize : height : 1280
      obtainMetricsViaMetrics : width : 720
      obtainMetricsViaMetrics : height : 1280
      obtainMetricsViaMetrics : localDensityDpi : 320
      obtainMetricsViaMetrics : localDensity : 2.0
      obtainMetricsViaMetrics : xdpi : 290.2855
      obtainMetricsViaMetrics : ydpi : 290.2855
      obtainMetricsViaMetrics : orientation : 1
      obtainMetricsViaMetrics : orientationString : ORIENTATION_PORTRAIT
      obtainMetricsViaRealSize : width : 1080
      obtainMetricsViaRealSize : height : 1920
      obtainMetricsViaMetrics : width : 1080
      obtainMetricsViaMetrics : height : 1920
      obtainMetricsViaMetrics : localDensityDpi : 480
      obtainMetricsViaMetrics : localDensity : 3.0
      obtainMetricsViaMetrics : xdpi : 435.42822
      obtainMetricsViaMetrics : ydpi : 435.42822
      obtainMetricsViaMetrics : orientation : 1
      obtainMetricsViaMetrics : orientationString : ORIENTATION_PORTRAIT

Explicitly stating anyDensity=true in the manifest gives (with the same 3 runs):-

 obtainMetricsViaRealSize : width : 1440
 obtainMetricsViaRealSize : height : 2560
 obtainMetricsViaMetrics : width : 1440
 obtainMetricsViaMetrics : height : 2560
 obtainMetricsViaMetrics : localDensityDpi : 640
 obtainMetricsViaMetrics : localDensity : 4.0
 obtainMetricsViaMetrics : xdpi : 580.571
 obtainMetricsViaMetrics : ydpi : 580.571
 obtainMetricsViaMetrics : orientation : 1
 obtainMetricsViaMetrics : orientationString : ORIENTATION_PORTRAIT
 obtainMetricsViaRealSize : width : 1080
 obtainMetricsViaRealSize : height : 1920
 obtainMetricsViaMetrics : width : 1080
 obtainMetricsViaMetrics : height : 1920
 obtainMetricsViaMetrics : localDensityDpi : 480
 obtainMetricsViaMetrics : localDensity : 3.0
 obtainMetricsViaMetrics : xdpi : 435.42822
 obtainMetricsViaMetrics : ydpi : 435.42822
 obtainMetricsViaMetrics : orientation : 1
 obtainMetricsViaMetrics : orientationString : ORIENTATION_PORTRAIT
 obtainMetricsViaRealSize : width : 1080
 obtainMetricsViaRealSize : height : 1920
 obtainMetricsViaMetrics : width : 1080
 obtainMetricsViaMetrics : height : 1920
 obtainMetricsViaMetrics : localDensityDpi : 480
 obtainMetricsViaMetrics : localDensity : 3.0
 obtainMetricsViaMetrics : xdpi : 435.42822
 obtainMetricsViaMetrics : ydpi : 435.42822
 obtainMetricsViaMetrics : orientation : 1
 obtainMetricsViaMetrics : orientationString : ORIENTATION_PORTRAIT

The first run is correct. So (for now) I intend to explicitly state the anyDensity value and I’ll try persisting the first run in preferences and see if that gets me through this. I have no idea yet, why the app should behave this way.

This might be a Samsung specific thing to do with some sort of optimisation that’s going on :-

http://stackoverflow.com/questions/32620373/galaxy-note-5-density-reduced-automatically

I/ActivityThread: Switching default density from 640 to 480
I/ActivityThread: Switching default density from 480 to 320

You can take a look at our work on Google Play

Related Posts

Android

Spoon – A Spooning newbie’s journey

The Problem I hope SPOON will help solve Despite extensive testing with one of my apps, “Your word against mine” on Google Play, I’m seeing some app crashes reported on the console that I cannot Read more…

Debugging Technique

Execute on hardware often – Never trust the emulator

There are behavioural differences between the hardware and the emulator so never run for too many builds without executing on real hardware. You may get severely caught out with bugs that go unseen and then Read more…