RSS Feed

‘code’ Category

  1. Invalid Product IDs

    六月 6, 2011 by bborn

    iOS除了可以推收费app之外,还可以通过IAP(In App Purchase)获得收益
    IAP开发其实很简单
    但是教程写的很繁琐 把简单的事情貌似很复杂
    除此之外,新手在起步的时候很容易遇到挫折
    就是获取商品ID到时候 返回Invalid Product IDs

    这里有两篇文章可以参考
    Apple Technical Note TN2259
    Invalid Product IDs

    但是这里有个问题 都没有提到
    设备不能越狱!!
    iOS devices must not Jailbreaking.

    就在这个问题上让我纠结了好几天
    很郁闷


  2. bada初体验二三事

    十月 31, 2010 by bborn

    很早之前看过一次bada
    本来想在十一之前做点东西出来的
    不过那个时候太忙 给耽误了

    周末没事在家 又想在bada上做点东西
    看了看bada的资料
    中文文章不多
    官方但api文档还不错 挺详细的
    并且附有一些简单的例子

    调试很方便 用断点出现过几次没有响应但情况
    再就是模拟器打开之后 再调试就会提示”simulator already launched”
    试了试几个办法都没发解决 这是个要优先解决的问题
    好在是模拟器启动的很快

    sdk1.0不带数据压缩和解压缩
    1.1增加了Inflator 和 Deflator
    不过这sdk更新就是将近1g …
    1.1的模拟器好看多了

    sdk目前没有找到json解析的方法
    所以需要第三方库
    在badadev看到这个话题的讨论
    可以使用yajl来做
    基本不需要做改动

    bada的网络编程看起来比较简单
    异步处理 可以较少考虑线程
    这方面还没有深入的看

    bada的ui这块文档不多 还有不少疑问
    可以可视化的编辑
    也可以用代码来生成
    1.1的向导增加了分辨率自适应
    不过还没有找到方法 怎么做?
    模拟器提供的分辨率就两种
    是不是目前真机的规格就这两种?

    bada的内存管理比较类似c++
    直观
    但是看多了objective c又有些不理解
    比如有些内存并不是显式分配的
    但也需要自己来释放
    比如

    ByteBuffer* pBuf1 = null;
    //Inflate buf from current position to limit of ByteBuffer buf.
    pBuf1 = Inflator::InflateN(buf);
    delete pBuf1;

    工厂模式?

    最后bada还有一个致命的问题
    目前ide只运行在windows平台上
    很不理解
    eclipse没问题 cdt没问题
    不明白
    只得装个虚拟机跑着


  3. mp3 cover fetcher

    五月 13, 2010 by bborn

    mp3 cover fetcher 是android手机上的一个软件
    它可以通过读取mp3的tag信息,查询到mp3所属专辑唱片的封面
    并且下载下来,写入到mp3文件里
    这样 在你的听音乐的时候 播放器里不会再是一片空白
    软件很简单 而且它是免费的!
    在android market里搜索”mp3 cover fetcher”
    更方便的扫描这个qr code
    qr code

    main
    2
    3

    就是这样


  4. Launchy2.5 汉化和修改

    四月 7, 2010 by bborn

    周末从五台山回来 发现launchy2.5的release已经出来了
    于是决定用剩下的一天假期来研究一下汉化和功能修改的事情
    相比上个版本变化不是很大
    除了有更好的性能之外
    看起来都是一些细节的修改
    其实对我来说 2.12就用的很不错了 :)

    首先说说汉化的事情
    新版本在选项窗口多了一点新内容
    如果喜欢用原版 但是又想看中文的话
    下载”launchy_zh.qm”放到安装目录下的”tr”目录下覆盖即可

    我的修改版和以前一样
    主要针对两点
    1. 支持双击双击方式,默认热键是双击ctrl
    2. 支持中文名的拼音查找

    qt虽然是一个跨平台的库
    但是即使同在windows下
    使用不同版本的vc编译出来的qt
    放在一起也不能同时工作
    说白点就是直接拿网上下载的插件回来有可能不能正常工作
    需要在相同的环境下重新编译一下
    我的编译环境是
    VS2008 (没有装sp1)
    Qt libraries 4.6.2 for Windows (VS 2008)

    安装包已经做好
    在这里下载
    http://code.google.com/p/launchy-chinese/downloads/list
    代码同步更新

    *2010.4.8更新,修改了插件的编译属性
    去掉了dll的manifest文件
    如果在dll里嵌入清单的话 需要在当前目录下去寻找运行时库
    而dll和exe不在同一个目录 这时候需要部署两份运行时库
    实际上dll需要的运行时库 exe的manifest文件已经包括了
    所以没必要再嵌入
    之前发现使用/mt可以解决问题 简单的测试也没有问题(在xp虚拟机下)
    今天在win7下测试 release版更新索引时会莫名其妙的crash
    猜想是因为运行时库不一致引起的
    更新后 问题解决


  5. boost::asio::async_read 的一些记录

    十二月 30, 2009 by bborn

    boost中的asio是一个非常好用的网络库
    不过可以参考的资料比较少
    大部分都是靠阅读自带的几个example来理解
    这里记录一下这两天的几个心得

    boost::asio::async_read_until(socket_, response_, “\r\n\r\n”, boost::bind(&shoutcast::handle_read_headers, this, boost::asio::placeholders::error));

    async_read_until, 一直读,直到读到指定的内容.但是了,并不是刚刚读到就停止,一般缓冲区里会有更多的内容,
    所以我们需要读出我们需要的,剩下的留下就好
    官方是这么说的”After a successful async_read_until operation, the streambuf may contain additional data beyond the delimiter. An application will typically leave that data in the streambuf for a subsequent async_read_until operation to examine.”

    boost::asio::async_read(socket_, response_, boost::asio::transfer_at_least(512), boost::bind(&shoutcast::handle_read_content, this, boost::asio::placeholders::error));

    async_read 可以选择使用transfer_at_least 这个CompletionCondition
    async_read 读入的缓冲区可以这样
    boost::array buffer_;
    boost::asio::buffer(buffer_);来构造
    也可以直接用字符数组来构造
    char _buf[512] = {0};
    boost::asio::buffer(_buf, 512);
    也可以用流,更像tcp的方式
    使用boost::asio::streambuf response_;
    它继承自 std::streambuf
    一般这样使用
    std::istream _stream(&response_);
    这里要注意的是 basic_istream::get
    如果我们指定get的个数count,那么取出的个数是count-1
    msdn是这样说的”The fourth function extracts up to _Count – 1 elements and stores them in the array beginning at _Str.”


  6. 改进版的Google 翻译前端

    七月 6, 2009 by bborn

    其实一直对android很感兴趣
    虽然没有用过它的真机…

    上个星期看到了这篇文章
    Android:Google 翻译前端
    作者的代码写的简单明了
    并且发布了源代码给大家学习
    真是很不错

    看了之后 决定动手增加点东西 学习一下android的开发
    增加的内容主要是在查询过程中弹出一个等待的对话框
    涉及到的内容包括 ProgressDialog, AsyncTask
    效果如下
    当用户点击Translate的时候,会出现一个”正在查询”的对话框
    查询完毕后对话框消失

    对话框很好做 showDialog(1) 后
    系统会调用

    @Override
    protected Dialog onCreateDialog(int id) {
    if(1 == id)
    {
    ProgressDialog dialog = new ProgressDialog(GTranslator.this);
    dialog.setTitle(“正在查询”);
    dialog.setMessage(“请稍候……”);
    return dialog;
    }
    return null;
    }

    但是 查询是个阻塞的过程
    我们必须得在另外一个线程里去做这个事情
    比较简单的方法就是继承AsyncTask
    网上有一篇转载比较多的关于AsyncTask的文章(Android线程模型(Painless Threading))
    官方的说明在这里 http://developer.android.com/reference/android/os/AsyncTask.html
    大概说一下 android 的ui线程不是线程安全的
    我们不能在其他的线程里直接做关于ui的操作
    这里有个简单的办法就是继承AsyncTask
    然后实现它的doInBackground方法
    在类的onPreExecute(),publishProgress(Progress…),onPostExecute(Result)方法里
    做ui的操作
    如果在doInBackground里操作ui
    可能会弹出异常提示
    “Only the original thread that created a view hierarchy can touch its views”
    不是每次都弹…为什么了?

    下面贴一下线程的代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    
    	private class ProcessDialogThread extends AsyncTask<String, Void, String> {
    		// @Override
    		protected String doInBackground(String... str) {
     
    			String toTranslateTextString = toTranslateEditText.getText()
    					.toString();
    			String tempString = toTranslateTextString.replace(" ", "%20");
    			fromString = mCountries[fromSpinner.getSelectedItemPosition()];
    			toString = mCountries[toSpinner.getSelectedItemPosition()];
    			String queryString = tempString + "&langpair=" + fromString + "%7C"
    					+ toString;
     
    			return getRawData(queryString);
    		}
     
    		protected void onPreExecute() {
    			showDialog(1);
    			translatedTextView.setText("Connecting...");
    		}
     
    		protected void onPostExecute(String rawData) {
    			dismissDialog(1);
    			if (null != rawData) {
    				String parsedDataString = getData(rawData);
    				if (null == parsedDataString || "" == parsedDataString) {
    					try {
    						translatedTextView.setText("Not found");
    					} catch (Exception e) {
    						e.printStackTrace();
    					}
    				} else {
    					translatedTextView.setText(parsedDataString);
    					dbAdapter.insertItem(toTranslateEditText.getText()
    							.toString(), parsedDataString);
     
    					/*
    					 * FileAccess.writeFile(this,
    					 * toTranslateEditText.getText().toString() + ":" +
    					 * parsedDataString);
    					 */
    				}
    			} else {
    				translatedTextView.setText("Translate failed!");
    			}
    		}
     
    		public String getRawData(String string) {
    			String dataString = null;
    			// String queryString = "hello%20world&langpair=en%7Czh-CN";
    			String queryString = string;
    			try {
    				URL url;
    				if (bAtOffice) {
    					url = new URL("http://10.85.40.153:8000/a.xml");
    				} else {
    					url = new URL(
    							"http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q="
    									+ queryString);
    				}
     
    				URLConnection conn = url.openConnection();
    				conn.connect();
    				BufferedReader reader = new BufferedReader(
    						new InputStreamReader(conn.getInputStream()));
     
    				byte buffer[] = new byte[1024];
     
    				// bis.r
    				String readerString;
    				while ((readerString = reader.readLine()) != null) {
    					dataString += readerString;
    				}
     
    				reader.close();
    				// is.close();
     
    			} catch (IOException e) {
    				System.out.print("Net work error");
    			}
    			return dataString;
    		}
    	}