Androidのバージョンはグングン上がります。
今やそろそろAndroid 11がリリースされつつあります。
そのAndroid 11にて、ついに日本の元号「令和」が標準APIで対応するようです。
結論
結論を真っ先に述べます。
- Android 11(R)にて、ついに日本の元号「令和」が標準APIで対応するようです。
- すでにAPIレベル24からAndroid標準APIはICUを取り込んでいます。
- でもAPIレベル24~29の間は「令和」には対応していません。「平成」どまりです。
[閑話]コードネームとかAPIレベルとか
ところで、お菓子の名前のコードネームですが、「Q」からやんなくなりました。
KitKatとかLollipopとかMarshmallowとかNougatとかOreoとかPieとか。時折、登録商標も混ざりながらも。
Androidっ子たちは、「Q」から綴りが始まるお菓子が何になるのかワクワクしてたのに、Googleが「お菓子の名前はもうやめた」と言い出して。
Android 10は「Q」。そろそろリリースされる11は「R」です。
Androidの「R」で「令和」に対応...まっまさか!その「R」は、「Reiwa」のRか?!なんちゃって。
そして、この10とか11というバージョン番号、そしてコードネームとは別に、開発者にとって重要な番号は「APIレベル」です。
Android 8.0はOreoであり、APIレベルは26です。が、Android 8.1となると、同じくOreoなんですが、APIレベルは27です。ややこしい!
そして「R」に割り当てられるAPIレベルの番号は...?それは当記事の最後の方に記しましたので、お楽しみに。(じらしてスミマセン)
IBM社製のICUというライブラリ
http://site.icu-project.org/home
「International Components for Unicode」の略だそうです。とにかく色々と便利なAPIが収録されています。
オープンソースソフトウェアです。
ICUのJapaneseCalendarクラス
com.ibm.icu.util.JapaneseCalendar
クラスは、日本の元号に対応しています。
最初の元号「大化」から現代まで。南北朝時代をどう扱っているか、というマニアックなところまで私は検証していませんが。
import java.util.Locale;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.DateFormatSymbols;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.JapaneseCalendar;
public class Honnoujinohen {
public static void main(String[] args) {
JapaneseCalendar jpCalendar = new JapaneseCalendar();
DateFormatSymbols dfs = new DateFormatSymbols(jpCalendar, Locale.JAPANESE);
DateFormat dateFormat = new SimpleDateFormat("Gyy年MM月dd日", dfs);
dateFormat.setCalendar(jpCalendar);
// 「本能寺の変」1582年6月2日
int year = 1582;
int month = 6;
int day = 2;
String s = dateFormat.format(new GregorianCalendar(year, month - 1, day).getTime());
System.out.println(s);
}
}
天正10年06月02日
大河ドラマファンや歴女には堪りませんね。麒麟がくる。「天が正しい」と書く元号だったのか。
ああ、応仁の乱。天保の改革。安政の大獄。元号に思いを馳せるだけで脳内で時代を駆け巡れます。
このICUが「令和」に対応したのは、2019年4月17日リリースのバージョン64.2からです。
Android標準API
Android標準APIでは、APIレベル24(Android 7.0 Nougat)からICUを取り込みました。
取り込んだだけあって、パッケージも変わっております。例えば、前出のJapaneseCalendar
クラスは、android.icu.util.JapaneseCalendar
です。
そして。ついに。Android 11(R)のAPIレベルで、
public static final int REIWA
が追加されます!まさかのint enumパターーーン!!!いやーーーん!!!
しょうがねぇだろ、IBM社製のICUがそもそもint enumパターーーンなんだからーーーん!!!
サンプルアプリ
こんなアプリを作ってみました。
「建武の新政」は、鎌倉幕府を倒した後醍醐天皇が、1333年7月17日からスタートさせた新政策ですが、当日はまだ元号が「元弘」だというヒッカケ問題ですね。今度の2学期中間試験に出そうだな。
平成から令和へ。
開発環境は以下の通りです。
Android Studio 3.6.1
Build #AI-192.7142.36.36.6241897, built on February 27, 2020
Runtime version: 1.8.0_212-release-1586-b04 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
GC: ParNew, ConcurrentMarkSweep
Memory: 1237M
Cores: 8
Registry: ide.new.welcome.screen.force=true
Non-Bundled Plugins:
Gradleの設定
Android 11(R)のAPIレベルで作らなければなりません。
Gradle設定ファイルに以下のようにします(一部略)。
android {
compileSdkVersion 'android-R'
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.example.gengou"
minSdkVersion 24
}
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
}
この記事執筆時点では、Android 11(R)のAPIレベルに番号が割り当てられていません。まだプレビュー版だからのようです。正式版がリリースされたら、おそらく30
になると推測されます。
minSdkVersion
は最低でも24
にしなければなりません。なぜなら前述にありますように、ICUがAndroid標準APIに組み込まれたのが、APIレベル24からだからです。
Activity
package com.example.gengou;
import android.icu.text.DateFormat;
import android.icu.text.DateFormatSymbols;
import android.icu.text.SimpleDateFormat;
import android.icu.util.GregorianCalendar;
import android.icu.util.JapaneseCalendar;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText year = findViewById(R.id.year);
EditText month = findViewById(R.id.month);
EditText day = findViewById(R.id.day);
TextView gengo = findViewById(R.id.gengou);
findViewById(R.id.button).setOnClickListener(v -> {
int y = Integer.parseInt(year.getText().toString());
int m = Integer.parseInt(month.getText().toString());
int d = Integer.parseInt(day.getText().toString());
JapaneseCalendar jpCalendar = new JapaneseCalendar();
DateFormatSymbols dfs = new DateFormatSymbols(jpCalendar, Locale.JAPANESE);
DateFormat dateFormat = new SimpleDateFormat("Gyy年MM月dd日", dfs);
dateFormat.setCalendar(jpCalendar);
String s = dateFormat.format(new GregorianCalendar(y, m - 1, d).getTime());
gengo.setText(s);
});
}
}
Android標準APIではなく、IBMのICUで令和に対応する
せっかくAndroid標準APIで令和に対応するってのに!それを使わずに、IBMのICUで令和に対応するって、なんか本末転倒!
と思われるかもしれませんが、以下の理由でそんなコトもしてみたいのです。
- Android標準APIで令和に対応するのは、「R」からだ。それはいい。
- ICUがAndroid標準APIに組み込まれたのは、APIレベル24(Android 7.0「N」)だ。
- であれば、Gradleの設定で
minSdkVersion
は最低でも24でないと、令和うんぬん以前に、android.icu
パッケージが使えない。 - だけど、自分の作るアプリは、Androidのバージョン6とか5とか4とかにも対応したい!
ということで、そのやり方です。
Gradleの設定
dependencies {
implementation 'com.ibm.icu:icu4j:64.2'
}
依存ライブラリとして追記してSyncNowですね。令和対応の64.2
以上を指定します。
プログラム
名前衝突を避けるためにもimport
文はこうなります。
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.DateFormatSymbols;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.JapaneseCalendar;
import java.util.Locale;
Locale
だけは、安定のjava.util
パッケージですね。
これでAndroid 6とか5とか4とかでも、令和対応できます。
[おまけ]当たり前ですが。
「光文」という元号は、ICUにはありませんので、ご安心を。
以上です。