最近有个盘点用的东西,要放到移动设备,本来用 .Net Compact Framework,CAB 部署在 CE 系统的移动条码设备。技术太旧,我用了这个周末两天时间,把这东西在试试实现在安卓上面,给用户看看效果。

很多很多的意外,大量 Gotcha… 分享一下我的惨痛经历。以下有错误、或各位大哥有更好做法,请留言赐教。

1. IIS 上面用 ASMX,返回 JSON,原来在客户端 POST 时候是必须注明 Content-type 为 json,否则 ASMX 返回 XML。POST 没有标识为 json,即使你自己序列化,它也是返回 XML 包裹着 JSON。

ASP.NET CODE:

namespace Stocktake {/// <summary>/// Summary description for RecordService/// </summary>
    [WebService(Namespace = "http://xxx.com/")][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)][System.ComponentModel.ToolboxItem(false)]// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]public class RecordService : System.Web.Services.WebService {[WebMethod][ScriptMethod(ResponseFormat = ResponseFormat.Json)]public StocktakeCode getStocktakeCode() {var result = new StocktakeCode() {Code = "Testing",Remark = "Some Remark"};return result;}}public class StocktakeCode {public string Code {get;set;}public string Remark {get;set;}}
}

这段服务器端代码,我拼了命找错处,StackOverflow、Google、百度,原来,是没有错的。TMD x 10000。问题是下面客户端的,之前没 addHeader()。

ANDROID CODE:

public class DataAccess {  public static String getStocktakeCode(StocktakeActivity activity)throws IOException {HttpHost target = new HttpHost(getHostName(activity), getServerPort(activity));HttpClient client = new DefaultHttpClient();HttpPost post = new HttpPost(getStockCodeWsPath(activity));post.addHeader("Content-type", "application/json; charset=utf-8"); //  THIS IS IMPORTANT
    HttpEntity results = null;try{HttpResponse response=client.execute(target, post);results = response.getEntity();return EntityUtils.toString(results);} catch (Exception e){throw new IOException("Web Service failed.");} finally{if(results!=null){try{results.consumeContent();} catch (IOException e){}}}}
}

2. web.config 要加 protocol … 我忘记了加。

ASP.NET web.config XML:

<webServices><protocols><add name="HttpPost"/></protocols>
</webServices>

不熟悉  web 开发的我,这个也很要人命。

3. MS 自动序列化为 JSON 时,多了个莫名其妙的 d:。客户端那边,必须用 getString 方式过滤掉。里面的字符才是我们要的。

ANDROID CODE:

JSONObject raw = new JSONObject(HttpPost_result);
String text = raw.getString("d");

4. Android 内,JSONObject 要取节点内的值用getString,遇上null 会抛JSONException异常。必须检查。

ANDROID CODE:

JSONObject raw = new JSONObject(HttpPost_result);
if(!raw.isNull("d")){String text = raw.getString("d");JSONObject newObj = new JSONObject(text);TextView tv = (TextView)activity.findViewById(R.id.textViewStocktakeCode);tv.setText(newObj.getString("Code"));TextView tv2 = (TextView)activity.findViewById(R.id.textViewStocktakeRemark);tv2.setText(newObj.getString("Remark"));activity.setIsStocktakeAllowed(true);
} else {//...
}

我这设计是,服务器可能返回对象(序列化为 JSON),也可能返回 null。返回 null 时候,服务器发出的响应 JSON 是 {d:null}。

5. Android 内,启动 AsyncTask 必须用 execute()。可能各位安卓的大哥觉得理所当然吧,我没怎么看 documentation 就动手,结果我直接 doInBackground,在 onPreExecute 打断点不到。就这问题,查了 TMD 四小时…。

ANDROID CODE:

错误:

String result = new StocktakeCodeWorker(StocktakeActivity.this).doInBackground((String[])null);

正确:

new StocktakeCodeWorker(StocktakeActivity.this).execute((String[])null);

Execute 是 void 没返回值,要干就要在 Override onPostExecute 内。

6. Android 内,用 intent 打开另一个程序等返回值,要指定 app 的话必须 setPackage。

ANDROID CODE:

Intent intent = new Intent("com.google.zxing.client.android.SCAN");
intent.setPackage("com.google.zxing.client.android"); // THIS IS IMPORTANT
intent.putExtra("SCAN_MODE","ONE_D_MODE");
intent.putExtra("SCAN_FORMAT", "CODE_128");
startActivityForResult(intent, SCAN_BARCODE_REQUEST);

否则,有多个程序供应比如 com.google.zxing.client.android.SCAN 的话,画面会出现 app chooser 让用户选。我测试用的手机上,刚好就有(淘宝、和 ZXING 本身)。我在好几个 QQ 群上问为何,也问为何淘宝出现在 app chooser,无回复。我猜,应该是淘宝用了 ZXING 的代码,而且连开放 INTENT 的也拿了过来的原因。

加上 setPackage 后,问题消失,app chooser 没有出现而直接运行了 ZXING。

7. Android 的 Preferences 内,用 EditTextPreferences 即使指明 input type 是 number,保存的依然是 String。除非你一直直接用代码来保存 preferences 和读取 preferences,否则,SharedPreferences.getInteger 是废的。要自己 parse。

ANDROID Preference XML:

<EditTextPreferenceandroid:key="server_port"android:title="@string/preference_serverPort"android:summary="@string/preference_serverPortRemark"android:dialogTitle="@string/preference_serverPort"  android:inputType="number"android:defaultValue="80" />

ANDROID CODE:

public static int getServerPort(StocktakeActivity activity){SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(activity);String textResult = sp.getString("server_port", "80").trim();return Integer.parseInt(textResult);
}

