‘编程学习’ 分类下的所有文章
20115 月13

杯具程序员

上联:为系统而生,为框架而死,为debug奋斗一辈子。 下联:吃符号的亏,上大小写的当,最后死在需求上! 横批:杯具程序员。

20115 月4

Android 手机端与服务端POST数据交互类

 

package com.wizzer.tools;

import java.io.*;
import java.net.URLEncoder;

import java.util.*;

import org.apache.http.HttpResponse;

import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.NameValuePair;
import org.json.JSONArray;
import org.json.JSONException;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;

public class BaseProtocol 
{
    private StringBuilder sb = new StringBuilder();
    private HttpClient httpClient;
    private HttpPost httpRequest;
    private HttpResponse response;
    private List nameValuePair = new ArrayList();
    private static final int DIALOG1_KEY = 0;
    private static final int DIALOG2_KEY = 1;

    public BaseProtocol()
    {
        httpClient = new DefaultHttpClient();
    }

    /**
     * *向服务器端发送请求 * *@paramurl *@throwsException
     * 
     * @throws UnsupportedEncodingException
     */
    public void pack(String url) throws Exception
    {
        httpClient = new DefaultHttpClient();
        httpRequest = new HttpPost(url);
        httpRequest.setEntity(new UrlEncodedFormEntity(nameValuePair));
        response = httpClient.execute(httpRequest);
    }

    /** *得到返回数据 * *@paramurl *@return *@throwsException */

    public String parse() throws Exception
    {
        // TODO状态处理500200
        if (response.getStatusLine().getStatusCode() == 200)
        {
            BufferedReader bufferedReader2 = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            for (String s = bufferedReader2.readLine(); s != null; s = bufferedReader2.readLine())
            {
                sb.append(s);
            }
        }
        return sb.toString();
    }

    /***
     * 向服务器发送信息 * *@paramkey *@paramvalue
     * 
     * @throws UnsupportedEncodingException
     */
    public void addNameValuePair(String key, String value) throws UnsupportedEncodingException
    {
        nameValuePair.add(new BasicNameValuePair(key, URLEncoder.encode(value, HTTP.UTF_8)));
    }

    /** *返回JSONArray对象数据模型 * *@return *@throwsJSONException */

    public JSONArray getJSON() throws JSONException
    {
        return new JSONArray(sb.toString());
    }

}
20115 月4

合肥 Android/Java开发交流群:26310065

手机开发:WM、Android、iOS WEB开发:Java、.NET、ASP、PHP、JSP 应用开发:C#、JAVA……

欢迎IT从业人士加入,交流开发经验、技术,项目外包等信息。 QQ群:26310065

20114 月8

告别程序员生涯,一点感慨与诸君共勉

再过几天,我就正式告别程序员生涯了,这也是我最后一次以职业程序员身份在CSDN发表文章。小弟谈谈入行几年来的感受,做一个人生阶段的自我总结,同时希望能给后来者带来点参考意见,能在这段路上走的更好。

本人2002年下半年正式入行,至今2007年4月一直从事软件开发工作。

上大学选择这个专业是阴差阳错,但接触之后对计算机产生了强烈的兴趣,对写软件有一种强烈的冲动。软件成型后,那种成就感和自豪感能给我难以名状的满足。

那时,喜欢看侯捷的书,对核心技术和核心技术人员由衷的崇拜,对技术的追求和水平的提高有一种莫名的狂热,当时我想只要能从事软件开发的工作,起初的薪金待遇可以不计,等我技术方面成熟后,自己就有更高更好的选择了,程序员-系统分析-项目经理-自己的软件公司,这是当时我一个朦胧的程序人生规划。

现在想来,不禁一番唏嘘。

我记得我在培训的时候,一个培训的老师当时是本地一家有名的高科技企业的CTO,确实是专业人才,就是不太会讲课。我问他做程序员的感受,他说经常写程序经常写到凌晨2点钟,很累不过很有意思,因为他喜欢这份职业(当然喜欢啊,他月薪7000-8000,2001年,济南),但也干不长啊,他已经做好了转行的准备,去做和计算机相关的行业。那年他28岁,我22岁。其实他那番话让我和我的同学已经很羡慕,我们羡慕他的技术深度和现在的岗位层次,金领啊,他就是我们眼里的金领啊。

而另一个技术水平很高的老师(在外企写单片机的,30岁,月薪8000-1万),告诉我的是:迟早要转行,就像他现在来当培训教师一样,原因:太累。

我没在乎他们的感慨,因为我年轻啊,加班到夜里2点很轻松啊,何况写写自己喜欢的软件,很高兴啊。30岁那时对我来说只是一个遥远的数字。工作后,感觉完全不一样了。首先很惭愧自己的机遇和能力都不是太好,一直从事基于数据库的信息管理系统的开发(我认为是软件开发里最简单和最基础的方面),换了三家公司,从基础程序员作到了系统分析的层次,现在开始往对外和管理方面发展。可以说粗略的沿着我以前设计的程序人生轨迹走了走。

其间也有过失业的落魄,吃不上饭的紧张,我记的最难的时候到CSDN上来发表文章,得到了很多兄弟姐妹的祝福和支持,给了我很大的鼓励,真的谢谢。

我今年28岁,未婚,彻底烦了。为什么?累;没有希望。先说说我的一点感悟。

软件行业分析: 1、开发出售行业适用的单机版软件。 2、开发行业适用的网络版(B/S)软件,一般是大单,几十万到几百万。 3、和行业的政府主管部门合作,推行一些行业方面的应用软件。 补充:做软件一定要做行业软件,才有前途。

这是本人几年来对这个行业的一点分析。

其实第一种情况是软件公司最通常的盈利模式,这种模式软件价格不高,但只要质量站得住脚,可以细水长流,保证公司的成本没问题,做的好还可以盈利不少,但想做大公司很难。

第二种情况,是真正挣钱的情况,接一个大单,什么钱都挣出来了。可以锻炼开发队伍,建立完整的大的开发框架,而且在这个行业里可以造成很大影响,在一个地方实施成功后可以低成本的再推广,占领一片市场。总之一句话可以让一个小公司真正的成长起来。

第三种情况纯粹就是敛财了,和主管部门合作,强行推广软件,绝对的只赚不赔,我想各个地区都有这样的案例,如税务方面的。缺点是这样的公司都受地域性限制,老板钱拿的太舒服,没什么上进心,公司很难做大,不过也成了地方的行业一霸了,也不错。

累,大家都知道就不说了。为什么没有希望呢?因为我发现一个公司真正勤勤恳垦的实干是挣不到大钱的。

真正能挣到大钱的公司完全都是靠老板的个人关系到什么程度,要想在某个行业里成为软件老大,要看你和这个行业里的政府主管部门的关系如何。我看到了太多软件和他们公司的产品,一个字“烂”。

