作者归档:贺 利华

关于贺 利华

正在学习编程,享受编程 热爱文学,闲来读读《读库》 有思想,没理想 正在学会专注

关于虾米小报的一次意外

首先我声明我是虾米的铁杆粉丝和中毒用户!

今天早上来到公司,首先开开浏览器,上虾米,签到看看有没有什么新任务可以做的。首页上倒是没有什么新任务,不过我自己点了一下全部任务,进去的页面让我有点高兴,日常任务里头有两个新的任务,之前还没有见过的,“虾米小报评论沙发”和“上传艺人照片”这两个任务,当时一看上传照片咱们是没有什么希望了,那就抢沙发吧,没想到还真是让我抢到沙发了。点了开始任务之后跳转到了这个页面,赶紧评论吧,呵呵,上图:

按照之前的习惯,如果达成任务的话,我想我应该收到通知,也就是导航条上方的小喇叭会响起来,不过这次我没有看到小喇叭。觉得挺奇怪的,不过我想既然不通知,那么我就直接到任务里头去领奖就是了,谁知等我再次进入任务页面的时候,我还是可以再次领任务,我也以为这个任务可以做多次,那么果断再领咯。再次接受任务,再点击开始任务,便进入到了404页面了。我想这应该是一个Bug吧,遂到给虾米提建议小组中发了一个主题帖,我想这个帖子在还没有被第三者发现的情况下就被虾小米给删了,不过我们还是能看到一些东西的,这个是虾小米删除帖子之后发送到我邮箱中的备份,上图:

虾米内部邮箱内容

网易邮箱中的内容

当然这篇文章并不是为了向虾小米问罪的,我也没有这个分量,只是觉得此次虾米上线“虾米小报”应该是作为一个重磅产品发布的,上线第一天还标明了大大的Beta字样,今天已经去掉了,而是将之前的电台Woo的图标给小报了,那么我想小报也应该能带给我们一种Woo的感觉,不过觉得此次似乎让人有些失望。首先虾虾米给我的回复是“刚刚那个是还没发布的内侧页面呢。呵呵”(侧应该为测,虾小米情急之中打错了),这让我觉得有点不负责任,产品没有得到充分的测试上线并不是一个好好做产品的态度。其次,虾小米将我的“给虾米提建议”小组中的帖子删了让我觉得很费解,因为在删除帖子的同时,虾小米并没有给出解释为什么要删除,而那个站内信的内容原本应该是在小组帖子上进行回复的内容,为何要私自发信呢?这样是不是有一些做错了事情不愿意承担责任,无视用户的感觉呢?首先我只是虾米的一个用户,我因为热爱虾米所以才会非常主动的提交这样的问题到小组,而此次删帖的行为无疑让我觉得虾小米有些敢做不敢当的感觉,也许下次就不会再有这种热情了。其实我一直都是非常喜欢虾米的,至于这样的错误自己在做产品的过程也不是没有犯过,但是并不会这么隐瞒过去,真实地去面对这个问题难道不好吗?难道说小组成员因为看到这个帖子还会故意去刷这个页面吗?让虾米出丑?我想不会,虾米至少还是一个比较单纯的社区。

这同时让我想到了豆瓣电台Android版本的问题,在上周日豆瓣电台Android连续升级了两个版本还是三个版本,为什么呢?我想大家可以去Google Market中看看豆瓣电台的评论就知道了,更新版本之后进入便提示异常程序退出,当时就在评论中写了一些,当然还是本着对互联网优秀应用热爱和珍惜的态度,我点击了给开发者邮件的按钮,给豆瓣的开发人员发了一封邮件,豆瓣的兄弟也很不容易啊,估计当天在加班还是怎么的(时间是周日),下午就给了答复,邮件内容如下,上图:

跟豆瓣开发者之间的邮件

写到这里我不禁有点…,这么优秀的互联网应用在这一段时间中连续让我看到不少的问题,有点失望啊。就在我写这篇文章之时,我再次刷新了虾米的首页,发现有新的任务,但是排序又不对,以前都是以日期逆序排列的,即使所有任务都没有完成也是新任务在最上方显示,而今天出现了排序错误,而CSS样表并没有修改,这就出现了我未完成“你所在的地方温度有多高”这个任务,但是已经给我画上了横线,而我早在几天之前完成的虾米T恤设计任务被排到了最上方,而且没有画上横线,这很显然是排序出错,而CSS保持之前的渲染规则导致的问题。

