DataOutputStreamにやられたぜ


先日納品したAndroidのサンプルコード(Java)で、日本語が化けるのだがという連絡が来たので、色々と調査した結果、DataOutputStreamクラスのwriteBytesメソッドの仕様が大っ嫌いになりそうな仕様になっているのよ。

文字列を基本となる出力ストリームに一連のバイトとして書き込みます。文字列中の各文字型データは順番に書き込まれ、このとき上位 8 ビットは無視されます。

『上位8ビットは無視される』って何よ。。。。 これが原因で、日本語とかマルチバイト文字列は、データが欠損してしまうわけよ。

os.writeBytes(contentsBuilder.toString());

って書いてあった部分があったら

byte[] bytes = contentsBuilder.toString().getBytes();
for (int i=0;i<bytes.length;i++){
  os.writeByte(bytes[i]);
}

でOKになります。

原因を見つけるまでに、切り分けで時間がめっちゃかかってしまったよ。
実際のHTTPパケットを見たくて、Wireshackインストール、ローカルPC(MacOSX)にWebサーバ立ち上げて、パケットを解析することになったんだけど、MacOSXって便利ね、

$ php -S localhost:8080

で、簡単にローカルWebサーバ起動できるのね。

あと、嵌まったのが、Android 9搭載の端末で開発していたので、HTTPのアクセスがNGになっているので、Manifest.xmlにandroid:networkSecurityConfig=”@xml/network_security_config”
を追記し、network_security_config自体は下記のように書いて、HTTP通信を許可するようにした。

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">192.168.100.11</domain>
    </domain-config>
</network-security-config>

なんとか解決することが出来て良かった!