可那赚钱的速度,呵呵。其实赚多少钱,都是老板的,我们打工的不就是拿个死工资吗,我们更多的人不是连个受剥削的机会都找不到吗?每次面试刚从大学出来的计算机的本科生,我真想对他说:你何必要选择这一行?每次面试那些工作经历比我长,年龄比我大程序员,看着他唯唯诺诺的目光,我就想:曾几何时我也像他这样,被人横眉冷对的面试多少次,以后我是不是还会像他这样,再去看人家的脸色啊?心寒啊! 看着同期毕业的同学,都转了行的,在自己的行业里都混的不错,大部分都比自己挣钱多,有干头;就是挣钱少的,他也干的轻松啊,最简单得到就是和自己项目接洽企业或政府的信息部主管或网管,懂的不多,轻轻松松,钱比我们的多,有问题老找我们,面对他犯的低级错误,我们还得笑呵呵。我心里确实不平衡啊。

一句话,不当程序员后悔,当了程序员更后悔。

出路在哪?我在找…

1、从程序员,到系统分析,到项目经理。条件:必须是大公司,工资高,福利好,有完整的发展曲线;个人对软件开发有持续的热情。 2、转行到大型企业,事业单位,政府做信息化方面的工作(可以说是网管)。生活有保障,不必太辛苦。条件:一定的能力,一定的人际关系。 3、考研,考博再深造,出国或留校搞教学,培养一代不如一代的本科生,闲时打着大学的名义做做项目,赚个房钱。条件:高学历,一定的经济基础和家庭背景。 4、创业:这个谈起来大发了。这里只说条件:很好的项目,创业精神,一定的经济基础。 5、共享软件:很多程序员的梦想,自己写个软件全世界的卖,光注册费够一家人生活的了。成功少数,但只要有的都发达了。如ACDsee,优化大师,超级兔子,千千静听(可到共享软件区查询)。但我告诉你,这方面基本是没法干了,写个小东西挣钱玩玩可以,要靠他吃饭,饿死吧。条件:过硬的专门的软件技术,富有创意的头脑。 6、网站:基本情况和共享软件差不太多,只是比共享软件更好干点。但奇迹照样有,可看看hao123的神话和现在很牛的80后的富翁。关键你有没有这个本事和这个命了。 7、行业信息化咨询顾问:随着各个行业信息化的普及,企业对这方面人才需求很大。真正实现信息化的企业都需要这样一个既懂软件,又懂行业知识的人员,他和网管还是有区别的,他的要求更高些,更像一个自由职业者,专家类型的,这样的人放在企业里小的是个主管,大的是个副总。条件:很深的行业内部的技术或管理经验,较强的软件开发或实施经验;通常35岁以上才是成熟人才,因为经验是要经过历练的。其实就是个人物了。 8、转行,彻底的转行。干不下去,精力不够了,脑子不灵了,钱太少。只要你够理由,你就走。从新开始另一段新的生活,有什么了不起的,哪里也饿不死我这个干软件的。

我是哪种人,我说我是第8种人,看看能不能兼第5,6种人。 我大学由于种种原因没毕业,最高学历是高中,呵呵。就学历而讲,能干到我目前这个水平我觉的可以了,是时候激流勇退了。 就职业规划和财富而言,我这几年走的路并不成功,最起码无奈的转行本身就是一种失败。就我的人生而言,我觉的很成功。我了却了自己的一个人生梦想,在短时间内品尝了一个“高科技”行业的酸甜苦辣,技术出身也使我比别人多了一份淡定和从容。现在我可以放下这段旅程,再来一个新的开始。

程序兄弟们别自卑,说到优势我们有很多:

1、聪明的头脑,较高的智商。有人说程序员呆,不会为人处事,只会和机器打交道,没前途没希望。我告诉你,程序员愿意和机器打交道是因为他专注于技术,是职业特点,如果我们程序员的头脑用到一般行业,企业,政府单位里去耍耍阴谋诡计,骗骗人,卖卖产品或套套别人的话,我敢说,他们十个人也玩不过我们一个人。俗一点:就他们那点智商,也就骗骗鬼啊。

2、创新精神,学习能力和频繁的知识更新速度。做软件的都知道,干一行的软件,就得学一行的知识,这一行的知识越丰富,软件才可能写的越好。我们都具备着很好的学习能力,学习新知识,新技术的能力。不敢说每个做过的行业我们多么了解,最起码我们总是站在风头浪尖上,高屋建瓴,问题看得远,想的长(要不你怎么去设计数据库啊,呵呵)。我们能以非专业人士的角度,系统的分析出一个行业某方面的流程,那当我们就做的这个行业时,我们对我们的能力还没有信心吗?

3、扎实的工作态度,未雨绸缪的危机意识。扎实的工作态度是每个合格的程序员都应该具备的,因为我们要对代码负责;谈到危机意识,我想大多数程序员都和我一样吃者碗里的,看着锅里的吧,也是被社会逼的没办法。其实这都成了我们的优点了,以后从事哪个行业,都需要这两点精神。

我要走了,去干个和软件根本不搭边的行业,我去干是因为我是老板之一,而且钱绝对比现在好赚。过年的时候,我有个外甥刚大学毕业,非要做软件,我给他了以下建议,算是为后来者留一点东西:

1、能进大公司就别去小公司,在大公司里你能接受真正正统软件开发教育,比到小公司当个什么啥都干,啥都不精的主管强。

2、不断的学习,注意技术积累和更新,那是你唯一的资本。

3、做软硬件结合方面的开发,单片机的开发,嵌入式系统的开发,比较有前途而且门槛高。但凡基于数据库的开发,不管是.NET平台的,J2EE平台的,VC,DELPHI,PB,VB都是扯淡,其核心价值是开发人员的经验而不是技术本身。因为真正的核心技术都在国外,中国没有,我发现不管那种语言,最好用的类库或组件都是老外写的。

4、要有个好点的学历,别像我一样。毕竟是个高学历的行业,学历低人家都瞧不起你,你的发展也很有限 。30岁之前,可考虑弄个高程,CCNA,数据库管理员之类比较有含金量的证书打扮打扮自己,过了35岁其实意义就不大了

何去何从,我们都有自己的路要走。我转行了,我就不再是程序员了吗,不!我只是不在做为别人打工的职业程序员了,我要做自己的终身程序员。闲来时我会为自己写程序,写我愿意写的。当写程序不再是一种职业而是一种兴趣和热情时,他才会陪伴我一辈子。我还会再来CSDN,做为一个非专业人士,一个轻松的真正的程序员而来。未来的一天,当我老的时候,不管那时我有什么成就,或不名一文,如果别人问起我以前是干什么的,我希望仍能自豪的回答:“我曾经是一名软件工程师”。

转载自:http://cnbeta.com/articles/139515.htm

20114 月1

Android开发:屏幕常亮 PowerManager和PowerManager.WakeLock

前言

  学习android一段时间了,为了进一步了解android的应用是如何设计开发的,决定详细研究几个开源的android应用。从一些开源应用中吸收点东西,一边进行量的积累,一边探索android的学习研究方向。这里我首先选择了jwood的 Standup Timer 项目。本文将把研究的内容笔记整理,建立一个索引列表。

PowerManager.WakeLock

  PowerManager.WakerLock是我分析Standup Timer源代码时发现的一个小知识点,Standup Timer 用WakeLock保证程序运行时保持手机屏幕的恒亮(程序虽小但也做得相当的细心,考虑的很周到)。PowerManager 和PowerManager.WakerLock7用于对Android设备的电源进行管理。
  PowerManager:This class gives you control of the power state of the device.
  PowerManager.WakeLock: lets you say that you need to have the device on.
  Android中通过各种Lock锁对电源进行控制,需要注意的是加锁和解锁必须成对出现。先上一段Standup Timer里的代码然后进行说明。
