蓝色魔法

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

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.”

做Mobile手机网页的缩放问题.

八月11

在做手机网页的时候会遇到缩放问题,  你可能希望限制用户使用缩放功能. 其实实现起来非常简单简单一行代码而已.

<meta name=”viewport” content=”width=device-width, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no”/>

把这个meta信息加入head中就可以了.  主要语句是

minimum-scale=1.0, maximum-scale=1.0,user-scalable=no”

限制了最小和最大缩放为1.0也就是100%最后关闭了自定义缩放.

要注意的是如果你锁定了缩放请务必注意站点的字体图片大小, 因为如果太大和太小都会造成用户浏览困难, 并且用户无法改变到适合的大小.

“Dream as if you’ll live forever, live as if you’ll die today”

六月19

让我们做伟大的梦,做眼前的事.

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

六月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”;
}
}

耐心等待, 等待NexusOne降价就出手!

五月25

耐心,耐心,耐心.

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.

« Older Entries