蓝色魔法

蓝色的魔法,永恒的世界.

IM垄断问题到底如何解决.

八月13

前言:以国内IM大亨QQ为例

IM,即时通讯软件的简称, 现在已是几乎所有网民无法离开的东西. 在中国IM的代言就是QQ, QQ拥有在中国IM市场的绝对占有率. 其实在国外IM类软件市场也差不多. 还是回到国内, 想打败QQ的人几乎天天有, Baidu, MSN, 旺旺等等. 但是他们没有一个能撼动QQ的垄断位置,  曾几何时看到QQ为了对付其他IM而改变? QQ作为一个山寨王唯一一个不山寨别人的就是QQ本身, 因为完全没有必要, 因为再好的功能也无法拖走QQ用户.

寻根: 问题到底出在哪?

那么到底是什么让QQ如此强大,  其实这要说到IM的本性. 既然是通讯那么通讯至少需要2个或以上的人才能称之为通讯. 而如何评价通讯的好还呢? 其一是通讯质量, 当然如今的宽度对以几人甚至几十人的多放通讯已经搓搓有余. 其二也是最关键的一点就是用户.  一个人的黄金对讲机有何用? 而QQ则是利用了这一点. QQ深知用户绝对不可能放弃QQ跑去用一个只能和自己聊的即时通讯软件. 要让一个QQ用户放弃QQ改用其他IM唯一的方法就是把他所有的朋友一起拉走, 但是朋友也有朋友那么你也需要把它们也一起拉走但是他们还有朋友, 结果可想而知, 你几乎需要把所有QQ用户一起拉走才有可能从QQ身上抢走一个用户. 当然这也是不现实的事情. 再加上通常用户不喜欢同时开多个IM, 所以只要QQ不比同行差上几条街, 用户还是愿意待在QQ那. 就像如果我告诉你如果你转来某某电话公司, 我只收你一半的价格, 但是你将无法打通非本公司的电话你还愿意转吗?

解决之道: 一个平台.

既然了解了根源问题, 那么离开解决问题的方法也不远了. 不过在此之前我们先说一下错误的解决方法. 很多人认为对付QQ垄断的方法就是力挺其他IM公司, 让他们的市场占有率可以和QQ平起平坐那么我们用户就可以利用市场竞争来坐收渔利. 我可以很负责人的告诉你, 这方方法有2个结果而这2个结果都是失败. 结果一, 市场出现3-4家IM公司, 他们都拥有差不多的市场占有率, 那么用户从垄断的受害者变为竞争的受害者, 你会发现你每天需要开3-4个IM来和你的朋友亲戚保持联系. 用户当然不可能忍受这样的痛苦, 那么我们进入结果二. 结果二, 其中一家做的最好的IM公司会重新占领市场, 于是一个新的QQ出现了, 我们又回到了原点.  说了错误的方法我们回到一个最为合理的解决方案, 一个开发的通信平台. 何谓一个开发的通信平台, 一个开发的通信平台就是一个所有人都可以为其开发但是又要遵守其通信规则, 这样所有人都可以正常的通信. 我们应该有这套类似IEEE这样的通信标准, 然后由一个国际性的非盈利组织管理,  所有的IM制造商应该按照其规则通信, 这样任何人都可以做一个可以和全世界通信的IM软件. 这个平台应该是绝对开发和非盈利性的. 这样的好处是没有人可以像QQ这样靠把用户绑在一起无法移动来保住自己垄断的地位. 因为如果用户不喜欢你的IM他们可以随时转去另一个, 而他们还是可以和往常一样和其家人通信联系.

实施:艰难的第一步.

解决方法虽然是有了, 但是实施起来却非常困难, 因为最大的难关还是在我们眼前, 如何让用户走出正确第一步? 正如我之前所说的QQ把用户都绑在了一起如何让他们松绑才是关键, 当然我们可以发动群众的力量不过那也非常困难. 也许我们该借助政府强制让QQ走下神坛, 主动加入上面提到的开发的平台.