private void acquireWakeLock() {
         if (wakeLock == null) {
                Logger.d("Acquiring wake lock");
                PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
                wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, this.getClass().getCanonicalName());
                wakeLock.acquire();
            }

    }

private void releaseWakeLock() {
        if (wakeLock != null && wakeLock.isHeld()) {
            wakeLock.release();
            wakeLock = null;
        }

    }
20113 月10

MySQL 数据库引擎InnoDB转换成MyISAM

1、备份数据库

为了安全,我采用了2个备份语句分别备份带表信息的sql和不带表信息的sql:

A:mysqldump -h localhost -uroot -ppass -R  mydb> F:\dbbak\mydb%DATE:~0,10%.2.sql  (默认utf8格式)

B:mysqldump -h localhost -uroot -ppass -R –default-character-set=gbk –compatible=No_table_options mydb> F:\dbbak\mydb%DATE:~0,10%.2.sql

2、修改MySQL 默认引擎

因为上述,备份的SQL语句中不包含表信息,还原数据库的时候采用默认引擎,即:

default-storage-engine=MyISAM

数据字段比较大的话,要添加

max_allowed_packet = 300M

3、执行MySQL还原数据库命令

C:>mysql -uroot -ppassword –default-character-set=gbk

mysql>create databse mydb; mysql>use mydb; mysql>source mydb.sql;

20113 月2

囧,升级 WordPress 3.1 导致网站不能访问

昨天升级之后就放着没管,也没去前台看看,谁知道不能访问了,额,一天时间。。

解决方法: 修改 wp-include/template-loader.php 文件,把下面两段话注释。

//if ( defined(‘WP_USE_THEMES’) && WP_USE_THEMES ) // do_action(‘template_redirect’);

20111 月26

Android 开发:TextView 文字阴影效果

res/values/styles.xml



    4px
    4px
    #f1f1f1
    60sp
    #4d4d4d
    0
    -3
    3

res/layout/main.xml

					
201012 月31

JAVA发送EMAIL的例子

import javax.mail.*;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.InternetAddress;
import java.io.UnsupportedEncodingException;
import java.util.Properties;

/**
 * Created by IntelliJ IDEA.
 * User: Wizzer
 * Date: 2010-12-29
 * Time: 16:39:50
 * To change this template use File | Settings | File Templates.
 */
public class Mail {
    public static void main(String args[]) throws MessagingException, UnsupportedEncodingException {
    Properties props = new Properties();
    props.put("mail.smtp.host","smtp.qq.com");
    props.put("mail.smtp.auth","true");
    PopupAuthenticator auth = new PopupAuthenticator(); 
    Session session = Session.getInstance(props, auth);
    MimeMessage message = new MimeMessage(session);
    Address addressFrom = new InternetAddress(PopupAuthenticator.mailuser+"@qq.com", "George Bush");
    Address addressTo = new InternetAddress("116****@qq.com", "George Bush");//收件人
    message.setText("邮件发送成功");
    message.setSubject("Javamal最终测试");
    message.setFrom(addressFrom);
    message.addRecipient(Message.RecipientType.TO,addressTo);
    message.saveChanges();
    Transport transport = session.getTransport("smtp");
    transport.connect("smtp.qq.com", PopupAuthenticator.mailuser,PopupAuthenticator.password);
    transport.send(message);
    transport.close();
    }

}
class PopupAuthenticator extends Authenticator {
public static final String mailuser="wizzer"; 
public static final String password="********";
public PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(mailuser,password);
}
}
201011 月18

MyCity 我的城市街拍,新浪微博街拍Android客户端 1.0发布

MyCity —我的城市街拍 1.0

是Android上的一个新浪微博的客户端,目的是实现手机上街拍发布图片和地理位置信息到微博的功能。 现阶段主要实现以下功能:

  1. 通过MyCity拍照,可以把图片发布到微博 2. 通过MyCity获得GPS地理位置,分享到微博(通过google地图展示)
  2. 用户可以附加100字以内的说明文字

下载地址: /MyCity.apk

使用说明: 按MENU键或第一次按发布键绑定微博帐号,进行拍照后附加文字发布微博,若在室外空旷处运行获得GPS地理位置信息后程序会自动在微博内容中添加google地图链接。

更新日志: 1、2010-11-18 9:00 修改位置信息未添加到微博中的bug,囧,我的错。

应用效果

201011 月17

新浪微博Android 客户端通过HTTP POST发布图片和文字源代码(作废)

1、发送图片+文字

要特别注意,图片的文件名要为 pic 才会被新浪接收。

              Map map = new HashMap();
       map.put("source", "appkey");//改成自己的key
       map.put("status", txt);
       postImg("http://api.t.sina.com.cn/statuses/upload.json",map,Environment.getExternalStorageDirectory()+ "/temp.jpg"
                                ,"帐号名字","密码");
              /**
     * 直接通过HTTP协议提交数据到服务器,实现表单提交功能
     * @param actionUrl 上传路径
     * @param params 请求参数 key为参数名,value为参数值
     * @param filename 上传文件
     * @param username 用户名
     * @param password 密码
     */
    private void postImg(String actionUrl,Map params, String  filename,String username,String password) {
        try {
            String BOUNDARY = "--------------et567z"; //数据分隔线
            String MULTIPART_FORM_DATA = "Multipart/form-data";  

            URL url = new URL(actionUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 

            conn.setDoInput(true);//允许输入
            conn.setDoOutput(true);//允许输出
            conn.setUseCaches(false);//不使用Cache
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
            conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + ";boundary=" + BOUNDARY);
            String usernamePassword=username+":"+password;
            conn.setRequestProperty("Authorization","Basic "+new String(SecBase64.encode(usernamePassword.getBytes())));

            StringBuilder sb = new StringBuilder();  

            //上传的表单参数部分,格式请参考文章
            for (Map.Entry entry : params.entrySet()) {//构建表单字段内容
                sb.append("--");
                sb.append(BOUNDARY);
                sb.append("\r\n");
                sb.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");
                sb.append(entry.getValue());
                sb.append("\r\n");
            }
            //            System.out.println(sb.toString());
            DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
            outStream.write(sb.toString().getBytes());//发送表单字段数据
            byte[] content = readFileImage(filename);
            //上传的文件部分,格式请参考文章
            //System.out.println("content:"+content.toString());
            StringBuilder split = new StringBuilder();
            split.append("--");
            split.append(BOUNDARY);
            split.append("\r\n");
            split.append("Content-Disposition: form-data;name=\"pic\";filename=\"temp.jpg\"\r\n");
            split.append("Content-Type: image/jpg\r\n\r\n");
            System.out.println(split.toString());
            outStream.write(split.toString().getBytes());
            outStream.write(content, 0, content.length);
            outStream.write("\r\n".getBytes());  

            byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();//数据结束标志
            outStream.write(end_data);
            outStream.flush();
            int cah = conn.getResponseCode();
            //            if (cah != 200) throw new RuntimeException("请求url失败:"+cah);
            if(cah == 200)//如果发布成功则提示成功
            {
                /*读返回数据*/
                //String strResult = EntityUtils.toString(httpResponse.getEntity()); 

                new AlertDialog.Builder(Main.this)
                // Main.this视情况而定,这个一般是指当前显示的Activity对应的XML视窗。
                .setTitle("")// 设置对话框的标题
                .setPositiveButton("确定",// 设置对话框的确认按钮
                        new DialogInterface.OnClickListener() {// 设置确认按钮的事件
                    public void onClick(DialogInterface dialog, int which) {

                    }})
                    .setMessage(" 发布成功 ")// 设置对话框的内容
                    .show();
            }
            else if(cah == 400)
            {
                new AlertDialog.Builder(Main.this)
                // Main.this视情况而定,这个一般是指当前显示的Activity对应的XML视窗。
                .setTitle("")// 设置对话框的标题
                .setPositiveButton("确定",// 设置对话框的确认按钮
                        new DialogInterface.OnClickListener() {// 设置确认按钮的事件
                    public void onClick(DialogInterface dialog, int which) {

                    }})
                    .setMessage(" 发布失败  \n 不可连续发布相同内容 ")// 设置对话框的内容
                    .show();
            }else{
                throw new RuntimeException("请求url失败:"+cah);
            } 

            //            InputStream is = conn.getInputStream();
            //            int ch;
            //            StringBuilder b = new StringBuilder();
            //            while( (ch = is.read()) != -1 ){
            //                b.append((char)ch);
            //            }
            outStream.close();
            conn.disconnect();
        }
        catch (IOException e)
        {
            e.printStackTrace(); 

        }
        catch (Exception e)
        {
            e.printStackTrace();  

        }  

    }

             public static byte[] readFileImage(String filename) throws IOException {
        BufferedInputStream bufferedInputStream = new BufferedInputStream(
                new FileInputStream(filename));
        int len = bufferedInputStream.available();
        byte[] bytes = new byte[len];
        int r = bufferedInputStream.read(bytes);
        if (len != r) {
            bytes = null;
            throw new IOException("读取文件不正确");
        }
        bufferedInputStream.close();
        return bytes;
    }

