通过SMS-Push技术激活J2ME程序

      Push技术是一种通过异步方式将信息传送给设备并自动启动MIDlet程序的机制。通常进行网络连接时,客户端主动去连接服务器,服务器处理请求并返回给客户端响应,这是同步处理机制。而Push技术不同,它不需要应用程序通过“拉”的方式从网络中取得数据,应用程序需要的数据会被主动“推”向设备。当设备接收到信息时,相关的MIDlet会被激活并开始运行,处理发送过来的数据。注意:Push技术是MIDP2.0的一个可选项。

 

      Push机制可以通过如下两种方式激活MIDlet:

 

     1.通过inbound网络连接,就是基于接入的连接的通知。

 

     2.通过基于计时器的时钟,又称基于警告的通知。

 

 

      Push注册机制的行为可以被描述为如下三个步骤:

      1.MIDlet在移动设备中注册一个连同协议名称的端口,如果任何信息到达指定的端口,并且使用相同的协议,那么AMS就将它转交给MIDlet。注册使用Java ME应用程序描述符(JAD)文件静态的完成。程序也能使用应用程序内置的API执行动态注册。

       2. 从服务器,信息被发送到特定的移动设备,使用MIDlet应用程序注册监听的协议和端口。

       3. 在信息被传递到移动设备后,AMS调用注册了监听此端口和协议的MIDlet应用程序。一旦信息被转交到MIDlet,那么处理信息就是此应用程序的责任了。典型的,根据信息的信息的内容,一个应用程序会选择打开一个屏幕,并允许用户与服务器进行一些事务。

 

       在jad文件中,每一个push注册条目都包含如下信息:

 

       MIDlet-Push-<n>: <ConnectionURL>, <MIDletClassName>, <AllowedSender>。

       MIDlet-Push-<n>:push注册属性名称。MIDlet套件中可以包含多条push注册。<n>的数值从1开始,并且对于附加的条目必须使用连续的序数。第一个发现的缺失条目将中止列表。任何剩余的条目都会被忽略。


       ConnectionURL:被Connector.open()使用的连接字符串。

 

       MIDletClassName:负责连接的MIDlet。指定的MIDlet必须使用MIDlet-<n>记录在描述文件或jar文件的manifest中登记过。

 

       AllowedSender:一个指定的过滤器,        它将限制哪些发送者能够能正当启动请求的MIDlet。

 

       通过上面的简单介绍,下面进入正题。如果对上面的介绍需要更详细的了解,请自己google或百度一下。在进入开发之前,需要注意的要点是一条简单的SMS消息将不会激活MIDlet。我们必须发送SMS消息到MIDlet注册监听的特定的端口。因此被用来发送SMS消息的软件(或SMS服务提供商)必须能够将它发送到设备指定的端口。接下来开发一个实例程序,我们能够从一个Java服务器端应用程序发送一条SMS消息到一个移动电话的指定端口,并自动启动移动设备中的一个MIDlet。在这里我利用两个支持java的手机来作为测试。一个手机作为服务器端,另一个手机作为接收该SMS消息的客户端。

 

       1.首先开发客户端程序:

 

       为方便起见,这里直接使用J2ME Wireless Toolkit工具创建该程序。

 

       (1).点击新建工程图标。会打开一个弹出窗口;在那里你可以指定工程名称和MIDlet类名。在工程名称中输入 MySamplePushRegistryProject,在MIDlet类名中输入com.sample.MySamplePushRegistry。

 

       (2).继上个步骤完成之后,会自动出现另一个弹出窗口,它将允许你设定项目的其他设置。确保你在API 选择标签中。在此标签中,从目标平台下拉菜单中选择JTWI(如果还没有选择)。同样确保CLDC 1.0单选按钮被选中。不要钩选Mobile Media API多选框(因为不会使用任何跟多媒体有关的API)。

 

       (3).进入push注册标签。点击添加按钮。将会出现一个弹出窗口。在连接URL域中输入sms://:50001,在类域中输入com.sample.MySamplePushRegistry,在允许发送者域中输入*。在完成该步骤后,一个条目将会被加入到父窗口中。

 

       (4).进入许可标签。单击添加按钮。从许可树中选择javax/microedtion/io/Connector/sms并单击OK。重复相同的步骤来添加许可javax/wireless/messaging/sms/receive 和 javax/microedtion/io/PushRegistry。在完成该步骤后,三项许可将被添加到应用程序中。

 

       (5).进入用户定义标签。这里,我们添加用户定义的变量,这将包含SMS端口。从我们的程序,我们查阅此用户定义变量来读取SMS端口。在此标签中,单击添加按 钮。打开一个弹出窗口。输入SMS-Port作为属性名称。选择OK。出现了最初的弹出的窗口。输入50001作为SMS-Port的值。

 

       (6),一切设置完成之后,在设置窗口中单击OK。

 

       通过以上设置,就生成了一个jad文件。该文件路径就要看你的WTK的工程目录所在路径了。在该jad文件中,你会找到在前面步骤中设定的完整配置。所有条目中最重要的一个如下:

 

        MIDlet-Push-1: sms://:50001,com.smaple.MySamplePushRegistry, *.

 

        此条目确保你的应用程序监听50001端口上的SMS消息。

 

        配置完成之后,这里我们做一个接收消息的类,该消息是服务器端通过SMS发送过来的。

 

