listfield with bitmap loaded from server - blackberry

i have made a listfield with images, the listfield is parsed from online xml file.
it seems that downloading the images into the listfield is blocking the process of parsing the content of the listfield "text" , i want to show the content of the listfield "text" and then start to proccess the download of the images and then show the images.
here is the code to call the downloader class:
Thread t = new Thread();
{
String imageFilename = imageurlStrin.substring(imageurlStrin.lastIndexOf('/') + 1);
String saveDire = "file:///store/home/user/pictures/listfield/"+imageFilename;
try {
FileConnection fconn = (FileConnection)Connector.open(saveDire);
if (fconn.exists()) {
// do nothing
}
if (!fconn.exists()) {
UrlToImage bit = new UrlToImage(imageurlStrin);
pic = bit.getbitmap();
}
}catch (Exception ioe) {
System.out.println("error 18");
}
};
t.start();
and this is the downloader class code:
public class UrlToImage implements Runnable{
String imageurlStrin=null;
BitmapDowloadListener listener=null;
public static Bitmap _bmap;
private EncodedImage eih1;
public void run() {
UrlToImage bit = new UrlToImage(imageurlStrin);
}
public UrlToImage(String imageurlStrin)
{
HttpConnection connection = null;
InputStream inputStream = null;
EncodedImage bitmap;
byte[] dataArray = null;
//byte[] data1 = null;
try
{
connection = (HttpConnection) Connector.open(imageurlStrin, Connector.READ, true);
inputStream = connection.openInputStream();
byte[] responseData = new byte[10000];
int length = 0;
StringBuffer rawResponse = new StringBuffer();
while (-1 != (length = inputStream.read(responseData)))
{
rawResponse.append(new String(responseData, 0, length));
}
int responseCode = connection.getResponseCode();
if (responseCode != HttpConnection.HTTP_OK)
{
throw new IOException("HTTP response code: "
+ responseCode);
}
final String result = rawResponse.toString();
dataArray = result.getBytes();
}
catch (final Exception ex)
{ }
finally
{
try
{
inputStream.close();
inputStream = null;
connection.close();
connection = null;
}
catch(Exception e){}
}
bitmap = EncodedImage.createEncodedImage(dataArray, 0,dataArray.length);
// this will scale your image acc. to your height and width of bitmapfield
int multH;
int multW;
int currHeight = bitmap.getHeight();
int currWidth = bitmap.getWidth();
int scrhi = Display.getWidth()/4;
int scrwe = Display.getWidth()/4;
multH= Fixed32.div(Fixed32.toFP(currHeight),Fixed32.toFP(scrhi));//height
multW = Fixed32.div(Fixed32.toFP(currWidth),Fixed32.toFP(scrwe));//width
bitmap = bitmap.scaleImage32(multW,multH);
Bitmap thefinal = bitmap.getBitmap();
//url = StringUtils.replaceAll(url ,"http://u.bbstars.com/i-", "");
final String imageFilename = imageurlStrin.substring(imageurlStrin.lastIndexOf('/') + 1);
String saveDire = "file:///store/home/user/pictures/listfield/"+imageFilename;
String Dire = "file:///store/home/user/pictures/listfield/";
JPEGEncodedImage finalJPEG = JPEGEncodedImage.encode(thefinal, 100);
byte[] raw_media_bytes = finalJPEG.getData();
int raw_length = finalJPEG.getLength();
int raw_offset = finalJPEG.getOffset();
FileConnection filecon = null;
OutputStream out = null;
try {
filecon = (FileConnection) Connector.open(Dire,Connector.READ_WRITE);
if(!filecon.exists()){
filecon.mkdir();
}
filecon = (FileConnection) Connector.open(saveDire,Connector.READ_WRITE);
if(!filecon.exists()){
filecon.create();
}
out = filecon.openOutputStream();
out.write(raw_media_bytes, raw_offset, raw_length);
out.close();
filecon.close();
System.out.println("----------------file saved"+imageFilename);
} catch (IOException e) {
System.out.println("---------------===================- error saving the file");
};
try {
FileConnection fconn = (FileConnection)Connector.open(saveDire);
if (fconn.exists()) {
InputStream input = fconn.openInputStream();
int available = input.available();
final byte[] data1=IOUtilities.streamToBytes(input);
input.read(data1, 0, available);
eih1 = EncodedImage.createEncodedImage(data1,0,data1.length);
}
}catch (Exception ioe) {
System.out.println("error gettin bitmap details from the piture");
}
_bmap=eih1.getBitmap();
}
public Bitmap getbitmap()
{
return _bmap;
}
}
what should i do to prevent UI blocking, i want the perfect why to call that downloader class without stoping the process of parsing the other listfield content?

