How to downloading Image in blackberry? 4.4/5 (87%) 11 votes

This tutorial describes how to download an image from remote server using HTTP over different network connections (Wi-Fi, WAP, and 3G).  The example I am going to demonstrate is using Observer design pattern which is listed under the Behavioral design patterns category from globally used Gang-Of-Four (GOF) patterns.

Overview of Observer Design pattern:

It is used to implement the Publisher/Subscriber scenario. We need a mechanism which allows us to notify subscriber objects whenever the publisher object changes state. For observers to receive a notification, they must implement some kind of update method/listeners which the subject can call whenever it changes state. The observers must have the freedom to register and un-register from subscription to the subject at any point in time.

Here in this example the subscriber object is the Blackberry UI thread and the publisher object is the Networking/Downloading thread. Network thread has to notify the UI thread once it complete or failed to download. And then the UI thread takes the control and updates the information in UI.

Steps:

1. Create and Blackberry UIApplication project
package com.javatechig.bb.java.ui;
import net.rim.device.api.ui.UiApplication;
public class DownloadMain extends UiApplication {
  public static void main(String[] args) {
          DownloadMain app = new DownloadMain();
         app.enterEventDispatcher();
 }
  public DownloadMain() {
         ImageDownloadScreen screen = new ImageDownloadScreen();
        pushScreen(screen);
  }
}
2. Create an “DownloadListener” interface to implement the listener functionality for the project. Here I am declaring two methods downloadSuccess() and errorOccured().
package com.javatechig.bb.java.ui;
import net.rim.device.api.system.Bitmap;
public interface DownloadListener {
       // invokes if download success
       public void downloadSuccess(Bitmap bitmap);

