システム設定でフォントを変更しても、フォントの大きさを維持する方法

目次
---

1. はじめに
2. 実装方法
3. まとめ


はじめに
---
Androidは端末自体の設定で、表示される文字のサイズを変更することができ、そのサイズ変更はKonyで開発したアプリにも適応されます。そのため、ユーザのフォントサイズ設定によってレイアウトが影響を受けてしまう可能性があります。
本記事では、システム設定でフォントサイズが変更されても影響を受けないよう、Konyアプリでフォントサイズを維持する方法について紹介いたします。

|実装前|実装後(完成イメージ)|
|---|---|
|![前.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/2400bd90-51c4-5a80-a871-e7c6dad050a2.gif)|![後.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/ea0a2557-66cc-12bd-0d36-f1553fbb38dd.gif)|

使用するサンプルは、Formにラベルを１つ置いただけのシンプルなプロジェクトです。
![スクリーンショット 2021-04-22 15.51.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/2b61c995-1c88-720b-8bbe-e82fc6f61bd0.png)


実装方法
---

フォントサイズの設定は、Visualizerでのビルド後にAndroidのネイティブコードを直接編集して修正することもできますが、再ビルド時に設定が上書きされてしまいます。
そこで今回は、Androidアプリのコンパイル前後で独自の処理を実行させることができる **androidprecompiletask.xml** を使用します。


**androidprecompiletask.xml**の使い方と実装方法について、順に説明していきます。

#### 1 ．テンプレートの保存 / 追加

まず、Visualizer上部のメニューから Product > Build を選択し、
Androidを選択してビルドを行います。
![スクリーンショット 2021-04-22 16.02.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/ade525e2-73f8-c2d5-d9c8-36f0c01e7702.png) 


Androidのビルドをすると、以下のパスに**androidprecompiletask.xml**のテンプレートが作成されます。
``<Workspace>/temp/<Appname>/build/luaandroid/extres/androidprecompiletask.xml``
![スクリーンショット 2021-04-22 11.55.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/9011a222-466d-c4c2-3956-88274bc85a72.png)


上のパスから**androidprecompiletask.xml**をコピーして、ワークスペース内のプロジェクトファイル直下にペーストします。
以下のように追加してください。
``<Workspace>\<Appname>\androidprecompiletask.xml``
![スクリーンショット 2021-04-22 11.58.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/1634a1e5-f863-c7ca-6d41-17b94872ad19.png)



#### 2 . androidprecompiletask.xml の編集

##### 2-1. androidprecompiletask.xml について
まずは、編集前のandroidprecompiletask.xml を見てみます。

```xml:androidprecompiletask.xml
<project name="PreCompile" default="PreCompileSetup">
    <!--- 
    コメント
    --->>
	<target name="PreCompileSetup" >
		<echo message="basedir = ${basedir} ,konyapp.dir = ${konyapp.dir}, appdir = ${app.dir} , isUniversalApp = ${isUniversalApp} ,isMobileBuild = ${isMobileBuild}"/>
		<echo message="Build mode = ${build.option} , Packagepath = ${packagepath} , x86 Support = ${supportx86}" />		
		<echo>Java/JVM version: ${ant.java.version}</echo> 
		<echo>Java/JVM detail version: ${java.version}</echo>
	</target>
</project>	
```
コメントには、ここで使われている値の説明とandroidprecompiletask.xmlの使い方が記載してあります。
内容は以下の通りです。

|値|説明|
|---|---|
|{basedir}|このxmlが存在する現在のディレクトリを指します|
|{konyapp.dir}|konyアプリケーションのベースディレクトリを指します|
|{app.dir}|現在のkonyアプリ用に作成されたNative androidアプリケーションのディレクトリを指します|
|{packagepath}|srcフォルダからの相対的なパッケージ名フォルダパスを示す|
|{build.option}|現在のビルドが "debug "または "release "モードであることを示す|
|{supportx86}|IDEのビルドオプションでx86フラグがチェックされている場合、"true "に設定されます|
|{isUniversalApp}|ユニバーサルビルドの場合は "true "に設定され、モバイルとタブレットの両方のアセットとjsファイルが単一のapkに含まれます |
|{isMobileBuild}|現在のビルドがモバイル用に起動されている場合は "true "に、タブレット用に起動されている場合は "false "に設定されます|


**androidprecompiletask.xmlの使い方**
>1) このxmlは、ワークスペース内のプロジェクトファイル直下に配置する

>2) このxmlは以下のように使用することができます。

>- 修正したBuild xmlファイルをAndroidのネイティブフォルダにコピーする。

>- その他のカスタムlib、assets、resファイルをネイティブのアンドロイド階層にコピーする。

>- 任意のlibからx86 .soファイルをコピーする（変数${supportx86}がtrueに設定されている場合のみ）