结局:美好的未来.

虽然前方的路很远很困难, 但是相信我们的未来是美好, 是一个自由的未来. 再次我呼吁”还我们一个自由的IM.”

苹果,我们到底该不该爱?

六月17

    从iPod开始苹果一炮而红, 从2流科技公司一下子超越微软成为世界第一大科技公司. 说到苹果的成就不得不说iPhone, 作为一个Android开发者说实话我也曾想过去为iOS开发, 可是却始终无法实现. 主要原因是开发苹果必须要在Mac OS上进行. 作为一个大众化的Windows用户我让我特地花钱去买台Mac主机实在不现实, 当然Windows上可以虚拟MacOS但是看着这长长几页的教材我就放弃了. 并不是我做不到而是我觉得作为一个程序员应该花时间在开发程序上而不是搭建开发平台上.
    这是我的小小故事我们回到主题上, 苹果到底该不该爱, 我们可以看看苹果的市场战略和思想. 先从iOS开始说, 首先我们知道iOS只能运行在自家的硬件平台上(iPhone,iPad), 苹果不想也不让其他硬件平台运行iOS, 也就是说如果你喜欢苹果的那么苹果专卖店是你唯一的去处. 从这里我们基本可以看出苹果的市场战略. 苹果不会让外人占了自己的便宜, 任何苹果产的硬件只能跑自己的OS而苹果的OS也只能在自家的硬件上跑. MacOS从来不会对兼容其他机器硬件做更新可以证明我的观点, 而iOS则是把这点做到了极致, 因为它不单单把其他硬件排除在外甚至用条款把Adobe,Admob等软件也踢出了iOS. 综上所说苹果的市场战略是极度封闭的, 他不愿意和任何人合作, 也不会给任何人便宜. 如果你爱苹果那么你将失去选择的权利. 当然如果你对只买苹果视为专一的表现而你的爱又可以至死不渝那么苹果是不错的选择, 而事实上苹果的产品的性价比比同类低很多说明这份爱的代价还真不小.
    总的来说, 爱苹果真的不容易. 爱上苹果会让你失去整个森林, 也许现在这颗苹果是绚丽的但是这个绚丽能持续多久呢? 而在欣赏苹果的绚丽的同时你又失去了什么呢?

Android软件开发中的一些心得和经验.

六月3

很多时候要通过JAVA Code来改变XML中View的各种属性, 例如seText, setVisibility等. 通常我们用findViewById去获取View, 要注意的是findViewById不可以放在OnCreat或setContentView之前, 例如 private Button btnAct= (Button) findViewById(R.id.btnToSBoard); 会出现空指针的错误. 因为在setContentView之前XML还没有被载入, 所以自然就无法找到你要找的View.

解决方法也很简单你可以用private Button btnAct然后在setContentView之后btnAct = (Button) findViewById(R.id.btnToSBoard);

onTouch事件中, 不包括点击按钮拖动进度条条等View操作

一个简单的为英文数字加上suffix的函数.

六月3

通常用到数字排名的时候需要为数字后加上后缀,让3变成第三.

后缀规则很简单, 1结尾的+st,2结尾+nd,3结尾+rd, 其他+th, 特别情况是11,12,13都为+th.

下面是简单的java代码, 输入数字输出数字加后缀

public String suffix(int num) {
// Handle special case 11,12,13
if (num == 11 || num == 12 || num == 13)
return num+”th”;
switch (num % 10) {
case 1:
return num+”st”;
case 2:
return num+”nd”;
case 3:
return num+”rd”;
default:
return num+”th”;
}
}

Android对于ListView拖动时变黑问题解决方法.

五月7

最近用ListView显示一些String数据, 不过发现如果不按住文字部分拖动ListView一切安好, 但是如果按住文字部分拖动的话所有文字部分都会变黑.

解决方法其实很简单, 问题的根源在于缓存颜色. 只要在ListView中加入以下属性即可.

android:cacheColorHint=”#00000000″

Android中写入读取XML的简单实例示范.