I think you may just have a simple syntax problem with the way you declared your thread object. See the BlackBerry documentation on Thread here
When you create a Thread, you normally either extend the Thread class with a subclass of your own, that implements the run() method, or you pass a new Runnable object in to the constructor of your Thread object. In your code, you actually declare a Thread instance, and create it, but do not give it a Runnable, or override the default run() method. So, this thread won't do anything in the background.
You have essentially declared a chunk of code within a local scope. That's what happens if you just put some code within a set of curly brackets ({ and }) that are not attached to anything:
Thread t = new Thread();
// this next curly bracket starts a "local scope". it is NOT part of Thread t!
{
String imageFilename = imageurlStrin.substring(imageurlStrin.lastIndexOf('/') + 1);
// The rest of your code here will not be executed on Thread t. It will be executed
// on the thread where you instantiate Thread t, right before you call t.start();
// If this code is called on the main/UI thread (which it probably is), then the
// network request will block the UI thread, which will stop the loading of the rest
// of the list.
};
t.start();
What you probably want is this:
Thread t = new Thread(new Runnable() {
public void run() {
String imageFilename = imageurlStrin.substring(imageurlStrin.lastIndexOf('/') + 1);
String saveDire = "file:///store/home/user/pictures/listfield/"+imageFilename;
try {
FileConnection fconn = (FileConnection)Connector.open(saveDire);
if (fconn.exists()) {
// do nothing
}
if (!fconn.exists()) {
UrlToImage bit = new UrlToImage(imageurlStrin);
pic = bit.getbitmap();
}
} catch (Exception ioe) {
System.out.println("error 18");
}
}
});
t.start();
Try that, and see if that fixes the problem.

Related

Android Studio, downloading image form url/app has stopped working