import javax.microedition.midlet.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import javax.wireless.messaging.*;

import java.io.*;


public class MySamplePushRegistry extends MIDlet
   implements CommandListener, Runnable, MessageListener {

    /** user interface command for indicating Exit request. */
    Command exitCommand  = new Command("Exit", Command.EXIT, 1);
    /** user interface text box for the contents of the fetched URL. */
    Alert content;
    /** current display. */
    Display display;
    /** instance of a thread for asynchronous networking and user interface. */
    Thread thread;
    /** The port on which we listen for SMS messages */
    String smsPort;
    /** SMS message connection for inbound text messages. */
    MessageConnection smsconn;
    /** Current message read from the network. */
    Message msg;
    /** The screen to display when we return from being paused */
    Displayable resumeScreen;

    public MySamplePushRegistry() {

        display = Display.getDisplay(this);

        content = new Alert("SMS Receive");
        content.setTimeout(Alert.FOREVER);
        content.addCommand(exitCommand);
        content.setCommandListener(this);
        content.setString("Receiving...");

        resumeScreen = content;
    }

   public void startApp() {
      smsPort = getAppProperty("SMS-Port");
      String smsConnection = "sms://:" + smsPort;
      //System.out.println(smsConnection);
      if (smsconn == null) {
         try {
            smsconn = (MessageConnection)
               Connector.open(smsConnection);
            smsconn.setMessageListener(this);
         } catch (IOException ioe) {
            ioe.printStackTrace();
         }
      }
      display.setCurrent(resumeScreen);
   }
   public void notifyIncomingMessage(MessageConnection conn) {
      if (thread == null) {
         thread = new Thread(this);
         thread.start();
      }
   }
   public void run() {
      try {
         msg = smsconn.receive();
         if (msg != null) {
            if (msg instanceof TextMessage) {
               content.setString(((TextMessage)msg).getPayloadText());
            }
            display.setCurrent(content);
         }
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
   //other methods to follow
    public void destroyApp(boolean unconditional) {
        thread = null;
        if (smsconn != null) {
            try {
                smsconn.close();
            } catch (IOException e) {
                // Ignore any errors on shutdown
            }
        }
    }
    public void pauseApp() {
        thread = null;
        resumeScreen = display.getCurrent();
    }

    /**
     * Respond to commands, including exit
     * @param c user interface command requested
     * @param s screen object initiating the request
     */
    public void commandAction(Command c, Displayable s) {
        try {
            if (c == exitCommand || c == Alert.DISMISS_COMMAND) {
                destroyApp(false);
                notifyDestroyed();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

 

 

       客户端开发完成之后,接下来开发服务器端:

 

       服务器端,我们通过调用J2ME中的jsr75包里的SMS相关类来发送指定端口的消息,代码如下: 

 

       import javax.microedition.io.Connector;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.TextField;
import javax.wireless.messaging.MessageConnection;
import javax.wireless.messaging.TextMessage;


public class smsDemo extends Form implements CommandListener{

    private final smsMIDlet sms;
    private TextField textMesg;
    private String strMesg;
    private String port="";
    private TextField dest;
    private String strDest;
    private Command send1Command;
    public smsDemo(smsMIDlet MIDlet) {
        // TODO Auto-generated constructor stub
        super("短消息");
        this.sms = MIDlet;
        //发送目的地
        dest = new TextField("电话号码", "",20, TextField.PHONENUMBER);
        //消息内容
        textMesg = new TextField("发送内容", "",100, TextField.ANY);
       
        append( dest );
        append( textMesg );
       
        send1Command  = new Command("发送",Command.SCREEN, 2);
       
        addCommand(send1Command);
        setCommandListener(this);//注册监听事件
       
    }
    public void commandAction(Command arg0, Displayable arg1) {
        // TODO Auto-generated method stub
        if (arg0 == send1Command) {
            try {
                 strDest = dest.getString();
                 strMesg = textMesg.getString();
                
                 Thread fetchThread=new Thread(){
                     public void run(){
                          try
                          {
                                 String addr = "sms://" + strDest + ":50001";
                                 System.out.println("发送地址为:" + addr);
                                 //建立连接
                                 MessageConnection conn =(MessageConnection) Connector.open(addr);
                                 //设置短信息类型为文本,短信息有文本和二进制两种类型
                                 TextMessage msg =

                                              (TextMessage) conn.newMessage(MessageConnection.TEXT_MESSAGE);
                                 //设置信息内容
                                 System.out.println("发送消息为:" + strMesg);
                                 msg.setPayloadText( strMesg );
                                 //发送信息
                                 conn.send(msg);
                                 //关闭连接
                                 conn.close();
                          }
                          catch(Exception exc)
                          {
                           exc.printStackTrace();
                          }
                         }
                 };
                
                 fetchThread.start();//启动线程
                
            }catch (Exception e) {
               System.out.print("Error in start/n");
               e.printStackTrace();
             }
        }

    }
}

        服务器端的代码也开发完成了,接下来是通过将其发布到真机上运行,测试效果。

 

        在发布到真机之前,需要将上面的客户端和服务器端的代码分别打包成jar文件,并分别发布到两个手机上。发布可以通过OTA,也可以通过拷贝到手机上再安装。注意通过拷贝来安装的时候将jad文件也拷贝进去,jad文件记录了jar文件的相关配置属性。在安装时,注意通过jad来安装jar。

 

        两个手机都安装完成之后,通过装有服务器端程序的手机进入我们自己开发的发送短信界面,输入装有客户端程序的手机号码,并输入发送内容。点击发送,如果一切正常,那么客户端的MIDlet就应该被触发了,并弹出提示是否运行该程序,如果看到这个界面,那么点击确定后,可以看到服务器端的消息就被发送到客户端来了。到此,SMS-Push技术就算是成功了。

 

        注意:

 

         1.服务器端发送短信的界面没有做发送成功的提示,也没有做退出界面,因此在点击发送按钮之后,没有任何提示。

 

         2.在安装客户端jar包时,安装完成之后,无需运行jar包,否则看不到SMS-Push的效果。

 

         最后该文章细节来自于http://www.cnblogs.com/bluespot/archive/2008/08/02/1258735.html,有不清楚的地方请查看该网址。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值