1

在参考了大量的教程后,我终于设法为 Blackberry OS 7.0 开发了 java 推送客户端(在 RIM 和服务器端注册完全可以,这是服务器脚本)。现在程序在设备上运行,当新的推送消息恢复时,设备右上角有一个小箭头闪烁,但我没有太多知识在标签字段或任何其他 UI 组件中显示该消息。请告诉我如何在屏幕上显示恢复的推送消息。我是编程初学者,所以我没有那么多知识需要你的帮助。在这里,我发布了我使用过的所有代码。

这是应用程序类

import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.container.MainScreen;

/**
 * This class extends the UiApplication class, providing a
 * graphical user interface.
 */
public class MyApp extends UiApplication
{
public static void main(String[] args)
{
    //every time we start the application we register to BIS for push
    if (args.length > 0 && args[0].equals("BlackBerryCity")) {
        System.out.println("!!!!!!!!!!!!!!I am inside if");
        //registering for push
        Push_main.registerBpas();
        MyApp app = new MyApp();
        app.enterEventDispatcher();
    }

    //every time we restart the phone , we call this background process that is responsible for listening for push
    else {
        System.out.println("!!!!!!!!!!!!!!I am inside else");
        //should put the background classes for listening to pushed msgs :D
        BackgroundApplication backApp=new BackgroundApplication();
        backApp.setupBackgroundApplication(); 
        backApp.enterEventDispatcher();                 
    }                               
}

public MyApp(){
    pushScreen(new MyAppScreen());
}
}

class MyAppScreen extends MainScreen
{
public MyAppScreen()
{             
    // What to add here no idea :(
}
 }

push_main 类

public class Push_main {
private static final String REGISTER_SUCCESSFUL = "rc=200";
private static final String DEREGISTER_SUCCESSFUL = REGISTER_SUCCESSFUL;
private static final String USER_ALREADY_SUBSCRIBED = "rc=10003";
private static final String ALREADY_UNSUSCRIBED_BY_USER = "rc=10004";
private static final String ALREADY_UNSUSCRIBED_BY_PROVIDER = "rc=10005";

private static final String PUSH_PORT = ""+"XXXXXX";  //push port
private static final String BPAS_URL = "http://cpXXXX.pushapi.eval.blackberry.com";
private static final String APP_ID = ""+ "XXXX-XXXXXXXXXXXXXXXXXXXXXXXXXXX";   // add application id

private static String URL = "http://:"+ "XXXXXX"; //   add your push port.
private static final int CHUNK_SIZE = 256;                

public static ListeningThread _listeningThread;
public static StreamConnectionNotifier _notify;

private static final long ID = 0x954a603c0dee81e0L;

public Push_main(){
     if(_listeningThread==null)
        {
            System.out.println("msg on listening thread 1");        
            _listeningThread = new ListeningThread();
            System.out.println("msg on listening thread 2");
            _listeningThread.start();
            System.out.println("msg on listhning thread 3 ");       
        }         
}

public static class ListeningThread extends Thread
{
    private boolean _stop = false;

    /**
     * Stops the thread from listening.
     */
    private synchronized void stop()
    {
        _stop = true;
        try 
        {
            // Close the connection so the thread will return.
            _notify.close(); 
        } 
        catch (Exception e) 
        {          
        }          
    }