Hi could you help me find out why my app stops working when I want to download image from url, here is the code
public void getOnClick(View view) throws IOException {
urlAdress = new URL("http://www.cosmeticsurgerytruth.com/blog/wp- content/uploads/2010/11/Capri.jpg");
InputStream is = urlAdress.openStream();
filename = Uri.parse(urlAdress.toString()).getLastPathSegment();
outputFile = new File(context.getCacheDir(),filename);
OutputStream os = new FileOutputStream(outputFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
is.close();
os.close();
I was also trying to use some code from similar topics but I get same message
Your app has stopped working
and it shuts down
Caused by: android.os.NetworkOnMainThreadException
The problem is that you are trying to download the image from the UIThread. You have to create a class which extends to AsyncTask class and make the download on the doInBackground method
private class DownloadAsync extends AsyncTask<Void, Void, Void> {
private Context context;
DownloadAsync(Context context) {
this.context = context;
}
#Override
protected Void doInBackground(Void... params) {
try {
URL urlAdress = urlAdress = new URL("http://www.cosmeticsurgerytruth.com/blog/wp- content/uploads/2010/11/Capri.jpg");
InputStream is = urlAdress.openStream();
String filename = Uri.parse(urlAdress.toString()).getLastPathSegment();
File outputFile = new File(context.getCacheDir(), filename);
OutputStream os = new FileOutputStream(outputFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
is.close();
os.close();
return null;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Then you can execute like this
public void getOnClick(View view){
new DownloadAsync(this).execute();
}

URL Read CodeName One

I'm relatively new to Codename One. I'm trying to read an URL and save the content on a String. I tried:
private String lectura = "";
private String escritura = "";
/*-------------------------------------------------------
* Methods
*-------------------------------------------------------
*/
public Bulbs(int i, char rtype){
type = rtype;
number = i;
status = readCNO(type, number);
}
public String giveStatus(){
status = readCNO(type, number);
return status;
}
public void turnBulbOn(){
writeCNO('B', number, 1);
}
public void turnBulbOff(){
writeCNO('B', number, 0);
}
public String readCNO(char type, int number){
ConnectionRequest r = new ConnectionRequest();
r.setUrl("http://192.168.1.3/arduino/R!" + type + "/" + Integer.toString(number));
r.setPost(false);
r.addResponseListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
try
{
NetworkEvent event = (NetworkEvent) ev;
byte[] data= (byte[]) event.getMetaData();
String decodedData = new String(data,"UTF-8");
System.out.println(decodedData);
lectura = decodedData;
} catch (Exception ex)
{
ex.printStackTrace();
lectura = "NoBulb";
}
}
});
NetworkManager.getInstance().addToQueue(r);
return lectura;
}
public String writeCNO(char type, int number, int action){
ConnectionRequest r2 = new ConnectionRequest();
r2.setUrl("http://192.168.1.3/arduino/R!" + type + "/" + Integer.toString(number) + "/"+ action);
r2.setPost(false);
r2.addResponseListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
try
{
NetworkEvent event = (NetworkEvent) ev;
byte[] data= (byte[]) event.getMetaData();
String decodedData = new String(data,"UTF-8");
System.out.println(decodedData);
escritura = decodedData;
} catch (Exception ex)
{
ex.printStackTrace();
escritura = "NoBulb";
}
}
});
NetworkManager.getInstance().addToQueue(r2);
return escritura;
}
However when I run it, the Console displays a bunch of errors like:
Duplicate entry in the queue: com.codename1.io.ConnectionRequest: com.codename1.io.ConnectionRequest#22b3c488
Help very appreciated!
David.
You are adding the exact same URL to the queue twice which Codename One detects as a probable mistake. If this is intentional just invoke setDuplicateSupported(true) on both connection requests.

Error while downloading & saving image to sd card in blackberry?