五月1

package test.xml;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xmlpull.v1.XmlSerializer;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.util.Xml;
import android.widget.TextView;

public class xml extends Activity {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  Write(“test.xml”, writeXml());
  
  TextView tv = (TextView) findViewById(R.id.tv);
  tv.setText(ReadXML());
 }

 private String writeXml() {
  XmlSerializer serializer = Xml.newSerializer();
  StringWriter writer = new StringWriter();
  try {
   serializer.setOutput(writer);

   // <?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
   serializer.startDocument(“UTF-8″, true);
   // <blog number=”1″>
   serializer.startTag(“”, “blog”);
   serializer.attribute(“”, “number”, String.valueOf(1));

   // <message data=”2009-09-23″>
   serializer.startTag(“”, “message”);
   serializer.attribute(“”, “date”, “2009-09-23″);

   // <title>Android XML</title>
   serializer.startTag(“”, “title”);
   serializer.text(“Android XML”);
   serializer.endTag(“”, “title”);

   // <url>http://www.moandroid.com/?p=508</url>
   serializer.startTag(“”, “url”);
   serializer.text(“http://www.cunynova.com”);
   serializer.endTag(“”, “url”);

   // </message>
   serializer.endTag(“”, “message”);
   // </blog>
   serializer.endTag(“”, “blog”);
   serializer.endDocument();
   return writer.toString();
  } catch (Exception e) {
   throw new RuntimeException(e);
  }
 }

 public boolean Write(String path, String txt) {
  try {
   OutputStream os = openFileOutput(path, MODE_PRIVATE);
   OutputStreamWriter osw = new OutputStreamWriter(os);
   osw.write(txt);
   osw.close();
   os.close();
  } catch (FileNotFoundException e) {
   return false;
  } catch (IOException e) {
   return false;
  }
  return true;
 }

 private String ReadXML() {
  String re = “123″;
  DocumentBuilderFactory docBuilderFactory = null;
  DocumentBuilder docBuilder = null;
  Document doc = null;
  try {
   docBuilderFactory = DocumentBuilderFactory.newInstance();
   docBuilder = docBuilderFactory.newDocumentBuilder();
   // xml file 放到 assets目录中的
   doc = docBuilder.parse(this.openFileInput(“test.xml”));
   // root element
   Element root = doc.getDocumentElement();
   // Do something here
   // get a NodeList by tagname
   NodeList nodeList = root.getElementsByTagName(“blog”);
   Node nd = nodeList.item(0);
   re = nd.getFirstChild().getFirstChild().getNodeValue();
  // re = getAttributes().getNamedItem(“number”).getNodeValue();
  } catch (ParserConfigurationException e) {
   e.printStackTrace();
  } catch (SAXException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   doc = null;
   docBuilder = null;
   docBuilderFactory = null;
  }
  return re;
 }

}

打开Android开发之门.

三月28

前段时间才刚刚开始用C#开发了些Windows Mobile的软件, 但是不久后就发现Windows Phone 7完全改变了, 就连开发方式都变了. 现在WM没有任何开发前途, 而WP7却还没出来, 完全陷入了两难的境地. 不过就在这时我做出了选择, 选择就是完全放弃WP平台. 鉴于本人对IPhone没什么好感, 而且加上IPhone开发还需要用MAC系统的麻烦, 于是乎自热而然的转到了Android阵营. 似乎是天意, 这学期学的事JAVA, Android也是用JAVA算是对了口.

不过以后的路还很长, 而且最主要的是我现在都还没Android的手机, 只能靠模拟器测试. 希望I900能够跑Android.

如何合理的管理你的密码.

二月25

对于密码大家不可能不知道, 密码几乎无处不在. 从Windows登入,到QQ,邮箱,网银等等都要用到密码, 如何合理管理这些密码呢? 这里教大家一些心得.

如何设置一个较为安全的密码其实网上也有很多了, 我这先要说的是如何管理密码. 让你为每个需要登入的地方都单独设置密码显然不显示, 但是还是有很好的替代方法的.

