Isai FL
「au 発表会 2014 Summer」で発表された isai FL という端末が発表されました。この端末は以下の資料のように640(XXX High DPI)のDensityを持つもので、国内では初めてのXXX High DPI の端末です。
その発売を記念して、該当するAndroid 4.4 のソースコードを調査してみたいと思います。
Android 公式ドキュメントでは、Metrics and Gridsで紹介されています。
4.4ソースコード調査
XXX High DPI が定義、利用されているソースコードは以下のもののようです。
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 | public class DisplayMetrics { /** * Standard quantized DPI for low-density screens. */ public static final int DENSITY_LOW = 120 ; /** * Standard quantized DPI for medium-density screens. */ public static final int DENSITY_MEDIUM = 160 ; /** * This is a secondary density, added for some common screen configurations. * It is recommended that applications not generally target this as a first * class density -- that is, don't supply specific graphics for this * density, instead allow the platform to scale from other densities * (typically {@link #DENSITY_HIGH}) as * appropriate. In most cases (such as using bitmaps in * {@link android.graphics.drawable.Drawable}) the platform * can perform this scaling at load time, so the only cost is some slight * startup runtime overhead. * * This density was original introduced to correspond with a * 720p TV screen: the density for 1080p televisions is * {@link #DENSITY_XHIGH}, and the value here provides the same UI * size for a TV running at 720p. It has also found use in 7" tablets, * when these devices have 1280x720 displays. */ public static final int DENSITY_TV = 213 ; /** * Standard quantized DPI for high-density screens. */ public static final int DENSITY_HIGH = 240 ; /** * Standard quantized DPI for extra-high-density screens. */ public static final int DENSITY_XHIGH = 320 ; /** * Intermediate density for screens that sit somewhere between * {@link #DENSITY_XHIGH} (320dpi) and {@link #DENSITY_XXHIGH} (480 dpi). * This is not a density that applications should target, instead relying * on the system to scale their {@link #DENSITY_XXHIGH} assets for them. */ public static final int DENSITY_400 = 400 ; /** * Standard quantized DPI for extra-extra-high-density screens. Applications * should not generally worry about this density; relying on XHIGH graphics * being scaled up to it should be sufficient for almost all cases. */ public static final int DENSITY_XXHIGH = 480 ; /** * Standard quantized DPI for extra-extra-extra-high-density screens. Applications * should not generally worry about this density; relying on XHIGH graphics * being scaled up to it should be sufficient for almost all cases. A typical * use of this density would be 4K television screens -- 3840x2160, which * is 2x a traditional HD 1920x1080 screen which runs at DENSITY_XHIGH. */ public static final int DENSITY_XXXHIGH = 640 ; |
http://tools.oesf.biz/android-4.4.2_r1.0/xref/frameworks/base/include/androidfw/ResourceTypes.h
854 855 856 857 858 859 860 861 862 863 864 | enum { DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT, DENSITY_LOW = ACONFIGURATION_DENSITY_LOW, DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM, DENSITY_TV = ACONFIGURATION_DENSITY_TV, DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH, DENSITY_XHIGH = ACONFIGURATION_DENSITY_XHIGH, DENSITY_XXHIGH = ACONFIGURATION_DENSITY_XXHIGH, DENSITY_XXXHIGH = ACONFIGURATION_DENSITY_XXXHIGH, DENSITY_NONE = ACONFIGURATION_DENSITY_NONE }; |
http://tools.oesf.biz/android-4.4.2_r1.0/xref/frameworks/native/include/android/configuration.h
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | struct AConfiguration; typedef struct AConfiguration AConfiguration; enum { ACONFIGURATION_ORIENTATION_ANY = 0x0000 , ACONFIGURATION_ORIENTATION_PORT = 0x0001 , ACONFIGURATION_ORIENTATION_LAND = 0x0002 , ACONFIGURATION_ORIENTATION_SQUARE = 0x0003 , ACONFIGURATION_TOUCHSCREEN_ANY = 0x0000 , ACONFIGURATION_TOUCHSCREEN_NOTOUCH = 0x0001 , ACONFIGURATION_TOUCHSCREEN_STYLUS = 0x0002 , ACONFIGURATION_TOUCHSCREEN_FINGER = 0x0003 , ACONFIGURATION_DENSITY_DEFAULT = 0 , ACONFIGURATION_DENSITY_LOW = 120 , ACONFIGURATION_DENSITY_MEDIUM = 160 , ACONFIGURATION_DENSITY_TV = 213 , ACONFIGURATION_DENSITY_HIGH = 240 , ACONFIGURATION_DENSITY_XHIGH = 320 , ACONFIGURATION_DENSITY_XXHIGH = 480 , ACONFIGURATION_DENSITY_XXXHIGH = 640 , |
おまけとしてツールやテストコードも調査
aaptツールのコード
http://tools.oesf.biz/android-4.4.2_r1.0/xref/frameworks/base/tools/aapt/AaptAssets.cpp
1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 | bool AaptGroupEntry::getDensityName( const char * name, ResTable_config* out) { if (strcmp(name, kWildcardName) == 0 ) { if (out) out->density = ResTable_config::DENSITY_DEFAULT; return true ; } if (strcmp(name, "nodpi" ) == 0 ) { if (out) out->density = ResTable_config::DENSITY_NONE; return true ; } if (strcmp(name, "ldpi" ) == 0 ) { if (out) out->density = ResTable_config::DENSITY_LOW; return true ; } if (strcmp(name, "mdpi" ) == 0 ) { if (out) out->density = ResTable_config::DENSITY_MEDIUM; return true ; } if (strcmp(name, "tvdpi" ) == 0 ) { if (out) out->density = ResTable_config::DENSITY_TV; return true ; } if (strcmp(name, "hdpi" ) == 0 ) { if (out) out->density = ResTable_config::DENSITY_HIGH; return true ; } if (strcmp(name, "xhdpi" ) == 0 ) { if (out) out->density = ResTable_config::DENSITY_XHIGH; return true ; } if (strcmp(name, "xxhdpi" ) == 0 ) { if (out) out->density = ResTable_config::DENSITY_XXHIGH; return true ; } if (strcmp(name, "xxxhdpi" ) == 0 ) { if (out) out->density = ResTable_config::DENSITY_XXXHIGH; return true ; } char * c = ( char *)name; while (*c >= '0' && *c <= '9' ) { c++; } // check that we have 'dpi' after the last digit. if (toupper(c[ 0 ]) != 'D' || toupper(c[ 1 ]) != 'P' || toupper(c[ 2 ]) != 'I' || c[ 3 ] != 0 ) { return false ; } // temporarily replace the first letter with \0 to // use atoi. char tmp = c[ 0 ]; c[ 0 ] = '\0' ; int d = atoi(name); c[ 0 ] = tmp; if (d != 0 ) { if (out) out->density = d; return true ; } return false ; } |
holo向けCTS(Compatibility Test Suite)のテストコード
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 | public class DisplayInfoActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.display_info); WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); display.getMetrics(metrics); DisplayMetrics dm = getResources().getDisplayMetrics(); int width = Math.round(dm.widthPixels / dm.density); int height = Math.round(dm.heightPixels / dm.density); TextView text = (TextView) findViewById(R.id.text); text.setText(getString(R.string.display_info_text, metrics.densityDpi, getScreenDensityBucket(metrics), width, height)); } private String getScreenDensityBucket(DisplayMetrics metrics) { switch (metrics.densityDpi) { case DisplayMetrics.DENSITY_LOW: return "ldpi" ; case DisplayMetrics.DENSITY_MEDIUM: return "mdpi" ; case DisplayMetrics.DENSITY_HIGH: return "hdpi" ; case DisplayMetrics.DENSITY_XHIGH: return "xdpi" ; case DisplayMetrics.DENSITY_XXHIGH: return "xxdpi" ; case DisplayMetrics.DENSITY_XXXHIGH: return "xxxdpi" ; case DisplayMetrics.DENSITY_TV: return "tvdpi" ; default : return "" + metrics.densityDpi; } } } |
au Isai FL向けのアプリアイコン
アプリアイコンは、通常の4倍の大きさの192×192 px の必要だそうです。ただ、以下のようにGoogle Play向けに512×512 px のアイコンを作っておいて、そこから各DPIごとのアイコンを生成していると思いますので問題ないかとは思います。アプリの機能を変更しないのに、versionCodeをあげて、google play に apkをアップしなおさないといけないのは少し手間ですね。Google Playにアップした512×512 px アイコンから自動的に各DPIごとのアイコンを生成して、配布するapkにいれてくれればいいのになぁと思ってしまいました。