Android中文乱码解决方法

来源:互联网 发布:录音机软件 手机 编辑:程序博客网 时间:2024/05/22 01:46

原文地址:http://blog.sina.com.cn/s/blog_5f30147a0101lu7a.html

Android中文乱码解决方法

    在手机与PC之间进行socket或HTTP通讯时,常常会出现中文乱码问题,其主要原因在于手机端字符编码默认为UTF-8,而服务器PC端默认为gbk或gb2312。

    手机到PC的信息编码传递、接收、解码显示的过程为:手机端以UTF-8编码信息(包括汉字),写入socket输出流。在写入输出流,或在socket中传递时,或在PC端读取来自手机的Socket流信息时,系统把信息编码进行了一次转换(经编程验证应该是转为GBK),这样在PC端默认以GBK方式解码显示来自手机的信息,出现中文乱码也就不足为奇了。

    根据以上分析,要解决PC端显示中文乱码的问题,必须在PC端对接受的手机端信息进行转码,具体过程如下:

    1、手机端:

    手机端一般可保持默认操作方式即可。当然,执行下述操作也不会产生错误输出:

    strSend = new String(strSend.getBytes(), "UTF-8");

    该操作是按照(手机)当前操作系统的编码格式获取字符串strSend的编码字节(数组),再转换为UTF-8字符串,进行传递。由于手机端默认使用UTF-8编码,所以该操作实际上是多余的。当然,你也可以将操作中第二个参数改变,转换其它编码格式传递试一下。

    2、PC端:

    tempstr = new String(mStrMSG.getBytes("GBK"),"UTF-8");或者:

    tempstr = new String(mStrMSG.getBytes(),"UTF-8");

    PC端的操作就是以默认编码方式(这里为GBK)获取接收到字符串编码字节,再转换为UTF-8格式的字符串显示,以呼应手机端UTF-8的编码格式。

    在本例所使用的设备环境下,只有转换为UTF-8才可以正确显示中文,转为其它格式都会出现乱码。其原因应该是手机端编码为UTF-8,PC端则须相应以UTF-8解码。

    这里两行语句的不同之处仅在于getBytes()是否带参数,不带参数表示以当前默认编码格式获取字节数组,带参数表示以给出的特定编码格式获取字符串的字节数组。 

    另外,经实验,PC端所接收的手机端发送来的中文信息,再次传回手机模拟器时不需要转换编码,否则手机端可能会显示乱码。这就出现了下面有趣的操作:

    mPrintWriter.println(mStrMSG + new String("  测试".getBytes("UTF-8")));

    其中mStrMSG为从手机端获取的包含汉字的信息,发回手机时不需要转换,而附加的汉字信息"  测试"则需要执行转码操作。而且只能以new String("  测试".getBytes("UTF-8"))的方式获取UTF-8编码字节数组,并生成UTF-8字符串;如果换成new String("  测试".getBytes(),"UTF-8")语句,则还是乱码。

    以上解决方案的源码下载

 

    从以上分析可以看出,UTF-8和GBK等之间的编码、解码、转换等操作,需要非常小心,否则会出现很多意想不到的错误。而且,上述解决方案也并非完善,如果汉字字数为奇数时,最后一个汉字还会是乱码,或"??"。

    究其原因,主要是gbk的汉字编码为2字节;而UTF-8的汉字编码则为3字节。
    为了解决奇数个汉字末尾的乱码问题,需要采用从socket输入流直接读取字节再转码的方式:

    以下是PC端的部分代码:

    ......

    private InputStream inputStream;

    ......

    while (true) {
       //inputStream.available()为输入流中的可读字符个数
       while (inputStream.available() > 0) {
          strBytes = new byte[inputStream.available()];
          inputStream.read(strBytes);
          mStrMSG = new String(strBytes,"utf-8");
          if (mStrMSG.trim().equals("exit")) {
             // 当一个客户端退出时
             mClientList.remove(mSocket);
             mPrintWriter.close();
             mStrMSG = "user:" + this.mSocket.getInetAddress()
                 + " exit(total:" + mClientList.size()+")";
             mSocket.close();
             sendMessage();
             //退出当前线程的运行
             return;
          } else {
             mStrMSG = mSocket.getInetAddress() + ":" + mStrMSG;
             sendMessage();
        }
      }

      ......

      手机模拟器端与此类似。

      完整代码下载

 

参考文章:

    《android应用开发揭秘》

     关于Android与pc通信时中文乱码的分析和解决

     Android http中文乱码问题总结

0 0