    /**
     * Listen for data from the HTTP url. After the data has been read, 
     * render the data onto the screen.
     * @see java.lang.Runnable#run()
     */    
    public void run()
    {    
        StreamConnection stream = null;
        InputStream input = null;
        MDSPushInputStream pushInputStream=null;

        while (!_stop)
        {
            try 
            {    
                // Synchronize here so that we don't end up creating a connection that is never closed.
                synchronized(this)  
                {
                    // Open the connection once (or re-open after an IOException),  so we don't end up 
                    // in a race condition, where a push is lost if it comes in before the connection 
                    // is open again. We open the url with a parameter that indicates that we should 
                    // always use MDS when attempting to connect.
                    System.out.println("\n\n msg connection 1");
                    _notify = (StreamConnectionNotifier)Connector.open(URL);
                    System.out.println("\n\n msg connection 2");

                }

                while (!_stop)
                {    
                    // NOTE: the following will block until data is received.
                    System.out.println("\n\n msg notify 1");
                    stream = _notify.acceptAndOpen();
                    System.out.println("\n\n msg 1 ");

                    try 
                    {
                        System.out.println("\n\n msg 2");
                        input = stream.openInputStream();
                        System.out.println("\n\n msg 3 ");

                        pushInputStream= new MDSPushInputStream((HttpServerConnection)stream, input);

                        System.out.println("\n\n msg 4");
                        // Extract the data from the input stream.

                        DataBuffer db = new DataBuffer();

                        byte[] data = new byte[CHUNK_SIZE];
                        int chunk = 0;

                        while ( -1 != (chunk = input.read(data)) )
                        {
                            db.write(data, 0, chunk);
                        }

                        updateMessage(data);

                        // This method is called to accept the push.
                        pushInputStream.accept();                          

                        data = db.getArray();
                    } 
                    catch (IOException e1) 
                    {
                        // A problem occurred with the input stream , however, the original 
                        // StreamConnectionNotifier is still valid.
                        //                          errorDialog(e1.toString());                   
                    }
                    finally
                    {
                        if ( input != null ) 
                        {
                            try 
                            {
                                input.close();
                            } 
                            catch (IOException e2) 
                            {                  

                            }
                        }

                        if ( stream != null )
                        {
                            try 
                            {
                                stream.close();
                            } 
                            catch (IOException e2) 
                            {                                    
                            }
                        }                                                 
                    }
                }                  
            } 
            catch (IOException ioe)
            {
                // Likely the stream was closed. Catches the exception thrown by 
                // _notify.acceptAndOpen() when this program exits.
                errorDialog(ioe.toString());        
            }
            finally
            {
                /*

                if ( _notify != null ) 
                {
                    try 
                    {
                        _notify.close();
                        _notify = null;
                    } 
                    catch ( IOException e ) 
                    {          

                    }
                }

                 */

            }
        }
    }
}

private static void updateMessage(final byte[] data)
{
    System.out.println("\n\n msg 6");

    Application.getApplication().invokeLater(new Runnable() 
    {
        public void run() 
        {
            // Query the user to load the received message.

            //              Dialog.alert( new String(data));


            UiApplication.getUiApplication().invokeLater( new Runnable() {
                public void run()
                {
                    NotificationsManager.triggerImmediateEvent(ID, 0, null, null);
                    Dialog d = new Dialog( Dialog.D_OK, new String(data) ,0, null, Screen.DEFAULT_CLOSE);
                    //                      _dialogShowing = true;
                    UiApplication.getUiApplication().pushGlobalScreen( d, 10, UiApplication.GLOBAL_MODAL );

                    // Dialog is closed at this point, so we cancel the event.                                        

                }
            } );        
        }    
    });
} 

public static void registerBpas() {

    /**
     * As the connection suffix is fixed I just use a Thread to call the connection code
     * 
     **/    
    new Thread() {
        public void run() {
            try {                   
                String registerUrl = formRegisterRequest(BPAS_URL, APP_ID, null) + ";deviceside=false;ConnectionType=mds-public";
                //Dialog.alert(registerUrl);
                if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)
                        && RadioInfo
                                .areWAFsSupported(RadioInfo.WAF_WLAN)) {
                    registerUrl += ";interface=wifi";
                }
                System.out.println("\n\n\n !!msg registerBPAS URL is:  "+ registerUrl + "\n\n");
                HttpConnection httpConnection = (HttpConnection) Connector.open(registerUrl);
                InputStream is = httpConnection.openInputStream();
                System.out.println("\n\n\n !!!!!!!!!!!I am here ");
                String response = new String(IOUtilities.streamToBytes(is));
                System.out.println("\n\n\n\n\n\n msg RESPOSE CODE :    " + response);
                System.out.println("\n\n\n !!!!!!!!!!!I am here2 ");
                httpConnection.close();
                String nextUrl = formRegisterRequest(BPAS_URL, APP_ID, response) + ";deviceside=false;ConnectionType=mds-public";
                System.out.println("\n\n\n\n\n\n msg nextUrl :    " + nextUrl);
                System.out.println("\n\n\n !!!!!!!!!!!I am here 3");
                if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)
                        && RadioInfo
                                .areWAFsSupported(RadioInfo.WAF_WLAN)) {
                    nextUrl += ";interface=wifi";
                    System.out.println("\n\n\n !!!!!!!!!!!I am here 4");
                }
                HttpConnection nextHttpConnection = (HttpConnection) Connector.open(nextUrl);
                InputStream nextInputStream = nextHttpConnection.openInputStream();
                response = new String(IOUtilities.streamToBytes(nextInputStream));
                System.out.println("\n\n\n !!!!!!!!!!!I am here 5");
                System.out.println("\n\n\n\n\n\n msg RESPOSE CODE 1:    " + response);
                nextHttpConnection.close();
                if (REGISTER_SUCCESSFUL.equals(response) || USER_ALREADY_SUBSCRIBED.equals(response)) {
                    Dialog.alert("msg Registered successfully for BIS push");

                    System.out.println("\n\n\n !!!!!!!!!!!I am here 6");
                    System.out.println("msg Registered successfully for BIS push");
                } else {
                    Dialog.alert("msg BPAS rejected registration");
                    System.out.println("msg BPAS rejected registration");
                }
            } catch (final IOException e) {
                Dialog.alert("msg IOException on register() " + e + " " + e.getMessage());
                System.out.println("msg IOException on register() " + e + " " + e.getMessage());
            }
        }
    }.start();
}

