2

我正在开发一个实现推送通知的 BB OS<7.X 应用程序。我终于得到了一些能够接收推送的工作代码。

但是,推送通知在我第一次在手机上部署应用程序时不起作用。如果我尝试在设备上发送推送,在我刚刚部署之后,当我从服务器发送推送时,我可以在设备的右上角看到一个小箭头正在加载,但没有推送消息显示在屏幕。

如果我重新启动设备,推送通知工作正常!!现在,每当我发送推送时,我都会在右上角再次看到小箭头,并且推送消息显示已更正。

代码如下所示(我认为重要的部分):

MyApp.java

   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()
        {             
             //some stuff here..
        }
     }

push_main.java

public class push_main {

/**
 * Entry point for this application
 * @param args Command line arguments (not used)
 */

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 = ""+"33387";  //push port
private static final String BPAS_URL = "http://pushapi.eval.blackberry.com";
private static final String APP_ID = ""+ "3592-M4587f9s9k836r930kO2395i32i66y10a34";   // add application id

private static String URL = "http://:"+ "33397"; //   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();
}
}

背景应用程序.java

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.io.Connector;
import javax.microedition.io.ServerSocketConnection;

import net.rim.device.api.io.http.HttpServerConnection;
import net.rim.device.api.io.http.MDSPushInputStream;
import net.rim.device.api.io.http.PushInputStream;
import net.rim.device.api.system.Application;
import net.rim.device.api.system.RadioInfo;
import net.rim.device.api.system.WLANInfo;

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://:" + "33387" ;//here after the + add your port number
             url += ";deviceside=false;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);
        }
    }

在主类MyApp.java上,您可以看到每次启动应用程序时,我都会注册推送。每次设备重启时,我都会启动一个后台进程来监听推送。或者至少,这就是我相信我在这里所做的。

我为什么要那么做?

我认为通过注册推送,后台监听器也会以某种方式启动......但我想它不会......这就是为什么当我重新启动手机时,这段代码被执行并且推送开始进入。

我该如何解决这个问题,以便我可以启动后台监听器:

  1. 首次部署应用程序

  2. 每次我重新启动设备

  3. 但不是在每次启动应用程序时。

4

0 回答 0