I am working on blackberry project where i want to download image & save it in sd card in blackberry. By going through many sites i got some code & based on that i wrote the program but when it is executed the output screen is displaying a blank page with out any response. The code i am following is..
code:
public class BitmapDemo extends UiApplication
{
public static void main(String[] args)
{
BitmapDemo app = new BitmapDemo();
app.enterEventDispatcher();
}
public BitmapDemo()
{
pushScreen(new BitmapDemoScreen());
}
static class BitmapDemoScreen extends MainScreen
{
private static final String LABEL_X = " x ";
BitmapDemoScreen()
{
//BitmapField bmpFld1=new BitmapField(connectServerForImage("http://images03.olx.in/ui/3/20/99/45761199_1.jpg"));
//add(bmpFld1);
setTitle("Bitmap Demo");
// method for saving image in sd card
copyFile();
// Add a menu item to display an animation in a popup screen
MenuItem showAnimation = new MenuItem(new StringProvider("Show Animation"), 0x230010, 0);
showAnimation.setCommand(new Command(new CommandHandler()
{
public void execute(ReadOnlyCommandMetadata metadata, Object context)
{
// Create an EncodedImage object to contain an animated
// gif resource.
EncodedImage encodedImage = EncodedImage.getEncodedImageResource("animation.gif");
// Create a BitmapField to contain the animation
BitmapField bitmapFieldAnimation = new BitmapField();
bitmapFieldAnimation.setImage(encodedImage);
// Push a popup screen containing the BitmapField onto the
// display stack.
UiApplication.getUiApplication().pushScreen(new BitmapDemoPopup(bitmapFieldAnimation));
}
}));
addMenuItem(showAnimation);
}
private static class BitmapDemoPopup extends PopupScreen
{
public BitmapDemoPopup(BitmapField bitmapField)
{
super(new VerticalFieldManager());
add(bitmapField);
}
protected boolean keyChar(char c, int status, int time)
{
if(c == Characters.ESCAPE)
{
close();
}
return super.keyChar(c, status, time);
}
}
}
public static Bitmap connectServerForImage(String url) {
System.out.println("image url is:"+url);
HttpConnection httpConnection = null;
DataOutputStream httpDataOutput = null;
InputStream httpInput = null;
int rc;
Bitmap bitmp = null;
try {
httpConnection = (HttpConnection) Connector.open(url,Connector.READ_WRITE);
rc = httpConnection.getResponseCode();
if (rc != HttpConnection.HTTP_OK) {
throw new IOException("HTTP response code: " + rc);
}
httpInput = httpConnection.openInputStream();
InputStream inp = httpInput;
byte[] b = IOUtilities.streamToBytes(inp);
EncodedImage hai = EncodedImage.createEncodedImage(b, 0, b.length);
return hai.getBitmap();
} catch (Exception ex) {
System.out.println("URL Bitmap Error........" + ex.getMessage());
} finally {
try {
if (httpInput != null)
httpInput.close();
if (httpDataOutput != null)
httpDataOutput.close();
if (httpConnection != null)
httpConnection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return bitmp;
}
public static void copyFile() {
// TODO Auto-generated method stub
EncodedImage encImage = EncodedImage.getEncodedImageResource("rim.png");
byte[] image = encImage.getData();
try {
// Create folder if not already created
FileConnection fc = (FileConnection)Connector.open("file:///SDCard/BlackBerry/images/");
if (!fc.exists())
fc.mkdir();
fc.close();
// Create file
fc = (FileConnection)Connector.open("file:///SDCard/BlackBerry/images/" + image, Connector.READ_WRITE);
if (!fc.exists())
fc.create();
OutputStream outStream = fc.openOutputStream();
outStream.write(image);
outStream.close();
fc.close();
System.out.println("image saved.....");
} catch (Exception e) {
// TODO: handle exception
//System.out.println("exception is "+ e);
}
}
}
This is the code which i am using. Not getting any response except blank page.. As i am new to blackberry development unable to find out what is the problem with my code. Can anyone please help me with this...... Actually i am having other doubt as like android & iphone does in blackberry simulator supports for SD card otherwise we need to add any SD card slots for this externally...
Waiting for your reply.....
To simply download and save that image to the SDCard, you can use this code. I changed your SDCard path to use the pictures folder, which I think is the standard location on BlackBerrys. If you really want to store it in images, you may just need to create the folder if it doesn't already exist.
package com.mycompany;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.io.file.FileConnection;
public class DownloadHelper implements Runnable {
private String _url;
public DownloadHelper(String url) {
_url = url;
}
public void run() {
HttpConnection connection = null;
OutputStream output = null;
InputStream input = null;
try {
// Open a HTTP connection to the webserver
connection = (HttpConnection) Connector.open(_url);
// Getting the response code will open the connection, send the request,
// and read the HTTP response headers. The headers are stored until requested.
if (connection.getResponseCode() == HttpConnection.HTTP_OK) {
input = new DataInputStream(connection.openInputStream());
int len = (int) connection.getLength(); // Get the content length
if (len > 0) {
// Save the download as a local file, named the same as in the URL
String filename = _url.substring(_url.lastIndexOf('/') + 1);
FileConnection outputFile = (FileConnection) Connector.open("file:///SDCard/BlackBerry/pictures/" + filename,
Connector.READ_WRITE);
if (!outputFile.exists()) {
outputFile.create();
}
// This is probably not a robust check ...
if (len <= outputFile.availableSize()) {
output = outputFile.openDataOutputStream();
// We'll read and write this many bytes at a time until complete
int maxRead = 1024;
byte[] buffer = new byte[maxRead];
int bytesRead;
for (;;) {
bytesRead = input.read(buffer);
if (bytesRead <= 0) {
break;
}
output.write(buffer, 0, bytesRead);
}
output.close();
}
}
}
} catch (java.io.IOException ioe) {
ioe.printStackTrace();
} finally {
try {
if (output != null) {
output.close();
}
if (connection != null) {
connection.close();
}
if (input != null) {
input.close();
}
} catch (IOException e) {
// do nothing
}
}
}
}
This class can download an image in the background, as I suggested. To use it, you can start a worker thread like this:
DownloadHelper downloader = new DownloadHelper("http://images03.olx.in/ui/3/20/99/45761199_1.jpg");
Thread worker = new Thread(downloader);
worker.start();
This will save the file as /SDCard/BlackBerry/pictures/45761199_1.jpg. I tested it on a 5.0 Storm simulator.
There are several problems with the code posted. It's also not completely clear what you're trying to do. From the question title, I assume you want to download a jpg image from the internet, and display it.
1) You implement a method called connectServerForImage() to download an image, but then it's commented out. So, the method isn't going to download anything if it's not called.
2) Even if it's uncommented, connectServerForImage() is called here
BitmapField bmpFld1=new BitmapField(connectServerForImage("http://images03.olx.in/ui/3/20/99/45761199_1.jpg"));
This will block the main (UI) thread while it downloads your image. Even though you can do it this way, it's not a good thing to do. Instead, you could create a Thread to download the image as a background task, and then use UiApplication.invokeLater() to load the image into your BitmapField on the main/UI thread.
3) Your copyFile() method tries to copy a file named rim.png, which must be an image bundled with your application, and saves it to the SDCard. Is this really what you want? Do you want to save the downloaded image instead? This method doesn't seem to be connected to anything else. It's not saving the image downloaded from the internet, and the image it does save is never used anywhere else.
4) In copyFile(), this line
fc = (FileConnection)Connector.open("file:///SDCard/BlackBerry/images/" + image, Connector.READ_WRITE);
is passing a byte[] in as part of the filename to open (your variable named image). You should probably be adding a String name to the end of your SDCard path. As the code is, it's probably opening a file in the /SDCard/BlackBerry/images/ folder with a very long name that looks like a number. Or it might fail entirely, if there are limits on the length of filenames.
5) In Java, it's not usually a good idea to make everything static. Static should normally be used for constants, and for a very few methods like the main() method, which must be static.
Try to clean these things up, and then repost the code, and we can try to help you with your problem. Thanks.

