Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
BeMor
Posts: 171
Registered: ‎08-20-2008
My Device: Not Specified

CoverageStatusListener

Hi All,

 

Has anyone got a working example of using CoverageStatusListener? Can see plenty of examples around for implementing checks to ensure data services and coverage is available before you route data but having concerns about users waiting for the 2 minute timeout if they loose coverage mid connection. I have created a class from an example I can no longer find which extends the Thread class and synchronises the input and output connections. I have tried implementing the CoverageStatusListener on this class getting the method coverageStatusChanged to close the stream along with a Dialog box prompting the users that they have lost MDS coverage. I have put the Dialog box under invoke later but no joy. Just one last question, is it right that the application and the whole Blackberry hangs while the connection is being performed? Many thanks in advance.

Please use plain text.
Developer
BeMor
Posts: 171
Registered: ‎08-20-2008
My Device: Not Specified

Re: CoverageStatusListener

Hi Again, Have sorted the freezing of the device. I corrected my code so it did run from separate thread. I did know you had to do this and thought I had but my Java is a bit rusty and I didn't implement the run method correctly so it was running on the UI thread. I am guessing that I may have to implement the CoverageStatusListner on the screen class that starts the connection thread and interrupt it if the device goes out of coverage. Anyway I will try this myself unless anyone can tell me a better way of doing this before I do.

 

There is still a big problem with my code. I have written an abstract class shown below that provides all the connectivity, all works well as much as can be expected so far apart from on the first connection you make you get a 401 error. The next connection you make works fine until the session expires and you get the 401 again. I have tried changing the order of the headers but with no joy. The server is Lotus Domino version 7 connecting to a WSDL webservice. If anyone can throw any light on this or have any suggestions on how I can improve the class below I'd be very grateful. :smileyhappy:

 

import java.lang.*; import java.io.*; import org.w3c.dom.*; import org.kobjects.base64.*; import org.xmlpull.v1.*; import javax.microedition.io.*; import net.rim.device.api.ui.component.*; import net.rim.device.api.ui.*; import net.rim.device.api.system.*; import java.lang.*; /** * */ public abstract class WSDLCon extends Thread { private InputStream input; private OutputStream output; private HttpConnection httpConn; private String envRequest; private StreamConnection streamConnection = null; private String soapAction = "\"\""; private String basicAuthPass; private boolean basicAuthBool = false; private String serviceURL; private String serviceHost; public int httpstatus; private final String ENV_HEADER = "" + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:DefaultNamespace\">\n" + "<soapenv:Header/>\n" + "<soapenv:Body>\n"; private final String ENV_FOOTER = "" + "</soapenv:Body>\n" + "</soapenv:Envelope>\n\n"; public WSDLCon(String envBody, String serviceURL, String serviceHost) { envRequest = ENV_HEADER + envBody + ENV_FOOTER; this.serviceURL = serviceURL; this.serviceHost = serviceHost; } public void run() { this.sendRequest(); } public void basicAuth(String userName, String password) { this.basicAuthPass = userName + ":" + password; this.basicAuthPass = Base64.encode(basicAuthPass.getBytes()); this.basicAuthBool = true; } public void sendRequest() { try { // Check coverage if (!CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_MDS)) { noCover(); return; } // init http connection with all necessary properties connect(); // do request output.write(envRequest.getBytes()); output.flush(); // receive reply receive(); } catch(java.io.IOException e){ System.err.println(e.toString()); } } private void noCover() { UiApplication.getUiApplication().invokeLater(new Runnable() // Run in UI thread when this thread is complete { public void run() { Dialog.ask(Dialog.D_OK,"No coverage found. Please ensure you have GPRS or 3G all in uppercase and try again."); } }); } public abstract void completed(); // What to do when whole process has completed public abstract void parseXMLStream(InputStream inputXML) throws XmlPullParserException, IOException; // handle the parsing private void setHttpProperties(HttpConnection httpConn) throws java.io.IOException { httpConn.setRequestProperty("Host", this.serviceHost); int envRequestLen = envRequest.length(); httpConn.setRequestProperty("Content-Length", Integer.toString(envRequestLen) ); httpConn.setRequestProperty("SOAPAction", this.soapAction); httpConn.setRequestProperty("Content-Type", "text/xml;charset=UTF-8"); httpConn.setRequestMethod(HttpConnection.POST); if (basicAuthBool) { httpConn.setRequestProperty("Authorization", "Basic " + this.basicAuthPass.toString()); } } private void connect() throws java.io.IOException { //This entire block is synchronized. synchronized(this) { //open the connection and extract the data streamConnection = (StreamConnection)Connector.open(serviceURL+";deviceside=false"); httpConn = (HttpConnection)streamConnection; setHttpProperties(httpConn); output = streamConnection.openOutputStream(); } } private void receive() throws java.io.IOException { synchronized(this) { input = streamConnection.openInputStream(); httpstatus = httpConn.getResponseCode(); if (httpstatus == HttpConnection.HTTP_OK) { try { parseXMLStream(input); } catch(org.xmlpull.v1.XmlPullParserException e){ System.err.println(e.toString()); } input.close(); output.close(); UiApplication.getUiApplication().invokeLater(new Runnable() // Run in UI thread when this thread is complete { public void run() { System.out.println("Running completed method..."); completed(); } }); } else { System.err.println("http connection problems: " + httpstatus); UiApplication.getUiApplication().invokeLater(new Runnable() // Run in UI thread when this thread is complete { public void run() { Dialog.ask(Dialog.D_OK,"Error: Connection error " + httpstatus + ". Please try again later."); } }); } streamConnection.close(); System.out.println("All closed...."); } // end synchronized } // end connect }

 

Please use plain text.
Developer
BeMor
Posts: 171
Registered: ‎08-20-2008
My Device: Not Specified

Re: CoverageStatusListener

Have been doing some packet sniffing on the web server that the web service is hosted on and can see that MDS seems to be either striping the Authorization header out altogether, modifying it to have a null username and password or at times passing the header as I set it. Seems to be an intermittent problem. Do I need to set the header differently so MDS doesn't mess with it? If anyone has any advice either on this problem or may be away to improve the class above please let me know. Cheers

Please use plain text.
Developer
BeMor
Posts: 171
Registered: ‎08-20-2008
My Device: Not Specified

Re: CoverageStatusListener

If I set 'Support HTTP Authentication' to false under the MDS service properties all seems to work okay without striping any headers. The only problem with this is that authentication to our Internet proxy then fails even though the credentials are set on the BES.
Please use plain text.