    // invokes if download failed
    public void errorOccured();
}
3. Create a Screen class and extends from MainScreen. This class will have the logic to implement all of the UI controls. Here in this example I am creating a button “Click to download”. My screen class is implementing the “DownloadListener” interface and overrides the downloadSuccess() and errorOccured() method. downloadSuccess() method used to perform all the UI activity, like update to UI if the download success. And errorOccured() method is for displaying the error message to UI if failed to download. Find the code below
package com.javatechig.bb.java.ui;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.UiApplication;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.Dialog;
import com.span.bb.java.net.ImageDownloader;
public class ImageDownloadScreen extends LoaderScreen implements DownloadListener{
    ImageDownloadScreen activeScreen = null;
    public ImageDownloadScreen() {
        setTitle("Download Image");
        ButtonField btn = new ButtonField("Click to Download", ButtonField.CONSUME_CLICK) {
            protected boolean navigationClick(int arg0, int arg1) {
                setShowLoader(true);
                //starting download thread
                ImageDownloader download = new ImageDownloader("http://www.ciracar.com/img/girls/cute_selena_gomez/cute_selena_gomez7.jpg");
                download.setDelegate(activeScreen);
                //Starting download thread
                new Thread(download).start();
                return true;
            }
        }
        ;
        //adding button to screen
        add(btn);
        //getting the reference of active screen
        activeScreen = this;
    }
    // Method to perform all the UI activity, like update to UI if the download success
    public void downloadSuccess(final Bitmap bitmap) {
        UiApplication.getUiApplication().invokeLater(new Runnable() {
            public void run() {
                setShowLoader(false);
                if (bitmap == null) {
                    Dialog.alert("Failed to download Image");
                }
                else {
                    try {
                        BitmapField image = new BitmapField(bitmap);
                        activeScreen.add(image);
                    }
                    catch (Exception e) {
                        Dialog.alert("Got error: " + e);
                    }
                }
            }
        }
        );
    }
    //display error message if error in download
    public void errorOccured() {
        //Currently not being used
        Dialog.alert("Failed to download Image");
    }
}
4. I am using a generic NetRequest class for separating all networking logic from the UI. Currently it has updateConnSuffix() method. This method updates the connection suffix required for different networks in blackberry. You can also write your logic and enhance this to prioritize the network connection usages. Find the code below
package com.javatechig.bb.java.net;
import net.rim.device.api.servicebook.ServiceBook;
import net.rim.device.api.servicebook.ServiceRecord;
import net.rim.device.api.system.DeviceInfo;
import net.rim.device.api.system.RadioInfo;
import net.rim.device.api.system.WLANInfo;
public class NetRequest {
    protected String updateConnSuffix() {
        String connSuffix = null;
        if (DeviceInfo.isSimulator()) {
            connSuffix = ";deviceside=true";
        }
        else if ((WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED)
        && RadioInfo.areWAFsSupported(RadioInfo.WAF_WLAN)) {
            connSuffix = ";interface=wifi";
        }
        else {
            String uid = null;
            ServiceBook sb = ServiceBook.getSB();
            ServiceRecord[] records = sb.findRecordsByCid("WPTCP");
            for (int i = 0; i < records.length; i++) {
                if (records[i].isValid() && !records[i].isDisabled()) {
                    if (records[i].getUid() != null
                    && records[i].getUid().length() != 0) {
                        if ((records[i].getCid().toLowerCase().indexOf("wptcp") != -1)
                        && (records[i].getUid().toLowerCase().indexOf(
                        "wifi") == -1)
                        && (records[i].getUid().toLowerCase().indexOf(
                        "mms") == -1)) {
                            uid = records[i].getUid();
                            break;
                        }
                    }
                }
            }
            if (uid != null) {
                // WAP2 Connection
                connSuffix = ";ConnectionUID=" + uid;
            }
            else {
                connSuffix = ";deviceside=true";
            }
        }
        return connSuffix;
    }
}
5. Declare “ImageDownloader” class to put all the downloading logic separately from UI. Here I am extending from NetRrquest as I want to reuse the “NetRequest” code for all of the networking logic we write. You can always open yourself to write in your own way. Find the code below
package com.javatechig.bb.java.net;
import java.io.IOException;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import com.javatechig.java.ui.DownloadListener;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.component.Dialog;
public class ImageDownloader extends NetRequest implements Runnable {
    // Holds the URL to download the image
    StringBuffer url = null;
    //holds the instance of the delegate screen
    protected Object delegate;
    public ImageDownloader(String url) {
        // image URL
        this.url = new StringBuffer();
        this.url.append(url.toString());
    }
    //taking the instance of the delegate
    //this is the object of the active screen from where the request is made
    public Object getDelegate() {
        return delegate;
    }
    public void setDelegate(Object delegate) {
        this.delegate = delegate;
    }
    // Thread starts the execution
    public void run() {
        byte[] dataArray;
        InputStream input;
        url.append(updateConnSuffix());
        HttpConnection httpConn = null;
        try {
            httpConn = (HttpConnection) Connector.open(url.toString());
            input = httpConn.openInputStream();
            dataArray = net.rim.device.api.io.IOUtilities.streamToBytes(input);
            final Bitmap googleImage = Bitmap.createBitmapFromBytes( dataArray, 0, -1, 1);
            ((DownloadListener) delegate).downloadSuccess(googleImage);
        }
        catch (IOException e) {
            e.printStackTrace();
            Dialog.alert("Eoor in downloading image");
        }
    }
}
6. Finally I want to show the loading progress in UI while the download is under progress. For this I have used a generic class “LoaderScreen” which extends MainScreen class. I am using “TimerTask” class for showing the loading animations.
package com.javatechig.bb.java.ui;
import java.util.Timer;
import java.util.TimerTask;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.container.MainScreen;
public class LoaderScreen extends MainScreen {
    Timer loadingTimer = new Timer();
    TimerTask loadingTask;
    int imageIndex = 0;
    Bitmap loader1 = Bitmap.getBitmapResource("loader001.png");
    Bitmap loader2 = Bitmap.getBitmapResource("loader002.png");
    Bitmap loader3 = Bitmap.getBitmapResource("loader003.png");
    Bitmap loader4 = Bitmap.getBitmapResource("loader004.png");
    Bitmap loader5 = Bitmap.getBitmapResource("loader005.png");
    Bitmap loader6 = Bitmap.getBitmapResource("loader006.png");
    Bitmap loader7 = Bitmap.getBitmapResource("loader007.png");
    Bitmap loader8 = Bitmap.getBitmapResource("loader008.png");
    Bitmap loader9 = Bitmap.getBitmapResource("loader009.png");
    Bitmap loader10 = Bitmap.getBitmapResource("loader010.png");
    Bitmap loader11 = Bitmap.getBitmapResource("loader011.png");
    Bitmap loader12 = Bitmap.getBitmapResource("loader012.png");
    boolean showLoader = false;
    int screenWidth = Display.getWidth();
    int screenHeight = Display.getHeight();
    int xAnchor = (screenWidth-200)/2;
    int yAnchor = (screenHeight-40)/2;
    String loaderText = "Please wait...";
    public LoaderScreen() {
        super();
        loadingTask = new TimerTask() {
            public void run() {
                invalidate();
                imageIndex++;
                if(imageIndex == 11){
                    imageIndex = 0;
                }
            }
        }
        ;
        loadingTimer.scheduleAtFixedRate(loadingTask, 100, 100);
    }
    public void setShowLoader(boolean showLoader) {
        this.showLoader = showLoader;
    }
    public boolean isShowing(){
        return showLoader;
    }
    protected void paint(Graphics graphics) {
        super.paint(graphics);
        if (showLoader) {
            //draw background:
            graphics.setColor(0x363636);
            graphics.fillRect(xAnchor, yAnchor, 200, 40);
            //draw animation frame:
            switch (imageIndex) {
                case 0:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader1, 0, 0);
                break;
                case 1:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader2, 0, 0);
                break;
                case 2:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader3, 0, 0);
                break;
                case 3:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader4, 0, 0);
                break;
                case 4:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader5, 0, 0);
                break;
                case 5:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader6, 0, 0);
                break;
                case 6:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader7, 0, 0);
                break;
                case 7:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader8, 0, 0);
                break;
                case 8:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader9, 0, 0);
                break;
                case 9:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader10, 0, 0);
                break;
                case 10:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader11, 0, 0);
                break;
                case 11:
                graphics.drawBitmap(xAnchor + 4, yAnchor + 4, 32, 32, loader12, 0, 0);
                break;
            }
            graphics.setColor(0xefefef);
            graphics.drawText(loaderText, xAnchor + 44, yAnchor + 6);
            graphics.setColor(0xff0000);
            graphics.drawRect(xAnchor, yAnchor, 200, 40);
        }
    }
}

I am using sequence of .png images for displaying the loading screen. You can find the images and complete source code from the Google code repository. Use this command to anonymously check out the latest project source code:

http://code.google.com/p/image-downloader-for-blackberry/

# Non-members may check out a read-only working copy anonymously over HTTP.

svn checkout http://image-downloader-for-blackberry.googlecode.com/svn/trunk/ image-downloader-for-blackberry-read-

About Javatechig

Javatechig has written 70 post in this blog.

Founder of Javatechig.com love Java, Android, Blackberry and other mobile development stuffs.

 

Tags: , ,