BlackBerry: Creat Bitmap object from SD card image

Can we create an Bitmap object from the SD card image file path ?
I have written a sample method to create it. Is it right approach?
public Bitmap createBitmap(String filepath){
try {
// filepath e.g. "file:///SDCard/test.jpg"
FileConnection fc = (FileConnection)Connector.open(filepath);
byte[] responseData = new byte[10000];
InputStream inputStream =fc.openDataInputStream();
int length = 0;
StringBuffer rawResponse = new StringBuffer();
while (-1 != (length = inputStream.read(responseData))) {
rawResponse.append(new String(responseData, 0, length));
}
byte[] dataArray = rawResponse.toString().getBytes();
Bitmap bitmap = Bitmap.createBitmapFromBytes(dataArray, 0, dataArray.length, 1);
// EncodedImage.createEncodedImage(dataArray, 0, dataArray.length);
return bitmap;
} catch (IOException e) {
return null;
// TODO Auto-generated catch block
// e.printStackTrace();
}
}
public final class MyScreen extends MainScreen {
Bitmap bit, bit1;
BitmapField bitf[] = new BitmapField[12];
FileConnection fc;
FlowFieldManager grid;
String[] imgpath = { "bharat.png", "fighter1.jpg", "fighter2.jpg",
"fighter3.jpg", "fighter4.jpg", "fighter5.jpg", "fighter7.jpg",
"fighter8.jpg", "fighter9.jpg", "fighter10.jpg", "fighter11.jpg",
"fighter6.jpg" };
String compath = "file:///SDCard/";`enter code here`
public MyScreen() {
grid = new FlowFieldManager();
try {
setTitle("Bharat Title");
for (int i = 0; i < imgpath.length; i++) {
fc = (FileConnection) Connector.open(compath + imgpath[i]);
DataInputStream in = fc.openDataInputStream();
int size = (int) fc.fileSize();
byte[] bb = new byte[size];
bb = IOUtilities.streamToBytes(in);
bit = bit.createBitmapFromBytes(bb, 0, bb.length, 1);
bit1 = new Bitmap(120, 120);
bit.scaleInto(bit1, Bitmap.FILTER_BOX);
bitf[i] = new BitmapField(bit1, FOCUSABLE);
grid.add(bitf[i]);
fc.close();
}
}
catch (Exception ex)
{
ex.getMessage();
}
finally {
try {
fc.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
add(grid);
}
}

Return the correct value from a JavaME thread

I wrote a function which returns a string. And there is a Thread implementation the function, like follows, and I am calling [metaDataTrimmed = getMetaData(url);] this function and store the return value to a string value. My problem is the the function immediately returns the null string, which is its initial value. And I checked my function works properly.
So I try for a Thread.sleep() method using a dirtybit and also tried for Thread.join(). Is there any standard method in BlackBerry to solve the problem, if not what is a good approach to solve the problem?
private String getMetaData(final String mediaUrl){
String metaDataT = "";
Thread metaThread = new Thread(new Runnable(){
public void run(){
try {
StreamConnection streamConnection=null;
HttpConnection httpConnection = null;
InputStream inputStream =null;
streamConnection=(StreamConnection)Connector.open(mediaUrl);
httpConnection=(HttpConnection)streamConnection;
httpConnection.setRequestProperty("Icy-metadata", "1");
int httpStatus=httpConnection.getResponseCode();
if(httpStatus==HttpConnection.HTTP_OK){
String mint = httpConnection.getHeaderField("icy-metaint");
inputStream = streamConnection.openInputStream();
int length= Integer.parseInt(mint);
int b = 0;
int count =0;
while(count++ < length){
b = inputStream.read();
}
int metalength = ((int)b)*16;
// if(metalength <= 0){waitBitMetaData = 1;return;}
byte buf[] = new byte[metalength];
inputStream.read(buf,0,buf.length);
String metaData = new String(buf);
int streamTilleIndex = metaData.indexOf("StreamTitle");
// if(streamTilleIndex <= 0){waitBitMetaData = 1;return;}
String streamTille = metaData.substring(streamTilleIndex);
int eqindex = streamTille.indexOf('=');
// if(eqindex <= 0){waitBitMetaData = 1;return;}
int colindex = streamTille.indexOf(';');
// if(colindex <= 0){waitBitMetaData = 1;return;}
String metaDatam = streamTille.substring(eqindex, colindex);
int lengthOfMaetaDataM = metaDatam.length();
if(lengthOfMaetaDataM <= 0){waitBitMetaData = 1;return;}
metaDataParsed =metaDatam.substring(2, lengthOfMaetaDataM-2);
System.out.println(metaDataParsed);
waitBitMetaData = 1;
}
}
catch (Exception e){
System.out.println(e);
waitBitMetaData = 1;
}
}
});
metaThread.start();
metaThread.start();
//while( metaDataParsed.equals("") || waitBitMetaData == 0){
//try {
// Thread.sleep(50);
//} catch (InterruptedException e) {
//System.out.println(e);
//}
//}
return metaDataParsed;
}
I think the reason you are getting null with a Thread is you don't wait for the end of the thread execution. This is not related to BlackBerry, but is purely related to Java. To solve this just do the whole task (not just networking part of it) on a separate (from UI) thread. When upon task completion you'll need to update the UI, then just use UiApplication.getUiApplication().invokeLater(Runnable action) pattern.

Resources