2、只发文字

  //POST发布文本信息
        public  void sendMsg(String status,String username,String password){
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://api.t.sina.com.cn/statuses/update.json");
                //NameValuePair实现请求参数的封装

                List  params = new ArrayList ();
                params.add(new BasicNameValuePair("source", "4016954419"));
                params.add(new BasicNameValuePair("status", status));
                try
                { 

                  //添加请求参数到请求对象

                    httppost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
                    httppost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false); 

                    String data=username+":"+password;
                    httppost.addHeader("Authorization","Basic "+new String(SecBase64.encode(data.getBytes())));
                    httppost.addHeader("Content-Type", "application/x-www-form-urlencoded");

                  //发送请求并等待响应
                  HttpResponse httpResponse = new DefaultHttpClient().execute(httppost);
                  //若状态码为200 ok
                  if(httpResponse.getStatusLine().getStatusCode() == 200)
                  {
                    //读返回数据
                    //String strResult = EntityUtils.toString(httpResponse.getEntity()); 

                    new AlertDialog.Builder(Main.this)
                    // Main.this视情况而定,这个一般是指当前显示的Activity对应的XML视窗。
                    .setTitle("")// 设置对话框的标题
                    .setPositiveButton("确定",// 设置对话框的确认按钮
                    new DialogInterface.OnClickListener() {// 设置确认按钮的事件
                        public void onClick(DialogInterface dialog, int which) {

                    }})
                    .setMessage(" 发布成功 ")// 设置对话框的内容
                    .show();
                  }
                  else if(httpResponse.getStatusLine().getStatusCode() == 400)
                  {
                      new AlertDialog.Builder(Main.this)
                        // Main.this视情况而定,这个一般是指当前显示的Activity对应的XML视窗。
                        .setTitle("")// 设置对话框的标题
                        .setPositiveButton("确定",// 设置对话框的确认按钮
                    new DialogInterface.OnClickListener() {// 设置确认按钮的事件
                        public void onClick(DialogInterface dialog, int which) {

                    }})
                        .setMessage(" 发布失败  \n 不可连续发布相同内容 ")// 设置对话框的内容
                        .show();
                  } 

                }
                catch (ClientProtocolException e)
                {
                  e.printStackTrace();
                  et.setText(et.getText()+" Error1:"+e.getMessage());
                }
                catch (IOException e)
                {
                  e.printStackTrace();
                  et.setText(et.getText()+" Error2:"+e.getMessage());
                }
                catch (Exception e)
                {
                  e.printStackTrace();
                  et.setText(et.getText()+" Error3:"+e.getMessage());
                }  

         }

3、加密类 SecBase64.java

package wizzer.cn.app;