public static void close(Connection conn, InputStream is, OutputStream os) {
    if (os != null) {
        try {
            os.close();
        } catch (IOException e) {
        }
    }
    if (is != null) {
        try {
            is.close();
        } catch (IOException e) {
        }
    }
    if (conn != null) {
        try {
            conn.close();
        } catch (IOException e) {
        }
    }
}

public static void errorDialog(final String message)
{
    UiApplication.getUiApplication().invokeLater(new Runnable()
    {
        public void run()
        {
            Dialog.alert(message);
        } 
    });
}

private static String formRegisterRequest(String bpasUrl, String appId, String token) {
    StringBuffer sb = new StringBuffer(bpasUrl);
    sb.append("/mss/PD_subReg?");
    sb.append("serviceid=").append(appId);
    sb.append("&osversion=").append(DeviceInfo.getSoftwareVersion());
    sb.append("&model=").append(DeviceInfo.getDeviceName());
    if (token != null && token.length() > 0) {
        sb.append("&").append(token);
    }
    return sb.toString();
}
}

推送消息阅读器

public final class PushMessageReader {

//added by me
static String msgId;

// HTTP header property that carries unique push message ID
private static final String MESSAGE_ID_HEADER = "Push-Message-ID";
// content type constant for text messages
private static final String MESSAGE_TYPE_TEXT = "text";
// content type constant for image messages
private static final String MESSAGE_TYPE_IMAGE = "image";

private static final int MESSAGE_ID_HISTORY_LENGTH = 10;
private static String[] messageIdHistory = new String[MESSAGE_ID_HISTORY_LENGTH];
private static byte historyIndex;

private static byte[] buffer = new byte[15 * 1024];
private static byte[] imageBuffer = new byte[10 * 1024];

/**
 * Utility classes should have a private constructor.
 */
public PushMessageReader() {
}

/**
 * Reads the incoming push message from the given streams in the current thread and notifies controller to display the information.
 * 
 * @param pis
 *            the pis
 * @param conn
 *            the conn
 */
public static void process(PushInputStream pis, Connection conn) {
    System.out.println("Reading incoming push message ...");

    try {

        HttpServerConnection httpConn;
        if (conn instanceof HttpServerConnection) {
            httpConn = (HttpServerConnection) conn;
        } else {
            throw new IllegalArgumentException("Can not process non-http pushes, expected HttpServerConnection but have "
                    + conn.getClass().getName());
        }

        //changed here
        msgId = httpConn.getHeaderField(MESSAGE_ID_HEADER);
        String msgType = httpConn.getType();
        String encoding = httpConn.getEncoding();

        System.out.println("Message props: ID=" + msgId + ", Type=" + msgType + ", Encoding=" + encoding);

        boolean accept = true;
        if (!alreadyReceived(msgId)) {
            byte[] binaryData;

            if (msgId == null) {
                msgId = String.valueOf(System.currentTimeMillis());
            }

            if (msgType == null) {
                System.out.println("Message content type is NULL");
                accept = false;
            } else if (msgType.indexOf(MESSAGE_TYPE_TEXT) >= 0) {
                // a string
                int size = pis.read(buffer);
                binaryData = new byte[size];
                System.arraycopy(buffer, 0, binaryData, 0, size);                   
                // TODO report message
            } else if (msgType.indexOf(MESSAGE_TYPE_IMAGE) >= 0) {
                // an image in binary or Base64 encoding
                int size = pis.read(buffer);
                if (encoding != null && encoding.equalsIgnoreCase("base64")) {
                    // image is in Base64 encoding, decode it
                    Base64InputStream bis = new Base64InputStream(new ByteArrayInputStream(buffer, 0, size));
                    size = bis.read(imageBuffer);
                }
                binaryData = new byte[size];
                System.arraycopy(buffer, 0, binaryData, 0, size);                   
                // TODO report message
            } else {
                System.out.println("Unknown message type " + msgType);
                accept = false;
            }
        } else {
            System.out.println("Received duplicate message with ID " + msgId);
        }
        pis.accept();
    } catch (Exception e) {
        System.out.println("Failed to process push message: " + e);
    } finally {
        Push_main.close(conn, pis, null);
    }
}

/**
 * Check whether the message with this ID has been already received.
 * 
 * @param id
 *            the id
 * @return true, if successful
 */
private static boolean alreadyReceived(String id) {
    if (id == null) {
        return false;
    }

    if (Arrays.contains(messageIdHistory, id)) {
        return true;
    }

    // new ID, append to the history (oldest element will be eliminated)
    messageIdHistory[historyIndex++] = id;
    if (historyIndex >= MESSAGE_ID_HISTORY_LENGTH) {
        historyIndex = 0;
    }
    return false;
}

}