上图:

虾米任务的排列错误

我想我还能说些什么呢?真的希望虾米的开发人员下次在上线产品之前充分地测试一下自己的产品,如果人手不够,我想虾米里面还是有很多比较乐意做这个志愿者的,不过这个可能涉及到商业上的一些问题,小生只当是妄言罢了。这几日热吵“狗日的”腾讯做了中国最大的山寨等等,我倒是觉得能有腾讯这样负责任的公司来把这些大众化的应用做好了做足了,对于用户来说是件好事,至于说扼杀了业内的小企业创新,我想即使没有腾讯国内团购行业百团大战的情景大家也不是没有看到,我们不缺聪明人也不缺人力,缺的就是创新,这些参与百团大战的小企业们难道不是国内互联网最为直接的写照吗?

即使在这样的环境下,其实我们还是有一些很不错的互联网公司在做着出色的产品,豆瓣和虾米就是其中的佼佼者(小生自认为如此),但是这些佼佼者最近的表现有点…,当然这可能是小问题,不过又有什么问题是大问题呢?

虾米小报?

虾米,我很喜欢的一个互联网应用。

从最早进入虾米到现在,经历虾米的改版挺多的,期间也看到了一些虾米对与虾米改版的意见和微词,更有甚者直接因为虾米的改版而选择了离开。不过对于我个人来讲,虾米的每次改版都带给我的是惊喜,虾米的逐渐成熟让虾米们在虾米越来越自在了。

今天上线,呀….,虾米上了一个Beta功能,虾米小报:

功能尚在Beta之中,不过体验了一把,感觉还是非常不错的。记得虾米第一个线下活动也就是杭州音乐节上线的时候,小组活动开始变得异常活跃了,慢慢的虾米小组就成为了虾米的论坛了,虾米有很多很多的小组,主要以两类小组最为活跃,一是娱乐类,主要以搞笑和投票调查为主;二是资讯类,主要以各种与音乐相关的活动的现场报道等。

但是由于虾米的一些限制,发图在虾米是比较麻烦的,而且小组毕竟是一个小众的东西,要求用户UGC的热情较高,主动性要求更强,很多时候传播率还是不够。然而以小报的形式来出现,就是一个媒体展示,更是将诸多散落在各个小组的UGC掌门人集结到了一起。

届时虾米集结号一响起,天下无不赢粮而影从,诸多大虾将从各个音乐节,各个颁奖晚会上给我们带来最为直接和草根的报道,虽然现在虾米还未开放上图功能,不过我相信未来肯定会开放的,至少优先开放给小报板块,因为这个商机实在是太大了,完全的UGC,通过虾米的Digg功能,将高品质的内容展现给用户,我想这应该是一个很不错的设想吧呵呵。

上个图,留个念:

“狗日的”的腾讯?

这两天估计在互联网圈子里头较为热的一个词就是这个了,当然还有我们男性同胞人见人爱的ChinaJoy的众多ShowGirl大阅兵啦。

来看看这张杯具的图吧,微博中已经成为“河蟹”的笑料了,甚至有童鞋强烈要求腾讯推出QQ正腐,并推出QQ公安、QQ拆迁办和QQ发改委进行系列配套。当然这是一些个戏谑和调侃的文字,这些个童鞋虽然是在调侃QQ,但是他们在调侃之时,尚在享受着QQ提供给大家的服务。这难道就是传说中的亦爱亦恨?我想作为一个互联网从业人士,每个人都曾是QQ的中毒用户,甚至至今依然会有很多QQ的铁杆粉丝,当然大家同吃一碗饭,难免会有利益之纷争,有道是只有“永恒的利益”啊。就在昨天通过“狗日的”腾讯 搅局者还是终结者?才算是了解到了腾讯这些年来的诸多业务转型,以及腾讯旗下小游戏主题站3366.com。

作为一个QQ的非中毒用户,绝对腾讯粉丝的我来说,我对于QQ这个聊天工具一直没有太大的感觉,因为自己聊天的需求非常之小,跟同学聊天一般都是直接电话聊,其他时间偶尔上上QQ也就是碰碰同学等等,对于IM工具,从易用性上来讲,QQ绝对是世界一流的。虽然自身对于QQ没有什么依赖,不过对于腾讯其他的产品体验得不少,从最早的QZone开始,我认为QZone就是一个垃圾,不过现在变得好多了,到之后QQ音乐,再到后来的QQ医生,再到QQ Live,这些个产品都曾深入体验过,给我的感觉是从2006年开始,腾讯整体的产品设计上开始统一起来,产品的设计性较功能性更强,同类的产品中,我们随口就能说出很多个来,但是当你真正安装上开始使用的时候,你就会发现其实QQ系列产品在功能之外做了很多的功课,对于产品易用性以及UI的友好性上面尤其花功夫。