>- project.propertiesやlocal.propertiesなどのカスタムパスを変更/追加する。

>- {isMobileBuild}を使って、モバイルとタブレットで異なるタスクを実行する。


今回はフォントサイズを固定するために、androidprecompiletask.xmlを使って、Androidのネイティブフォルダにある **\<AppName>.java** と **AndroidManifest.xml** に処理を書き込んでいきます。

**\<AppName>.java**は以下のパスに格納されているものです。
``<Workspace>/temp/<Appname>/build/luaandroid/dist/<Appname>/src/com/orgname/<Appname>/<Appname>.java``

##### 2-2. プロパティの作成
はじめに、**\<AppName>.java**に追加したいコードを、プロパティとしてまとめていきます。

追加するコードは以下です。

```xml:androidprecompiletask.xml
<project name="PreCompile" default="PreCompileSetup">
        ......(省略)
		<echo>Java/JVM detail version: ${java.version}</echo>
		
>>>>  追加  >>>>
		<property name="importStatements" value="import android.content.res.Configuration; ${line.separator}
		import android.content.Context; ${line.separator}"/>
		
		<property name="fontsizeFixCode" value="@Override ${line.separator}
		protected void attachBaseContext(Context newBase) { ${line.separator}
		super.attachBaseContext(newBase); ${line.separator}
		final Configuration override = new Configuration( ${line.separator}
		// Copy the original configuration so it isn’t lost. ${line.separator}
        newBase.getResources().getConfiguration() ${line.separator}
		); ${line.separator} override.fontScale = 1.0f; ${line.separator}
		applyOverrideConfiguration(override); ${line.separator} }" />
>>>>>>>>>>>>>>

	</target>
</project>	
```

javaファイル上で改行させるために${line.separator}を使用しているため読みにくいと思います。一度 実際に追加されるコードに直して説明します。

```java
// importStatements 
import android.content.res.Configuration;
import android.content.Context;


// fontsizeFixCode
@Override 
protected void attachBaseContext(Context newBase) { 
   super.attachBaseContext(newBase); 
   final Configuration override = new Configuration( 
     // 元の設定が失われないようにコピー 
     newBase.getResources().getConfiguration() 
   ); 
   override.fontScale = 1.0f; 
   applyOverrideConfiguration(override); 
}
```

- importStatements

フォント設定を扱えるように、端末の構成情報を扱うクラスと、アプリケーションのリソースなどにアクセスするためのクラスをインポートしています。
詳しくはこちらをご覧ください。

https://developer.android.com/reference/kotlin/android/content/res/Configuration

https://developer.android.com/reference/android/content/Context?hl=ja


- fontsizeFixCode  

元の端末設定に、``fontScale = 1.0f; ``というフォントサイズ設定をoverrideしています。ここでフォントサイズを設定することで、端末の設定に左右されずにアプリで文字を表示することができるようになります。
Configurationと、KonyアプリでのfontScaleついて詳しくはこちらをご覧ください。

https://developer.android.com/reference/android/view/ContextThemeWrapper

https://basecamp.temenos.com/s/article-detail/a046A00000AVTFxQAP/fix-the-font-size-regardless-the-system-settings


##### 2-3. **\<AppName>.java** への書き込み
2-2では、**\<AppName>.java**に追加したいコードをプロパティとして用意しました。次は、そのプロパティを**\<AppName>.java**に書き込むための処理を追加します。
追加するのは以下のコードです。

```xml:androidprecompiletask.xml
<replaceregexp file="${app.dir}/src/${packagepath}/${appid}.java"
               match="extends KonyMain  \{"
               replace="extends KonyMain { ${line.separator} ${fontsizeFixCode}"
               byline="true"/>

<replaceregexp file="${app.dir}/src/${packagepath}/${appid}.java"
	           match="${packagename};"
	           replace="${packagename}; ${line.separator} ${importStatements}"
	           byline="true"/>
```

**replaceregexp**
``replaceregexp``は、指定のファイル内に存在する、特定の正規表現パターンを置換する時に使用します。

|パラメータ|説明|
|---|---|
|file|対象のファイル|
|match|ファイル内で探す正規表現パターン|
|replace|置換する正規表現パターン|
|byline|ファイルを一度に１行ずつ処理するかどうかをtrue/falseで指定する。(デフォルトではfalse)|

他にもパラメータはありますが、今回は使用しないため割愛いたします。
詳しくはこちらをご覧ください。

https://ant.apache.org/manual/Tasks/replaceregexp.html


今回は、追加したい行の手前にあるコードを``match``に指定して、``replace``に「**match + 作成したプロパティ**」を
入れることで、特定箇所への書き込みを実現しています。

##### 2-4. **AndroidManifest.xml** への書き込み
最後に**AndroidManifest.xml**にも以下の修正を加えます。