首先我们需要3套密码, 按长度分为顶级,中级和低级. 然后给不同的安全需要进行分类.

低级密码: 也就是你最常用最好记的密码, 这套密码可以设置给论坛,网盘等服务. 这个分类里的东西是那些就算被盗了也不会有太大损失的东西. 这个密码绝对不要用于任何常用的邮箱,和网银等重要服务. 

中级密码: 这个密码可以给予一些较为重要的东西, 例如QQ,邮箱等.

高级密码: 这个密码给予最高级安全需要的东西, 例如网银, 支付宝等.

绝对不能做的傻事:

  1. 邮箱密码绝对不能和网银或者QQ密码一样, 特别是和网银挂钩的邮箱. 这个我是有血的教训的…
  2. 如果有多个邮箱密码也不能相同.
  3. 不要随便用中级密码在不明网站注册, 如果你对网站不了解不要用中级以上密码去注册, 就是你觉得你将要注册的服务对你很重要, 请先用一个其他密码然后用纸写下来. (不要记录在电脑里.) 这里的原因很简单, 万一你注册的网址的管理员别有用心, 没用MD5加密你的注册密码, 那么很容易就知道你的中级密码了, 而且你注册时候几乎必填邮箱, 是不? 而且你的邮箱也用的是中级密码,对不? 那么结果也就不用说了.

加强密码强度:

  1. 密码不设为任何连续的数字或者英文. 例如12345,abcd, 甚至是13579都不要去用. 对于暴力破解来说这些组合是优先尝试的.
  2. 密码不要设成和生日或者电话号码. 生日和电话号码很多时候都是公开的. 当然你可以加入生日到密码组合中, 例如你可以用你生日的年加上父母的月加上子女的日等等. 就是如此本人还是不推荐把生日或电话号码放进密码中.
  3. 如果支持尽量在密码中加入特殊字符, 什么事特殊字符就不用我说了吧”@#$%^&*()” 只要服务器支持加入1个特殊字符都能让你的密码破解难度高几倍. 为什么呢? 我们用简单是数学就知道, 英文52个+10个数字. 一共是62个.  1个5位数的密码可用拥有62^5种组合, 但是如果算入特殊字符…特殊字字符有多少我不清楚, 但是这个数字大于100, 也就是说同样5为组合加入特殊字符后的组合数量是162+^5总组合. 而且一般暴力破解不会加入特殊字符因为实在太多了.
  4. 密码模板: 如果你不善于记住密码, 那么密码模板是非常好的方法. 什么是密码模板? 举个很简单的例子,  Ok#ole+”网址前三位”+门牌号码. 我们来分析一下这个模板, 签名的Ok#ole是不变的普通字符, 也就是你需要记住的(不多吧?),然后”网址前三位”是你用这个密码网址的前三位(当然不包括www.). 如果是QQ.com那么就是qqc,如果是hotmail那么就是hot等. 最后门牌号码就不用说了吧? 这样假如你登入gmail而且你住在603室那么你密码为Ok#olegma603,而qq的密码为Ok#oleqqc603这个密码长度够了, 难度也够了. 这样的密码如果被盗一个就算盗号者IQ再高没模板也无法破解你的其他的密码.  这样的好处很明显, 你需要记住的就是不变的字符(少量)和模板就可以了, 就算某个网站的密码被人盗取, 也不会影响到其他. 这样既不用为每一个网站记住一个单独的密码又可以让他们独立开来. 如果你想更安全那么把模板设置的更复杂就好啦.

结语,  有人说没有100%安全的密码, 说的没错但是如果你能做到99.99%安全再加0.01的运气不就100%了吗? 希望大家都能安安全全,开开心心的度过虎年哦~

一个3DsMax作品,IPOD.

十二月26

由于是第一次用3DsMax花了好几个小时,去熟悉软件, 看教程, 找答案等等. 好辛苦, 不过做完后还是很有成就感的. 再辛苦都值了!!

作品奉上:

ipod with 3dsMax