public class SecBase64 {
private static final byte[] encodingTable = { (byte) 'A', (byte) 'B',
    (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
    (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L',
    (byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q',
    (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V',
    (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a',
    (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f',
    (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k',
    (byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p',
    (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
    (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
    (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4',
    (byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9',
    (byte) '+', (byte) '/' };
private static final byte[] decodingTable;
static {
   decodingTable = new byte[128];
   for (int i = 0; i < 128; i++) {
    decodingTable[i] = (byte) -1;
   }
   for (int i = 'A'; i <= 'Z'; i++) {
    decodingTable[i] = (byte) (i - 'A');
   }
   for (int i = 'a'; i <= 'z'; i++) {
    decodingTable[i] = (byte) (i - 'a' + 26);
   }
   for (int i = '0'; i <= '9'; i++) {
    decodingTable[i] = (byte) (i - '0' + 52);
   }
   decodingTable['+'] = 62;
   decodingTable['/'] = 63;
}

//加密

public static byte[] encode(byte[] data) {
   byte[] bytes;
   int modulus = data.length % 3;
   if (modulus == 0) {
    bytes = new byte[(4 * data.length) / 3];
   } else {
    bytes = new byte[4 * ((data.length / 3) + 1)];
   }
   int dataLength = (data.length - modulus);
   int a1;
   int a2;
   int a3;
   for (int i = 0, j = 0; i >> 2) & 0x3f];
    bytes[j + 1] = encodingTable[((a1 <>> 4)) & 0x3f];
    bytes[j + 2] = encodingTable[((a2 <>> 6)) & 0x3f];
    bytes[j + 3] = encodingTable[a3 & 0x3f];
   }
   int b1;
   int b2;
   int b3;
   int d1;
   int d2;
   switch (modulus) {
   case 0: 
    break;
   case 1:
    d1 = data[data.length - 1] & 0xff;
    b1 = (d1 >>> 2) & 0x3f;
    b2 = (d1 <>> 2) & 0x3f;
    b2 = ((d1 <>> 4)) & 0x3f;
    b3 = (d2 << 2) & 0x3f;
    bytes[bytes.length - 4] = encodingTable[b1];
    bytes[bytes.length - 3] = encodingTable[b2];
    bytes[bytes.length - 2] = encodingTable[b3];
    bytes[bytes.length - 1] = (byte) '=';
    break;
   }
   return bytes;
}

//解密

public static byte[] decode(byte[] data) {
   byte[] bytes;
   byte b1;
   byte b2;
   byte b3;
   byte b4;
   data = discardNonBase64Bytes(data);
   if (data[data.length - 2] == '=') {
    bytes = new byte[(((data.length / 4) - 1) * 3) + 1];
   } else if (data[data.length - 1] == '=') {
    bytes = new byte[(((data.length / 4) - 1) * 3) + 2];
   } else {
    bytes = new byte[((data.length / 4) * 3)];
   }
   for (int i = 0, j = 0; i < (data.length - 4); i += 4, j += 3) {
    b1 = decodingTable[data[i]];
    b2 = decodingTable[data[i + 1]];
    b3 = decodingTable[data[i + 2]];
    b4 = decodingTable[data[i + 3]];
    bytes[j] = (byte) ((b1 <> 4));
    bytes[j + 1] = (byte) ((b2 <> 2));
    bytes[j + 2] = (byte) ((b3 << 6) | b4);
   }
   if (data[data.length - 2] == '=') {
    b1 = decodingTable[data[data.length - 4]];
    b2 = decodingTable[data[data.length - 3]];
    bytes[bytes.length - 1] = (byte) ((b1 <> 4));
   } else if (data[data.length - 1] == '=') {
    b1 = decodingTable[data[data.length - 4]];
    b2 = decodingTable[data[data.length - 3]];
    b3 = decodingTable[data[data.length - 2]];
    bytes[bytes.length - 2] = (byte) ((b1 <> 4));
    bytes[bytes.length - 1] = (byte) ((b2 <> 2));
   } else {
    b1 = decodingTable[data[data.length - 4]];
    b2 = decodingTable[data[data.length - 3]];
    b3 = decodingTable[data[data.length - 2]];
    b4 = decodingTable[data[data.length - 1]];
    bytes[bytes.length - 3] = (byte) ((b1 <> 4));
    bytes[bytes.length - 2] = (byte) ((b2 <> 2));
    bytes[bytes.length - 1] = (byte) ((b3 << 6) | b4);
   }
   return bytes;
}

//解密

public static byte[] decode(String data) {
   byte[] bytes;
   byte b1;
   byte b2;
   byte b3;
   byte b4;
   data = discardNonBase64Chars(data);
   if (data.charAt(data.length() - 2) == '=') {
    bytes = new byte[(((data.length() / 4) - 1) * 3) + 1];
   } else if (data.charAt(data.length() - 1) == '=') {
    bytes = new byte[(((data.length() / 4) - 1) * 3) + 2];
   } else {
    bytes = new byte[((data.length() / 4) * 3)];
   }
   for (int i = 0, j = 0; i < (data.length() - 4); i += 4, j += 3) {
    b1 = decodingTable[data.charAt(i)];
    b2 = decodingTable[data.charAt(i + 1)];
    b3 = decodingTable[data.charAt(i + 2)];
    b4 = decodingTable[data.charAt(i + 3)];
    bytes[j] = (byte) ((b1 <> 4));
    bytes[j + 1] = (byte) ((b2 <> 2));
    bytes[j + 2] = (byte) ((b3 << 6) | b4);
   }
   if (data.charAt(data.length() - 2) == '=') {
    b1 = decodingTable[data.charAt(data.length() - 4)];
    b2 = decodingTable[data.charAt(data.length() - 3)];
    bytes[bytes.length - 1] = (byte) ((b1 <> 4));
   } else if (data.charAt(data.length() - 1) == '=') {
    b1 = decodingTable[data.charAt(data.length() - 4)];
    b2 = decodingTable[data.charAt(data.length() - 3)];
    b3 = decodingTable[data.charAt(data.length() - 2)];
    bytes[bytes.length - 2] = (byte) ((b1 <> 4));
    bytes[bytes.length - 1] = (byte) ((b2 <> 2));
   } else {
    b1 = decodingTable[data.charAt(data.length() - 4)];
    b2 = decodingTable[data.charAt(data.length() - 3)];
    b3 = decodingTable[data.charAt(data.length() - 2)];
    b4 = decodingTable[data.charAt(data.length() - 1)];
    bytes[bytes.length - 3] = (byte) ((b1 <> 4));
    bytes[bytes.length - 2] = (byte) ((b2 <> 2));
    bytes[bytes.length - 1] = (byte) ((b3 << 6) | b4);
   }
   return bytes;
}

private static byte[] discardNonBase64Bytes(byte[] data) {
   byte[] temp = new byte[data.length];
   int bytesCopied = 0;
   for (int i = 0; i < data.length; i++) {
    if (isValidBase64Byte(data[i])) {
     temp[bytesCopied++] = data[i];
    }
   }
   byte[] newData = new byte[bytesCopied];
   System.arraycopy(temp, 0, newData, 0, bytesCopied);
   return newData;
}

private static String discardNonBase64Chars(String data) {
   StringBuffer sb = new StringBuffer();
   int length = data.length();
   for (int i = 0; i < length; i++) {
    if (isValidBase64Byte((byte) (data.charAt(i)))) {
     sb.append(data.charAt(i));
    }
   }
   return sb.toString();
}

private static boolean isValidBase64Byte(byte b) {
   if (b == '=') {
    return true;
   } else if ((b = 128)) {
    return false;
   } else if (decodingTable[b] == -1) {
    return false;
   }
   return true;
}

//测试类
public static void main(String[] args) {
   String data = "wizzer@qq.com:etpass";
   byte[] result = SecBase64.encode(data.getBytes());// 加密
   System.out.println("Basic "+data);
   System.out.println("Basic "+new String(result));
   System.out.println(new String(SecBase64.decode(new String(result))));// 解密
   }
}
201011 月16

Android 2.1 GPS定位和拍照功能代码

1、GPS功能代码

private void getLocation()
    {
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                 200, 0, locationListener);

    }
    private final LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) { //当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
            // log it when the location changes
            if (location != null) {
                Lat.setText(String.valueOf(location.getLatitude()));
                Lon.setText(String.valueOf(location.getLongitude()));

            }
        }

        public void onProviderDisabled(String provider) {
        // Provider被disable时触发此函数,比如GPS被关闭
        }

        public void onProviderEnabled(String provider) {
        //  Provider被enable时触发此函数,比如GPS被打开
        }

        public void onStatusChanged(String provider, int status, Bundle extras) {
        // Provider的转态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
        }
    };

2、拍照功能代码

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     // Hide the window title.
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.main);
        imageView = (ImageView) this.findViewById(R.id.iv1);
        Button button = (Button) this.findViewById(R.id.bt1);
        button.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri
                        .fromFile(new File(Environment
                                .getExternalStorageDirectory(), "temp.jpg")));
                intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
                startActivityForResult(intent, 0);
            }
        });

    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 0 && resultCode == Activity.RESULT_OK) {
            this.imageView.setImageDrawable(Drawable.createFromPath(new File(
                    Environment.getExternalStorageDirectory(), "temp.jpg")
                    .getAbsolutePath()));

        }
    }

3、退出程序确认

