Search code examples
xmlhttpblackberrydownload

Downloading file from server


Here I am trying to download a file from the server onto the sdcard. The code is as shown below:

try{
   FileConnection fconn = (FileConnection)Connector.open("file:///SDCard/BlackBerry/documents/Report.xml");
   if (fconn.exists()) {
      fconn.delete();
   }

   fconn.create();
   add(new RichTextField("Deleted and created", Field.NON_FOCUSABLE));

   HttpConnection connection = (HttpConnection)        
   Connector.open("http://127.0.0.1/xml/home.xml");
   add(new RichTextField("Connection success", Field.NON_FOCUSABLE));
   InputStream ds = connection.openInputStream(); 
   byte[] data = new byte[ds.available()];
   ds.read(data);
   add(new RichTextField("Data read", Field.NON_FOCUSABLE));
   OutputStream outStream = fconn.openOutputStream();
   outStream.write(data);
   outStream.close();
   add(new RichTextField("Data written succesfully", Field.NON_FOCUSABLE));
   fconn.close();

   }
   catch (Exception e) {
   // TODO: handle exception
}

The problem is that on the emulatora I see the first two messages i.e.

  • Deleted and created
  • Connection success

But after, that no message is given that the data is written or not. The size of XML file is 1KB. Can please help me over this? Is there any problem in my code or is there another problem?


Solution

  • First of all, this line:

    add(new RichTextField("Deleted and created", Field.NON_FOCUSABLE));
    

    Makes me think you are doing this directly on the event thread, which is bad practice. If the connection times out or takes a long time, then you are freezing the GUI for that time. You would usually spawn a worker thread to do long tasks like this.

    That said, your code could work, but it is not really robust. A lot of things can go bad. For instance, this line:

    HttpConnection connection = (HttpConnection) Connector.open("http://127.0.0.1/xml/home.xml");
    

    The returned connection can be null so you must check for it. You'd better use ConnectionFactory instead as it appends the correct suffix for each kind of connection (WiFi, BES, TCP,...). In simulator, I'm not sure you can use a localhost URL since it is local to your workstation, but the simulated BB device has to go through an MDS simulator.

    With FileConnection you must also check it is not null, and also that fconn.canRead returns true. Take into account that not every device has an sdcard slot (most recent ones do). You could check if the card is available as it is explained in this article, or let the catch handle the exception. If you are testing on simulator, you'll have to "mount" a virtual sdcard.

    Also this call:

    ds.read(data);
    

    will block until the server actually sends you something. This is probably what is happening.

    You must check you have the correct permissions. For the file connection, you'll need:

    ApplicationPermissions.PERMISSION_FILE_API 
    

    And for the network connection, depending on where are you connecting to, you'll need one of:

    ApplicationPermissions.PERMISSION_INTERNET
    ApplicationPermissions.PERMISSION_SERVER_NETWORK
    

    A final tip: add a finally clause to the try-catch, and close all the streams and connections in the finally (in case they are not null).