背景应用

public class BackgroundApplication extends Application {
public BackgroundApplication() {
    // TODO Auto-generated constructor stub
}
public void setupBackgroundApplication(){

    MessageReadingThread messageReadingThread = new MessageReadingThread();
    messageReadingThread.start();


}   

private static class MessageReadingThread extends Thread {

    private boolean running;
    private ServerSocketConnection socket;
    private HttpServerConnection conn;
    private InputStream inputStream;
    private PushInputStream pushInputStream;

    public MessageReadingThread() {
        this.running = true;
    }

    public void run() {

         String url = "http://:" + "XXXXXX" ;//here after the + add your port number
         url += ";deviceside=true;ConnectionType=mds-public";
         if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) && RadioInfo.areWAFsSupported(RadioInfo.WAF_WLAN)) {
            url += ";interface=wifi";
            }

        try {
            socket = (ServerSocketConnection) Connector.open( url );
        } catch( IOException ex ) {
            // can't open the port, probably taken by another application
            onListenError( ex );
        }

        while( running ) {
            try {
                Object o = socket.acceptAndOpen();
                conn = (HttpServerConnection) o;
                inputStream = conn.openInputStream();
                pushInputStream = new MDSPushInputStream( conn, inputStream );
                PushMessageReader.process( pushInputStream, conn );
            } catch( Exception e ) {
                if( running ) {
                  //  Logger.warn( "Failed to read push message, caused by " + e.getMessage() );
                    running = false;
                }
            } finally {
               // PushUtils.close( conn, pushInputStream, null );
            }
        }

      //  Logger.log( "Stopped listening for push messages" );
    }

    public void stopRunning() {
        running = false;
        //PushUtils.close( socket, null, null );
    }

    private void onListenError( final Exception ex ) {
       // Logger.warn( "Failed to open port, caused by " + ex );
      System.out.println(ex);
    }
}
}

我必须为主屏幕添加什么才能在即将到来的消息中显示?

先感谢您。

4

0 回答 0