8. 用 Eclipse 图形化界面添加 Permission ,android.permission.INTERNET,加完依然无法连。搜了一下 StackOverflow,试试手工直接修改 XML,把它删了再手写一次,又可以了… 原因不明。

ANDROID Manifest XML:

<uses-permission android:name="android.permission.INTERNET"/>

真心不知道什么回事。

这完全是为了做个 protocol 出来给用户试试看而已。已能用,不美观,代码不公开。其实最关键部分,已经在上面全都写了。过程没有乐趣,只有痛苦。被采纳的话,接下去给下面的人改。

转载于:https://www.cnblogs.com/leptonation/p/3309040.html

Android 杂记 - 存货盘点用的客户端相关推荐

  1. android开发我的新浪微博客户端-用户授权页面UI篇(3.1)

    看上面的图,其实这个页面的UI实现不复杂,首先是背景部分的实现这个参考 android开发我的新浪微博客户端-载入页面UI篇(1.1),重点来讲讲这个半透明的弹出对话框窗口是如何实现的,首先新建名为A ...

  2. android处理服务器的集合,android集合SSH搭建服务器客户端请求

    android集合SSH搭建服务器客户端请求 (2012-06-14 06:21:53) 标签: android 服务器 杂谈 android集合SSH搭建服务器客户端请求小弟以前是学的J2EE,由于 ...

  3. android开发我的新浪微博客户端-用户授权页面功能篇(3.2)

      ==> 在上一篇实现了用户授权页面的UI,如上图,接下来要做的就是在这个基础上完成功能部分真正实现用户的授权认证,这一篇是android开发我的新浪微博客户端-OAuth篇(2.1)的具体应 ...

  4. android开发我的新浪微博客户端系列教程

    android开发我的新浪微博客户端-载入页面UI篇(1.1)http://www.1000phone.net/thread-7750-1-1.html android开发我的新浪微博客户端-载入页面 ...

  5. android 除了webview 浏览器控件,android开发我的新浪微博客户端-OAuth认证过程中用WebView代替原来的系统自带浏览器...

    前面的文章的OAuth认证过程在获取oauth_verifier码是是通过调用android系统带的浏览器进行用户授权认证的, 具体见:android开发我的新浪微博客户端-用户授权页面功能篇(3.2 ...

  6. Android高仿网易新闻客户端之动态添加标签

    承接上一篇文章:Android高仿网易新闻客户端之首页,今天来实现动态添加标签效果. 动态标签页是一个流式布局,实现了宽度自动换行高度自动分配的功能,代码如下: FlowLayout.java pac ...

  7. [Android] Android 手机下 仿 微信 客户端 界面 -- 微聊

    Android 手机下 仿 微信 客户端 界面 -- 微聊 (包括聊天列表 + 聊天对话页 + 朋友圈列表页 + 我的/发现 列表页) 项目演示: 功能说明: 1)底部标签切换 (TabHost + ...

  8. 基于Android的小巫新闻客户端开发--UI设计(主界面)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 基于An ...

  9. 开篇--基于Android的小巫新闻客户端开发

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 开篇-- ...

  10. android开发c s架构,【开源】基于C/S架构的Android员工增删改查客户端

    背景:html 期末快到了,各门课的课程设计都要来临了,最近Java课的课程设计就在想着作什么好,因而想了下弄一个android的应用吧,因而便有下文了.java 刚入门android,技术很不过关, ...

最新文章

  1. Camera系列规格参数
  2. spring cloud微服务分布式云架构 - Spring Cloud集成项目简介
  3. (紀錄)[ASP.NET MVC][jQuery]-1 純手工打造屬於自己的 jQuery GridView
  4. 什么是网络推广浅析如何提高搜索引擎的抓取频次?
  5. ASP.NET中相对路径的使用总结
  6. 在mysql中更改数据类型_如何在MySQL中更改列的数据类型?
  7. 呼和浩特 计算机编程入门先学什么,学好UG编程先学什么?应该先弄懂这些问题...
  8. php dns更新,php_mzdns: 站群,大量域名 通过 dns 服务商 api 批量添加 ip 工具。你懂的~ 基于 mzphp2 框架。...
  9. php7 cms,PHP7CMS 无条件前台GETSHELL
  10. java socket调用接口_java调用websocket接口
  11. 深度学习(六十二)SqueezeNet网络设计思想笔记
  12. java 的function_Function方法-java
  13. 又一个停止申请后才知道的功能?QQ至尊保服务“下线” 已试运营三年
  14. 用deque模拟栈解决八皇后问题
  15. 汇编语言典型例子详解_汇编语言例子_汇编语言 举例子
  16. FTP/文件传输协议
  17. linux根目录9个g,linux根目录下5个主要的目录,及目录的功能
  18. WIN7下IIS的安装与配置
  19. Industrial Design System v4.5 1CD(工业产品设计软件)
  20. 辨别 优盘 真假 [金士顿]

热门文章

  1. 斯坦福课程Knowledge Graphs-What is a Knowledge Graph?
  2. sublime 中文配置
  3. nacl溶解度_氯化钠溶解度
  4. android批量发送短信
  5. amd 服务器cpu型号怎么看,AMD CPU型号识别方法图解
  6. 常用的几种红外接收器
  7. 联想裁员与全球化背景下的知识阶层失业
  8. easyui datagrid 点击其它 单元格,不让头列 checkbook 选中
  9. AJAX框架构图插画,Zend Framework框架中实现Ajax的方法示例
  10. 今年春节北京烟花爆竹备货量下降46.7%