```xml:androidprecompiletask.xml
<replaceregexp file="${app.dir}/AndroidManifest.xml"
	           match='orientation'
	           replace='orientation|fontScale'
	           byline="true"/>
```

##### ソースの全体
作成したソースがこちらです。

```xml:androidprecompiletask.xml
<project name="PreCompile" default="PreCompileSetup">

	<target name="PreCompileSetup" >
		<echo message="basedir = ${basedir} ,konyapp.dir = ${konyapp.dir}, appdir = ${app.dir} , isUniversalApp = ${isUniversalApp} ,isMobileBuild = ${isMobileBuild}"/>
		<echo message="Build mode = ${build.option} , Packagepath = ${packagepath} , x86 Support = ${supportx86}" />
		<echo>Java/JVM version: ${ant.java.version}</echo>
		<echo>Java/JVM detail version: ${java.version}</echo>

		<property name="importStatements" value="import android.content.res.Configuration; ${line.separator}
		import android.content.Context; ${line.separator}"/>

		<property name="fontsizeFixCode" value="@Override ${line.separator}
		protected void attachBaseContext(Context newBase) { ${line.separator}
		super.attachBaseContext(newBase); ${line.separator}
		final Configuration override = new Configuration( ${line.separator}
		// Copy the original configuration so it isn’t lost. ${line.separator}
        newBase.getResources().getConfiguration() ${line.separator}
		); ${line.separator} override.fontScale = 1.0f; ${line.separator}
		applyOverrideConfiguration(override); ${line.separator} }" />

		<replaceregexp file="${app.dir}/src/${packagepath}/${appid}.java"
                       match="extends KonyMain  \{"
                       replace="extends KonyMain { ${line.separator} ${fontsizeFixCode}"
                       byline="true"/>

	    <replaceregexp file="${app.dir}/src/${packagepath}/${appid}.java"
	                   match="${packagename};"
	                   replace="${packagename}; ${line.separator} ${importStatements}"
	                   byline="true"/>

	    <replaceregexp file="${app.dir}/AndroidManifest.xml"
	                   match='orientation'
	                   replace='orientation|fontScale'
	                   byline="true"/>
	</target>
</project>

```

#### 3 . Androidビルドと確認
ソースが完成したので、最後にもう一度 androidprecompiletask.xmlのパスがあっているか確認しましょう。
``<Workspace>\<Appname>\androidprecompiletask.xml``
![スクリーンショット 2021-04-22 11.58.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/1634a1e5-f863-c7ca-6d41-17b94872ad19.png)

確認ができたら、Visualizerで再度Androidビルドをします。
端末設定を変更しても、フォントサイズが維持されていることが確認できると思います。
![後.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/ea0a2557-66cc-12bd-0d36-f1553fbb38dd.gif)


#### ※ フォントサイズが維持されていない場合
**\<AppName>.java** と **AndroidManifest.xml** にコードが追加されているか確認してください。


**\<AppName>.java**
パス: ``<Workspace>/temp/<Appname>/build/luaandroid/dist/<Appname>/src/com/orgname/<Appname>/<Appname>.java``

２行目に import~~ が追加されていることを確認
![スクリーンショット 2021-04-22 16.17.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/1ef756d2-9081-2726-4ae0-0eab75a0d6bf.png)

「extends KonyMain { 」の後に、追加した処理が書き込まれていることを確認
![スクリーンショット 2021-04-22 16.16.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/44700d31-dac8-75ef-5265-c60f10aca991.png)


**AndroidManifest.xml** 
パス: ``<Workspace>/temp/<Appname>/build/luaandroid/dist/<Appname>/AndroidManifest.xml``
「fontScale」で検索して、追加されていることを確認。
![スクリーンショット 2021-04-22 16.20.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/7d82df3b-eeb2-df6d-f274-1a3a9852e8e8.png)

replaceregexp　に設定した matchパラメータの値と実状に差異があり上手く置換できなかった可能性がありますので、再度ご確認ください。(スペースの数など)



まとめ
---
今回は、システム設定でフォントを変更してもフォントの大きさを維持する方法をご紹介いたしました。フォントサイズ以外にも、androidprecompiletask.xmlを使えば KonyアプリケーションでAndroidの端末設定をカスタムできると思うのでぜひ試してみてください！


**参考**

https://basecamp.temenos.com/s/question/0D52K000043kNUXSA2/keep-font-size-same-if-user-changes-the-system-settings

https://basecamp.temenos.com/s/article-detail/a046A00000AVTFxQAP/fix-the-font-size-regardless-the-system-settings

https://developer.android.com/reference/kotlin/android/content/res/Configuration

https://developer.android.com/reference/android/content/Context?hl=ja

https://developer.android.com/reference/android/view/ContextThemeWrapper