public boolean onKeyDown(int keyCode, KeyEvent event) {

        //按下键盘上返回按钮
        if(keyCode == KeyEvent.KEYCODE_BACK){
            new AlertDialog.Builder(Main.this)
            // Main.this视情况而定,这个一般是指当前显示的Activity对应的XML视窗。
            .setTitle("")// 设置对话框的标题
            .setMessage(" 确定退出? ")// 设置对话框的内容
            .setPositiveButton("确定",// 设置对话框的确认按钮
                new DialogInterface.OnClickListener() {// 设置确认按钮的事件
                    public void onClick(DialogInterface dialog, int which) {
                        //退出程序
                        android.os.Process.killProcess(android.os.Process.myPid());
                }})
            .setNegativeButton("取消",// 设置对话框的取消按钮
                new DialogInterface.OnClickListener() {// 设置取消按钮的事件
                    public void onClick(DialogInterface dialog, int which) {
                        // 如果你什么操作都不做,可以选择不写入任何代码
                        dialog.cancel();
                }}
            ).show();

            return true;
        }else{      
            return super.onKeyDown(keyCode, event);
        }
    }
201011 月12

mysql : Lock wait timeout exceeded; try restarting transaction

使用的InnoDB   表类型的时候, 默认参数:innodb_lock_wait_timeout设置锁等待的时间是50s, 因为有的锁等待超过了这个时间,所以报错. 可以把这个时间加长,或者优化存储过程,事务避免过长时间的等待.

my.ini文件: #innodb_lock_wait_timeout = 50 改成 innodb_lock_wait_timeout = 500

 重启mysql服务。

20109 月29

C# Windows Mobile 实现休眠状态下定时任务

OpenNETCF.WindowsCE.LargeIntervalTimer llTimer = new OpenNETCF.WindowsCE.LargeIntervalTimer(); 

//第一次触发时间

llTimer.FirstEventTime = DateTime.Now;

llTimer.Interval = new TimeSpan(0, 30, 0);

//是否只触发一次

 llTimer.OneShot = false;

llTimer.Tick += new EventHandler(llTimer_Tick);

llTimer.Enabled = true;

static void llTimer_Tick(object sender, EventArgs e)

 {

             //

  }

 

来源:http://www.cnblogs.com/fox23/archive/2008/02/03/AtTime.html

opennetcf下载:http://www.opennetcf.com/Products/SmartDeviceFramework/tabid/65/Default.aspx

20109 月28

C# Windows Mobile 6 通过注册表实现开机自运行

方法1:制作CAB安装包

VS2005,新建项目–其他项目类型–安装和部署–智能Cab安装项目–在Program files里增加文件夹myexe

添加要可执行 a.exe。

打开注册表视图,在HKEY_LOCAL_MACHINE 增加 Init 文件夹,新建字符串 Launch98,值为

“\Program files\myexe\a.exe”

这样,安装cab之后重启下即可自运行。

private void Form1_Activated(object sender, EventArgs e)
        {
            this.Hide();  //隐藏窗体
        }

方法2:通过程序运行注册键值

 

  //注册开机
  //Registry.LocalMachine 对应于 HKEY_LOCAL_MACHINE主键
  RegistryKey key = Registry.LocalMachine.OpenSubKey("init", true);
  if (key.GetValue("Launch77") == null)
  {
       key.SetValue("Launch77", Assembly.GetExecutingAssembly().GetName().CodeBase);
       MessageBox.Show("注册成功!", "提示");
   }
   key.Close();
20109 月22

WM windows mobile 6.1 C#网络开发,程序自动升级等

终于的终于,还是用C#开发了,仿照了一些M8上软件界面。。

分享一些经验,由于时间太紧,有些功能是比较土的方法暂时实现的,之后还需升级。

1、网络传输

 public static string Login(string userName, string password)
        {
            string LOGIN_RES = "";
            try
            {

                string url = com.LOGIN_URL ;//url
                url = url + "&username=" + userName;
                url = url + "&password=" + password;

                HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
                objRequest.Method = "GET";
                objRequest.Timeout = 60 * 1000;
                //WebProxy proxy = new WebProxy("192.168.0.2:80", true);
                // proxy.Address = new Uri("");//按配置文件创建Proxy 地置
                //proxy.Credentials = new NetworkCredential("用户名", "密码");//从配置封装参数中创建
                //objRequest.Proxy = proxy; 

                HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();

                Stream objStream = objResponse.GetResponseStream();
                StreamReader objReader = new StreamReader(objStream, Encoding.GetEncoding(com.PageEnCode));
                LOGIN_RES=objReader.ReadToEnd();
                if (LOGIN_RES != null) LOGIN_RES = LOGIN_RES.Trim();
                objReader.Close();
                objStream.Close();

                return LOGIN_RES;

            }
            catch (Exception ex){
                Console.Write(ex.Message);
                return null;

            }

        }

2、程序升级

利用1里面的方法,读取服务器某网页文件,获取版本号和当前程序版本进行比较,若有最新版,

则在WM里打开浏览器进行下载:

private void checkUpdate()
        {
            int k = comHTTP.AutoUpdate();
            if (k > com.COPYRIGHT)
            {
                MessageBox.Show("\r\n系统监测到新版本,程序将自动打开下载,请安装后继续使用.\r\n\r\n", "提示");
                System.Diagnostics.Process.Start("IEXPLORE.EXE", "/autoupdate.cab");//打开IE,
                Application.Exit();

            }
        }
20109 月21

windows mobile模拟器如何联网?

windows mobile开发的时候模拟器如何联网?

  1. 安装Active sync,到微软网站上面去找找,有免费下载。

  2. 打开Active sync连接选项,里面有下拉选框的那个(允许连接到以下其中一个端口),选择DMA

  3. 在VS2005里面启动模拟器成功(要知道自己连的是哪个)之后,Tools菜单里面有个”Device Emulator Manager”,找到刚刚连上的模拟器(前面会有个小图标,其他没启动就没有),右键点击,选择”Cradle” 这时候Active sync跳出来说找到一个device,不理他,等待emulator里面跳出个小对话框,告诉你连接成功(很快就自己消失),OK,这时候就可以上网了。

注意:Active Sync会吃掉所有的UDP包,所以用这种方式开发UDP客户端行不通了。

20109 月17

Java ME/J2ME 环境搭建、WM6.1运行JBED虚拟机手机实现JSR179定位

接触Java ME,到现在已经过去五天了。利用一款带GPS模块的WM6.1系统的手机实现定位和数据上报项目,周期为18天,公司没有一个人搞过手机开发,囧,身为研发部负责人责无旁贷(目前是光杆司令)……

废话不多讲,刚开始用MyEclispe + MyEclispeMe + WTK + JDK 搭建了开发环境(这也是费了九牛二虎之力)

一、Java ME/J2ME环境的搭建

1、安装 MyEclipse

MyEclipse_6.5.1GA_E3.3.2_Installer.exe、myEclipse6.5汉化包.rar、MyEclipse注册码.txt

2、安装 MyEclispeMe 开发插件

运行MyEclispe –>帮助–>Software Updates–>Find and Install –>搜索新部件

新建站点:http://eclipseme.org/updates/ (可能要翻翻哦),确定,全部勾选,安装,完毕。

3、安装 JDK

JDK6.0.21版本,如果找不到就先安装 jdk-6u20-windows-i586.exe 再打21补丁 JavaSetup6u21.exe。

4、安装 JavaME SDK

sun_java_me_sdk-3_0-win.exe

