本文共 3137 字,大约阅读时间需要 10 分钟。
有了前面的基础,现在就开始实现SNProtector。
这回我们对SNProtector又有哪些要求和目标呢?1。和前面的OnceProtector和TimeProtector一样要使用简单;2。用户可以在程序里输入用户名和序列号并验证;3。允许用户试用;4。允许验证后继续运行程序。好了,有了目标之后我们如何管理注册码呢?
放在资源里?放在程序里?这两种方法都不方便批量的分发。哪里呢?我选择jad里面:)分发的程序的jad里面有两个用户定义字段:
User: cakecSN: 8180076728b161326ae2cc61b783b451他们有什么用?看下去就明白了。大家是不是又想到一个问题,如何可以像前面的两个Protector一样使用简便
只需要判断一下check,又能在用户输入注册码后再继续运行呢?因为check判断和其它的startApp的初始工作在一个函数里面,难道有什么办法让函数停止执行?然而如果主进程停止了执行,我又怎么显示输入注册码的界面,响应用户的输入呢?思考10秒钟然后看我的方案:)看看你跟我想的是不是一样:利用midlet的生命周期。
大家知道midlet每次pause之后再次切换的时候系统会调用startApp函数,此时让check通过不就可以了。ok,下面来看实现:
首先是注册码输入界面SNInputUI:package vmlinux.app;
import javax.microedition.lcdui.*;
public class SNInputUI extends Form {
TextField tfUser_;
TextField tfSN_;public SNInputUI(){ super(StringManager.get("SNInputUI.Title"));tfUser_=new TextField(StringManager.get("SNInputUI.User"),"",20,TextField.ANY);tfSN_=new TextField(StringManager.get("SNInputUI.SN"),"",60,TextField.ANY);this.append(tfUser_);this.append(tfSN_);}public String getUser(){ return tfUser_.getString();}public String getSN(){ return tfSN_.getString();}}这个没有难度,不说了。
然后是SNProtector:我们需要使用新的UI来获取注册信息,所以构造函数是这样:
public SNProtector(MIDlet app)
{ super(app);ui_=new SNInputUI();cmdDone_=new Command(StringManager.get("SNProtector.Done"),Command.SCREEN,1);cmdTry_=new Command(StringManager.get("SNProtector.Try"),Command.SCREEN,2);ui_.addCommand(cmdDone_);ui_.addCommand(cmdTry_);}由于我们已经设置了基类Protector为CommandListener,所以需要改造一下基类:
修改Protector的commandAction并增加doCommand函数public void commandAction(Command c, Displayable d) {
if(c==cmdOK_)
app_.notifyDestroyed();elsedoCommand(c);}protected void doCommand(Command c)
{ }然后在SNProtector重写doCommand:
protected void doCommand(Command c)
{ if(c==cmdDone_){ 。。。}else if(c==cmdTry_){ 。。。}}当用户选择注册的时候,要做的工作就是把用户的输入保存起来。
如果用户选择了试用,就需要一个标志,说明用户要试用。做完这些工作我们还需要提醒用户暂停程序,然后再恢复程序以便达到我们重新调用startApp的目的。所以完整的doCommand就是这样:
protected void doCommand(Command c)
{ if(c==cmdDone_){ SNInputUI input=((SNInputUI)ui_);if(input.getUser().equals(app_.getAppProperty("User"))){ try{ RecordStore.deleteRecordStore(SNRMS);}catch(Exception ex){ //ignore}try{ RecordStore rs=RecordStore.openRecordStore(SNRMS,true);byte[] buf=input.getSN().getBytes();rs.addRecord(buf,0,buf.length);rs.closeRecordStore();}catch(Exception ex){ System.out.println(ex);}showAlert();}}else if(c==cmdTry_){ tryit=true;showAlert();}}现在已经把用户输入的注册码保存了起来,在决定命运的check函数里就需要
把保存的信息读出来然后对比判断是否有效,这个就是check函数:public boolean check()
{ if(tryit){ tryit=false;return true;}boolean r=true;try{ RecordStore rs=RecordStore.openRecordStore(SNRMS,true);RecordEnumeration e=rs.enumerateRecords(null,null,false);if(e.hasNextElement()){ r=checkCode(generate(app_.getAppProperty("User"),new String(e.nextRecord())));}else{ r=false;}rs.closeRecordStore();}catch(Exception ex){ r=false;}if(!r){ showUI();}return r;
}最后就是sn系统的核心checkCode和generate函数。
generate根据用户名和输入的注册码生成注册序列号然后checkCode比较生成的注册序列号和验证码得出结论。来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10294527/viewspace-126962/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/10294527/viewspace-126962/