不过从QQ这样“一直在模仿,从未被超越的”的形态来看,这对于国内诸多互联网初创公司来说确实不是一个很好的消息,特别是之前看到有人说到国内创业环境跟美国的不同,硅谷的企业之间有一个不成文的规定,大企业不抄袭小企业的产品和模式,如何涉足一般选择直接收购,在收购产品和专利的同时将优秀的人才收入囊中,这对于初创企业来讲,其实是一件非常有利的事情,不用担心哪天那个大灰狼直接跑到你家中实施暴行,还满嘴仁义的说“其实我们只是打酱油的”。去你妈的,什么玩意儿啊?

[pullquote]“有什么业务是腾讯不做的吗?”美团网CEO王兴的语气中难掩郁闷。[/pullquote]

我想中国互联网创新的先锋人士(同时也是互联网山寨人士)王兴老大哥在饭否关闭之后,重新创业瞬间引得团购业里,天下赢粮而影从,引多少英雄竞折腰啊。可惜我们可爱又可恨的小企鹅又一次露出了他那淫邪的笑容,那么这次谁又会笑到最后呢?我想大量蛋疼的QQ用户,能给腾讯带来的不会少吧。届时大家应该就能看到某个办公室里头,坐着一队人,看着屏幕上的小企鹅,不停的刷团购信息,蛋疼得紧啊。

《黄金矿工喜讯特别版》发布了

从加入喜讯到今天整整两个月了,期间做了一个小产品,就是《黄金矿工喜讯特别版》。

游戏的创意来源于PC上flash版本的黄金矿工,不过重新结构了游戏的可玩性和关卡的设置,并新增了一些游戏模式的东西,加入了更多的设计性的要素,特别是画面感的增强,我个人认为应该是最大的。游戏发布并没有正式的在Google的Market上发布,只是选择性的在国内的一些知名的论坛上发了一些帖子。效果还算不错,在安卓网上的帖子,下载量已经达到了1383,在机锋网的帖子 下载量目前是874,感觉都还不错,然后今天下午放上了安卓市场里面,目前下载量是141,感觉还不错。跟之前自己的预期相比,目前的结果还是比较喜人的。

官方网址是:http://m.xixun.com/hjkg

目前提供了Android和Symbian版本,支持Android 1.5及以上版本和S60 V3版本

给一些截图吧:

下载地址: http://m.xixun.com/hjkg

Android上如何正确实现程序的联网,事关WIFI/CMWAP/CMNET

我想很多Android程序开发者都曾碰到过这样的问题,那就是如何让自己的程序在国内如此复杂的网络环境下顺利的接上网络,给我们的用户一个更好的体验。
从网络上一些已有的数据来看,Android手机用户群体的联网率普遍比较高,联网的方式非常多样,最多的还是使用WIFI,当然WIFI速度和资费上的优势让她成为了每一个玩机者的首选网络接入方式,但是很多的时候我们的条件并不是那么的尽如人意。例如在公车或地铁上,我们这些诸多支付不起3G资费的人士,首选的接入方式依然是CMWAP/CMNET,而由于国内网络的一些个问题,选择这两个或者其他的APN会有一些问题,问题就是我们可能需要设置代理才可以顺利登录网络。

以下是我自己在网络上寻找解决方案的时候,收集的一些信息,记录如下:

WAP是一中手机上网的协议。CTWAP是中国电信的WAP接入名称(China Telecom WAP),CMWAP是中国移动的WAP接入名称(China Mobile WAP),  UNIWAP是联通的WAP接入名称(china Unicom WAP),  另外CTNET/CMNET/UNINET同上。
CTWAP的上网网关:10.0.0.200:80
CMWAP的上网网关:10.0.0.172:80
UNIWAP使用的网关与CMWAP一致
我们可以通过MCC+MNC码的方式来进行简单的判断,但是实际上这种方式并不是完全正确的方法(自己在项目上碰到了该问题,因为实际情况中我们总是需要面对多种网络的情况)。这个时候其实我们可以稍微Hack一下,虽然Android并没有提供非常好的API,不过我们可以通过一些方法绕过去这里有一篇非常不错的文章http://www.javaeye.com/topic/565662 ,讲解得还算全面。
下面给出我自己的解决方案:
WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
  HttpClient httpClient = new DefaultHttpClient();
  if(!wifiManager.isWifiEnabled()){
   Uri uri = Uri.parse("content://telephony/carriers/preferapn"); //获取当前正在使用的APN接入点
   Cursor mCursor = this.getContentResolver().query(uri, null, null, null, null);
   if(mCursor != null){
    mCursor.moveToNext(); //游标移至第一条记录,当然也只有一条
    String proxyStr = mCursor.getString(mCursor.getColumnIndex("proxy"));
    if(proxyStr != null && proxyStr.trim().length() > 0){
     HttpHost proxy = new HttpHost(proxyStr, 80);
     httpClient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
    }
   }
  }
  HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), 20 * 1000);
        HttpConnectionParams.setSoTimeout(httpClient.getParams(), 20 * 1000);
        HttpGet httpGet = new HttpGet(wrapGetUrl());
 try
        {
            HttpResponse response =httpClient.execute(httpGet);
            if(response.getStatusLine().getStatusCode() == 200){
             HttpEntity entity = response.getEntity();
             InputStream content = entity.getContent();
             BufferedInputStream bis = new BufferedInputStream(content);
             StringBuilder builder = new StringBuilder();
             int b;
             while((b=bis.read()) != -1){
              builder.append((char)b);
             }
             String resultStr = builder.toString();
               Log.v("result", resultStr);
}catch(Exception e){
}finally{
httpClient.getConnectionManager().shutdown();
}
该方案在打开WIFI/CMWAP/CMNET的情况下均单独测试成功。
同理HttpPost也可以如法炮制,下面附上一段代码:
int version = 3;
  Class versionClass = VERSION.class;
  TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
  WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
  String manufacturer = "";
  String device = "";
  String networkOperatorName = tm.getNetworkOperatorName();
  String IMEI = tm.getDeviceId();
  try {
   Field field = versionClass.getField("SDK_INT");
   version = (Integer) field.get(new VERSION());
   Class buildClass = Build.class;
   Field manu_field = buildClass.getField("MANUFACTURER");
   manufacturer = (String) manu_field.get(new android.os.Build()) + " ";
   Field deviceField = buildClass.getField("DEVICE");
   device = (String) deviceField.get(new Build());
  } catch (Exception e) {

  }
  HttpClient httpclient = new DefaultHttpClient();
  try {
   if(!wifiManager.isWifiEnabled()){
    Uri uri = Uri.parse("content://telephony/carriers/preferapn");
    Cursor mCursor = this.getContentResolver().query(uri, null, null, null, null);
    if(mCursor != null){
     mCursor.moveToNext();
     String proxyStr = mCursor.getString(mCursor.getColumnIndex("proxy"));
     if(proxyStr != null && proxyStr.trim().length() > 0){
      HttpHost proxy = new HttpHost(proxyStr, 80);
      httpclient.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
     }
    }
   }
   HttpConnectionParams.setConnectionTimeout(httpclient.getParams(), 20 * 1000);
            HttpConnectionParams.setSoTimeout(httpclient.getParams(), 20 * 1000);
   HttpPost httppost = new HttpPost("YOUR_POST_URL");
   List nameValuePairs = new ArrayList();
   nameValuePairs.add(new BasicNameValuePair("os", "Android"));
   nameValuePairs.add(new BasicNameValuePair("os_version",String.valueOf(version)));
   nameValuePairs.add(new BasicNameValuePair("device", manufacturer+device));
   nameValuePairs.add(new BasicNameValuePair("uuid", md5(IMEI)));
   nameValuePairs.add(new BasicNameValuePair("network", networkOperatorName));
   httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8));
   HttpResponse response;
   response = httpclient.execute(httppost);
   httpclient.execute(httppost);
   StatusLine statusLine = response.getStatusLine();
   if(statusLine.getStatusCode() == 200){
Toast.makeText(this, R.string.updatesucceed, Toast.LENGTH_SHORT).show();
   }else{
Toast.makeText(this, R.string.updatefailed, Toast.LENGTH_SHORT).show();
   }
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  } catch (ClientProtocolException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }finally{
   updateFlag = true;
   httpclient.getConnectionManager().shutdown();
  }