5、安装 WTK

WTK2.5.2_01版本,sun_java_wireless_toolkit-2.5.2_01-win.exe

MyEclispe–>首选项–>J2ME–>设备管理–>选择WTK目录–>refresh

(以上这些软件你就百度吧,不行就google,再不行必应)

注意:MyEclipse 编译的JAR包,很可能在虚拟机上安装不了。提示什么907啊,30的错误。

解决办法就是打开,JAR,编辑META-INF文件夹下的 MANIFEST.MF 文件,增加一行:

MIDlet-1: Test,,demo.LocationMIDlet  名字为Test,入口类为demo.LocationMIDlet

有的环境可能需要JAD包,相应的里面也要加上这一行。

二、支持JSR179的虚拟机

WM6.1上安装4EsmertecJbed_v20090217.5.1a_Chs.cab,狗狗搜,搜不到就找我要吧。

三、测试代码

package demo;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.List;
import javax.microedition.location.Coordinates;
import javax.microedition.location.Criteria;
import javax.microedition.location.Location;
import javax.microedition.location.LocationException;
import javax.microedition.location.LocationProvider;
//import javax.microedition.location.QualifiedCoordinates;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class LocationMIDlet extends MIDlet implements CommandListener, Runnable
{
    private Display myDisplay;
    private Command okcmd;
    private Command ecmd;
    private Form form;
    private List myList;
    private boolean yes;

    public LocationMIDlet()
    {
        myDisplay = Display.getDisplay(this);
        myList = new List("测试真机是否支持 JSR179", List.IMPLICIT);
        okcmd = new Command("测试", Command.OK, 1);
        ecmd = new Command("退出", Command.OK, 1);
        form = new Form("GPS");
        String cellid=System.getProperty("CellID");
        if(cellid==null||"".equals(cellid)){
            cellid=System.getProperty("Cell-ID");
        }
        if(cellid==null||"".equals(cellid)){
            cellid=System.getProperty("CELLID");
        }
        if(cellid==null||"".equals(cellid)){
            cellid=System.getProperty("CELL-ID");
        }
        form.append("CellID:"+cellid);
        form.append("JSR:"+System.getProperty("Version"));
        myList.addCommand(okcmd);
        form.addCommand(ecmd);
        form.setCommandListener(this);
        myList.setCommandListener(this);
    }
    protected void destroyApp(boolean arg0)
            throws MIDletStateChangeException {}
    protected void pauseApp(){}
    protected void startApp() throws MIDletStateChangeException
    {
        myDisplay.setCurrent(myList);
    }
    public void commandAction(Command arg0, Displayable arg1)
    {
        if(arg0 == okcmd)
        {
            String version = System.getProperty("microedition.location.version");
            yes = (version != null && !version.equals(""));
            Thread t = new Thread(this);
            t.start();
        }
        if(arg0 == ecmd)
        {
           this.notifyDestroyed();
        }
    }
    public void run()
    {
        myDisplay.setCurrent(form);
        //测试真机是否支持 jsr179
        if(yes)
        {
            // Set criteria for selecting a location provider:
            // accurate to 500 meters horizontally
            // 设置精度
            Criteria myCriteria = new Criteria();
            myCriteria.setHorizontalAccuracy(500);

            double lat = 0;
            double lon = 0;

            // Get an instance of the provider
            // 找卫星,找服务
            try
            {
                LocationProvider myLocationProvider = LocationProvider.getInstance(myCriteria);

                // Request the location, setting a one-minute timeout
                // 请求位置,并设置超时时间
                Location myLocation = myLocationProvider.getLocation(5000);
                Thread.sleep(1000);
                Coordinates myCoordinates = myLocation.getQualifiedCoordinates();
                for(int i=0;i<10;i++){
                if(myCoordinates != null)
                {
                    // Use coordinate information
                    // 得到经纬度
                    lat = myCoordinates.getLatitude();
                    lon = myCoordinates.getLongitude();
                }

                form.append("真机支持JSR179,纬度坐标:" + String.valueOf(lat) + ",经度坐标:" + String.valueOf(lon));

                form.append("------------"+i);

                try{
                    Thread.sleep(1000);
                    }catch(Exception e){

                    }
                }
            }
            catch (LocationException e)
            {
                form.append("LocationException 发生异常");
                e.printStackTrace();
            } catch (InterruptedException e)
            {
                form.append("InterruptedException 发生异常");
                e.printStackTrace();
            }

        }
        //真机不支持 jsr179
        else
        {
            form.append("真机不支持JSR179");

        }

    }

}

四、遗留问题

WM6.1手机系统运行JBED虚拟机上的Java ME软件,通过JSR179获取经纬度已实现。
(先运行WM上的GPS软件,后执行虚拟机里的测试代码)
两个问题:
1、室内等信号弱的地方无法定位;
2、JSR179是否需要WM上的程序进行GPS初始化待验证。
初步验证失败,貌似需要WM上先初始化GPS拨号找到卫星,虚拟机里程序才能读取数据,杯具。。。
再研究研究。。。
20109 月14

MyEclipse+Lwuit:java.lang.NoClassDefFound

在运行Lwuit例子时报: java.lang.NoClassDefFoundError:com/sun/lwuit/uidemo/UIDemoMIDlet 错误 解决办法比较简单: 在Myeclipse中,选择Project->properites->Java Build Path->Order and Export,选中lwuit即可。

ps: 命苦的人儿还在加班。JAVA ME 从〇开始。。 两周要开发出成品。55

20109 月10

最封闭的开源系统:Android的八宗罪

  你以为 Android 是开放的吗?Google 采用了一系列的控制手段来保证每一部 Android 手机上都有它指定的软件和硬件规格。然而,他们同时又利用 Android SDK 里面的 Apache 许可证来大肆鼓吹 Android 是开放的。

  没错,Google 的移动平台是当前最聪明的利用开源来驱动商业议程的实现。但在我们深入探讨这个为什么之前,我们先说说为什么 Android 的成功和开源并没有什么关系吧。

  是什么成就了 Android

  虽然早期饱受质疑,Google 的 Android 移动平台已经在移动行业得到了营运商和手机厂商的广泛支持,仅剩固执的诺基亚。Android 从 08 年的一款机型发展到 10 年的 50 多款,发展之快让绝大多数的业内观察家们吃惊。

  Android 的成功和开源毫无关系。它的成功依靠下列三个主要因素:

JAVA手机网[www.cnjm.net]  - 苹果. 这点看起来很奇怪,Android 竟然是靠它的主要对手发家的?让我来分析下。在 iPhone 空前绝后的成功以及苹果对网络营运商傲慢苛刻的态度下,营运商们迫切的在寻找一种更便宜的选择。因此这些第一层最大的营运商们开始积极的用 Android 来开发手机给那些买不起 iPhone 的用户,更重要的是,他们不需要每卖一部手机就给 Apple 300 欧元以上的回扣。

  - 全世界的营运商们迫切希望自己鹤立鸡群. Android 给他们提供了一个统一的软件平台。他们可以很方便的定制自己想要的系统,而且花费的代价也很低(3 个月的时间,这个比 SavaJe 12 个月以上的定制周期要短很多)。对大型的营运商来说,Android 也降低了他们在智能手机软件方面的投资。这也是为什么大多数的 Android 手机项目背后都是营运商和 OEM 厂商的组合。