Windows Phone从6.5.1看将来!

十月27

Windows Mobile 6.5 正式版的到来不但让我们看到了Windows Mobile 美丽的UI, 也让我们看到了Windows Mobile 美丽的将来. 从Windows Mobile 6.5开始微软正式命名Windows Mobile为Windows Phone. 这次的命名不看看只是一次简单的命名, 微软的这一动作让我们看到了微软对Windows Phone的承诺.

就在6.5发布不久我们迎来的6.5.1. 这次更新来的很突然也很革命化. 6.5.1中把开始按钮放到了屏幕下方. 对微软这样的巨人公司做出如此举动其实是很大的变化. 也许一般人觉得这没什么了不起, 我用的软件UI天天都有翻天覆地的变化, 有些人甚至觉得这次的改动是多此一举, 其实不然, 要知道Windows Phone从第一代开始就是把开始按钮放在最上面的, 无论如何改变那个神圣的左上角永远坐着开始按钮, 突然做出改动是很冒险的, 看看塞班, 或者PC上的OS, 有几个拥有大量用户的OS会突然之间对自己的UI做出巨大改变的? 为什么没有人敢怎么做, 原因很简单, 用户是懒惰的, 要让用户来适应改变很有可能造成用户反感和抵抗, 所以所有的OS巨头们都一成不变的最大化保留其UI原样而只小心翼翼的做一些简单的修改和美化. 但是客观来看5年甚至10年前设计的UI真的是有太多的缺点了. Windows Phone这次改变让我们看到了微软的决心. 微软要改变Windows Phone, 让Windows Phone变得更人性化. 从实际来看, 用户操作手机时手指自然而然的是在手机下方, 而把开始按钮放到下方不但减少了用户按次按钮的距离而且避免了了很多时候按了菜单后还要把手指移开才能看到出来了什么. 其实手机屏幕的左上和右上角都是非常不适宜放按钮的地方而开始按钮也是时候给用户让让位了.  微软这次对Windows Phone的改变虽然看似简单但是意义深刻, 相信将来还会有更多的大刀阔斧的改变. 让Windows Phone更人性化,更好用.

最后我想提出一些自己的看法, 首先虽然把开始放下去是很不错的想法然后关闭/最小化按钮也下去了, 接着问题来了, 下方是不是太拥挤了? 很多时候左右软按钮的内容都无法完全显示, 虽然微软通过简化输入法按钮来给软按键腾位置, 但是还是捉襟见肘. 当然现在的方法是开发者们可以尽量的缩短字符来适应新UI但是毕竟有些时候文字太少会为用户带来理解上的麻烦. 我的看法是吧输入法按钮去掉, 首先下方栏是黄金宝地, 离开手指最新, 操作最方便可谓是寸土寸金, 而输入法按钮其实使用频率并不高. 一般需要输入键盘的时候都会自动弹出, 例如发短信, 当用户点击文本框的是输入法自然而然的弹出, 当用户点击发送时输入键盘自动隐藏, 一次完整的操作完全用不到输入法按钮. 所以完全可以去除输入法按钮给软按钮让位. 当然也有特殊情况用户需要显示输入键盘但是却没有自动弹出触发, 例如下拉列表里快速定位到某字母, 所以也不能就简单的去处输入法键盘. 而输入法键盘的去处有很多, 例如可以集成到开始按键上, 例如长按开始按钮,或者双击等, 也可以放到上方任务栏等, 不过有个比较理想的方法是有用手势代替, 在任何时候当用户用手指在屏幕下方30%内从左向右滑动就可以把输入法键盘从左边调出, 而从右相左滑动则可以调出另外一个输入法键盘. 这样的解决方案不但解决了输入法键盘的去处还可以多语言用户提供了极大的方便, 例如左向右滑拉出英文键盘, 反之则为中文.

Windows Phone还有很远的路要做, 很多改进要做, 希望这次6.5.1的改动是以后千千万万改动的开始, 同时也希望WP越做越好.

« Older Entries