最近在做根据IP地址自动显示城市天气,真是一步一个坑(其实是自己的知识储备不到位)。今天就说说这个坑爹的volley和json编码这个“大坑”。昨天搞了一个通宵,IP地址可以获取,IP地址获取地理位置也解决了,中华万年历天气数据也可以获取了,结果解析的时候出了大问题——原中华万年历json数据是GBK编码,是这样的(获取方法http://wthrcdn.etouch.cn/weather_mini?city=深圳):
正常应该是这样的:
(经网页自动转码后效果)
经volley获取后的数据是这样的:
(汉字全是乱码)
转码后所有的数据都不能正常显示。经查询原中华万年历json数据是GBK编码:
按理说,把GBK码转成utf-8就应该可以正常显示汉字。看了上百个网页,基本都是说怎么转码的,但没有一个成功的,直接转码代码没问题,直接把BGK的汉字转成utf-8可以正常显示。但在处理volley获取的GBK编码json数据时不行。
直到我看到了下面这篇文章:
android volley设置编码,Android Volley 框架JSON中文乱码问题的解决_笔杆abc的博客-CSDN博客
感谢!!!
虽然文章中没有说如何处理,但我至少知道了不能正常显示的原因,根本原因是volley在获取数据时就“已经”进行了转码,但用的是iso-8859-1编码格式。也就是说volley在获取数据后已经进行了一次转码,GBK->utf-8,但转码不对,再怎么转都是错的。
所以下一步就是如何正确转码,网上普遍的做法就是重写request,这个对我来说是有点难。也很麻烦。后来我想,既然是转码错误,把数据再转回去(iso-8859-1转回BGK),再重新进行转码(GBK转码utf-8)不就行了吗?就是把接收的数据iso-8859-1转换成原编码格式GBK,然后再把GBK转码成UTF-8,应该可以。所以就有下面的代码:
URLEncoder.encode(response,"ISO-8859-1");
String constr = new String(response.getBytes("ISO-8859-1"),"GBK");//iso-8859-1转回GBK
URLEncoder.encode(constr,"GBK");
String conUtf8 = new String(constr.getBytes("GBK"),"UTF-8");//GBK转码UTF-8
结果就显示正常了:
那个�?是℃,现在还不知道是哪里问题。应该也可以解决。
但有一个疑问,如果网站数据是utf-8编码,用volley获取后是可以正常显示汉字的,但iso-8859-1编码不是不可以显示汉字吗?
还有百度IP地址获取城市的代码是unicode编码,也要转码,否则把解构出的城市直接给中华万年历时获取不到数据。
而且在获取的时候汉字也必须要转码,不然获取不到。所以深圳天气在获取的代码里显示是这样的:
http://wthrcdn.etouch.cn/weather_mini?city=%E6%B7%B1%E5%9C%B3
网页直接输入下面这样就可以:
http://wthrcdn.etouch.cn/weather_mini?city=深圳
深圳两个字也是经过转码的。
String encodeStr = URLEncoder.encode(city, "utf-8");//unicode转utf-8
这个现在到底要怎么转还没有弄清,只是实验成功了,根本原理还不懂。