Before Unity 5.1 Screen.dpi value was calculated as the average of xdpi and ydpi. However on some devices these values are not correct, because they have to be set by device manufacturer and they are not used by Android OS, so they are not guaranteed to be correct. Instead Android OS uses densityDpi value for UI scaling. In Unity 5.3 we’ve changed Screen.dpi implementation to return the average of xdpi and ydpi only when the value is not too far from densityDPI, otherwise we were returning densityDPI. This was an attempt to return better dpi value on devices where xdpi and ydpi are totally wrong. However this turned out to be quite inconsistent because more devices than expected have xdpi (and ydpi) different than densityDpi.
We are going to make Screen.dpi to always return densityDpi value. This may change how your existing games look. If you’ll encounter this issue, or if you need a more precise dpi value, you can use the following C# script to get dpi value in an old way. Just keep in mind that on some devices xdpi and ydpi values are totally wrong.
float GetDPI()
{
AndroidJavaClass activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject activity = activityClass.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaObject metrics = new AndroidJavaObject("android.util.DisplayMetrics");
activity.Call<AndroidJavaObject>("getWindowManager").Call<AndroidJavaObject>("getDefaultDisplay").Call("getMetrics", metrics);
return (metrics.Get<float>("xdpi") + metrics.Get<float>("ydpi")) * 0.5f;
}