JAVA手机网[www.cnjm.net]  - 高通. 这个市值 100 亿美元的芯片厂商对 Android 的崛起功不可没。手机开发产商可以直接拿高通已经为 Android 集成好的方案,在 9-12 个月的时间内向市场上推广。(相比起来摩托罗拉的 CLIQ 花了 16 个月,而 HTC G1 则花费了 2 年多的时间)。除了高通,我们还有 TI 的 OMAP3 平台(摩托罗拉 Droid/Milestone 基于此方案)。ST Ericsson 和 Broadcom 也在做 Android 的集成方案。 JAVA手机网[www.cnjm.net]   换句话说,在 Android 手机上,大多数的 OEM 预算花在了定制方面。而 Symbian 的绝大部分预算花在无线通信的移植和硬件整合上了(Symbian 2001 年所做决定的结果)。总的来说,Android 使 OEM 厂商可以大幅削减研发预算,把钱花在定制这个刀刃上。当然我们不能忘记 Android 是免费的。这个免费让众多厂商激动不已。

  话说回来,Android 用开源来做市场宣传,非常成功的搅乱了整个行业,导致了诺基亚对 Symbian 的收购以及 Windows Mobile 的全面崩溃(不过译者觉得 iPhone OS 4 的多重任务机制的发布让 WP7 真正成了杯具帝)。不过更重要的是,利用开源的名号和 Google 的魅力,Android 吸引了成千上万的开发者,虽然 Android 并不能让开发者们赚到很多钱,而且 Android 手机的数量不到苹果产品的十分之一(连支持收费的国家都比苹果少6倍)。

  在开源的面纱后面

  让人更惊讶的是 Android 到底有多封闭,尽管外面包裹着 Google“不作恶”的口号和 Apache 授权许可证模式。借用亨利福特在 Model-T 相关的书里的一句话:“任何人都可以自由挑选 Android 的颜色,只要那是黑色”(anyone can have Android in their own colour as long as it’s black)。Android 是一个绝好的商业案例——展现一家公司是如何用开源来赢得关注和社区参与,而且同时保持一个非常严密的商业运作。

JAVA手机网[www.cnjm.net]  Google 是如何控制着每台 Android 手机里采用什么服务、软件和硬件的?这个搜索巨人建立了一套很完善的控制管理系统。为了挖掘更多的信息,我们花了两个月,和很多与 Android 有着紧密联系的内部人士进行了讨论。我们发掘出的事实让人震惊。从宏观方面说,Google 控制 Android 手机构成以下八宗罪:

  1. 私有分支. Android 有多个私有分支,这些只给几个特定合作伙伴,往往是那些开发 Android 的 OEM 厂商,而且这些只提供给需要知道的人。这些私有分支比已经公布的 SDK 要超前起码 6 个月,也是 OEM 厂商可以保持竞争力的关键。而公开的 SDK 则是为第三方应用提供私有分支里发布的最新功能。

  2. 封闭的评估流程. 所有的代码评估员似乎都是 Google 员工,也就是说从社区提交的代码只有 Google 才有权力决定是否接受。而且 Google 内部还流传着“并非此处发明”的一种思考文化,他们觉得 Google 员工写的代码是天下无敌。随便问任何一个给 Android 提交过补丁的人,你会得到一样的答复:几乎没有什么提交被 Google 接受,而被拒绝的时候往往没有任何理由和解释。

  3. 进化的速度. Google 对 Android 的创新的速度是移动行业内绝无仅有的,他们在 18 个月里发布了四个大版本。想在 Android 上面做文章的 OEM 厂商只得紧跟 Google 的步伐(这里想起了移动杯具的OMS),不然就跟不上新功能的发布和 bug 修复。Nexus One、Droid、G1 和其它带有 Google体验应用的手机给 Google 提供了创新的测试场。

  4. 不完善的软件. 用公开的 SDK 并不能完整的建造手机。缺少的几个关键的部份包括无线通信的集成模块、国际化语言包、营运商信息包以及闭源的 Google 应用,比如 Market、Gmail 和 Gtalk。虽然 Cyanogen 可以自己定制 ROM,但里面包含的那些应用没有授权,所以不能发布在商业用途的 Android 手机上。

  5. 闭门的开发者社区. Android Market 是唯一一个拥有超过四万个程序并和每个手机 OEM 厂商都签有合约的 android 程序商店。这个限制很要命,因为没有一个 OEM 厂商愿意发布没有 Market 的 Android 手机(天朝是另类)。当然,在 Market 上发布应用是个非常简单的事情,没有什么审批的步骤,这个和苹果的 AppStore 刚好相反。

  6. 反分化合约. 外界几乎不清楚原来 OHA 的成员都签署了反分化的合约。但这个合约更可以被理解为不能发布没有通过 CTS 兼容测试的手机。(下面细说 CTS)(译者注:貌似中国移动已经被踢出 Android 的私有分支,是不是因为他们建立的 OMS 违反了这个协定呢?)

  7. 保密的发展蓝图. Android 的发展蓝图是很杯具的,到目前为止,公开发布的发展蓝图还停留在 2009 年的第一季度。如果想要看到内部的发展蓝图,你需要 Google 的赐福.

  8. Android 商标. Google 掌握着 Android 的注册商标和冠名权。任何想用 Android 品牌的厂商都需要得到Google的授权。简单的说:进 Google 的门,或者没有门。如果你要自己做 Android 分枝,你就全部靠自己了,比如你需要中国移动那么大的公司。

  Android 的传奇中还有个大篇章:CTS(兼容测试组),也就是 Google 一套测试 Android 手机是不是达到 Google 的标准。根据我们的线人消息,CTS 不仅仅测试软件的 API 部份,它还包括性能测试,硬件功能,设备设计,UI 用户界面需求,和机内打包的服务。CTS 决定了你可以添加额外功能,但不能从最基础的配置中削减功能。除了 CTS 以外,OEM 厂商还要和 Google 签订授权合同,这样他们才能打包 Google 的服务,比如 Gmail、YouTube 等等。

  CTS 限制了 OEM 定制弱化版 Android 手机的想法(译者注:山寨的机会啊!MTK、中微星,年底发布些低端 Android 手机吧!)。这也大大限制了 Android 开拓低端市场的能力。CTS 和向前兼容 4 万多个应用的事实,极大的挑战着 Google 想占领智能手机市场2位数的市场份额目标。这些限制,还有 Google 与 OEM 亦敌亦友的合作关系,使得 OEM 圈内掀起了建立 Android 基金的讨论。

  Google 的终极目标

  手握 Android,Google 的目标是为自己产生收入的服务提供一个稳定的平台。在当前,这个广告生意。但未来,Google 的目标在语音服务(几十亿没有数据服务的用户)和 Google Checkout(比如变成移动领域的 visa 卡)。但不管 Google 的终极目标是什么,我们应该意识到 Android 和 Windows Mobile、Mac OSX 或 PalmOS 相比,并没有开放多少。Android 是用开源来驱动商业议程的最聪明的案例之一。Android 骨子里并没有我们潜意识里所灌输的那么多不作恶思想。