k9mailを日本語環境でただしく使えるようにした
GDP1 で android のメールアプリが Connection error
と言うエラーで新しいメールをまったく受信してくれない状態になってしまった。GDDフォンだとこの問題はいまのところ出たことはない。
昔、 brad のブログで k9mail というのを見たのを思い出したのでそれを入れてみたのだが、ヘッダーのエンコード処理がされておらず日本語の件名などをつかうと化け化けになってしまう。
機能的には k9mail のほうが優れていて、このエンコード問題さえ解決できれば使えそうだなーと思ったのでいっちょパッチを書いてみた。
diff --git a/src/com/android/email/mail/internet/MimeHeader.java b/src/com/android/email/mail/internet/MimeHeader.java
index 24aad4d..a117e08 100644
--- a/src/com/android/email/mail/internet/MimeHeader.java
+++ b/src/com/android/email/mail/internet/MimeHeader.java
@@ -11,6 +11,7 @@ import java.util.List;
import com.android.email.Email;
import com.android.email.Utility;
import com.android.email.mail.MessagingException;
+import org.apache.james.mime4j.codec.EncoderUtil;
public class MimeHeader {
/**
@@ -97,12 +98,35 @@ public class MimeHeader {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out), 1024);
for (Field field : mFields) {
if (!Utility.arrayContains(writeOmitFields, field.name)) {
- writer.write(field.name + ": " + field.value + "\r\n");
+ String v = field.value;
+
+ if (hasToBeEncoded(v)) {
+ v = EncoderUtil.encodeEncodedWord(
+ field.value,
+ EncoderUtil.Usage.WORD_ENTITY
+ );
+ }
+
+ writer.write(field.name + ": " + v + "\r\n");
}
}
writer.flush();
}
+ // encode non printable characters except LF/CR codes.
+ public boolean hasToBeEncoded(String text) {
+ for (int i = 0; i < text.length(); i++) {
+ char c = text.charAt(i);
+ if (c < 0x20 || 0x7e < c) { // non printable
+ if (c != 0x0a && c != 0x0d) { // non LF/CR
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
class Field {
String name;
github にもあげた。
この実装がただしいかどうかはわからないけど、これで一応ちゃんとエンコードされるようになる。
ところで、おもしろいのがこのパッチは com.android. なパッケージを編集してしまっていると言うこと。 なんと k9mail は com.android.* のパッケージも含んでいるのである。android のメール機能を持ってきて再利用している。 これはアプリごとにVMが別れてるandroidだからできることなのかなぁとか思ったりした。
エンコードされないとかどう見てもバグなので issue 登録しておいた。パッチは採用されないと思うけどw android のメールではこの問題はおこらないということは com.android.* なところはいじらなくても実現可能ということなので。