How can I repaint part of screen on blackberry while connections run? - multithreading

I have two questions.
The first is about updating the UI, the second is when I try to connect to the camera to get a mjpeg stream and run getResponseCode(), the app locks there. The MDS shows a lot of data transferring.
I have some classes like ....:
Http extends Thread {
public abstract String getUrl();
public abstract String getBase64Encode();
public abstract void onReturn(int responseCode, InputStream is,int lenght);
protected abstract void onError(Exception e);
}
CameraHttp extends Http and MjpegHttp extends CameraHttp.
http connects to a URL which is the jpeg or mjpeg camera adresses.
I have a Camera Class. It starts a connection with the overridden method mjpegconnection.go();
I also have a static bitmap on ViewCam screen which extends MainScreen.
After it starts:
url = getUrl();
queryString = encodeURL(queryString);
byte postmsg[] = queryString.getBytes("UTF-8");
httpConnection = (HttpConnection) Connector.open(url
+ ";deviceside=false", Connector.READ_WRITE);
httpConnection.setRequestMethod(HttpConnection.GET);
httpConnection.setRequestProperty("Authorization", getBase64Encode());
os = httpConnection.openDataOutputStream();
for (int i = 0; i < postmsg.length; i++) {
os.write(postmsg[i]);
}
{
if (!cancel) {
System.out.println(httpConnection.getURL()+
" *****"+httpConnection.getPort());
System.out.println("onreturn oncesi"
+ httpConnection.getResponseCode());
onReturn(httpConnection.getResponseCode(), httpConnection
.openInputStream(),(int) httpConnection.getLength());
System.out.println("onreturn sornrası");
}
os.close();
httpConnection.close();
}
} catch (Exception e) {
System.out.println("hata " + e.getMessage());
try {
httpConnection.close();
Thread.sleep(60);
} catch (Exception ie) {
}
onError(e);
}
After dosomething
// decides mjpeg-jpeg stream
// if it is mjpeg, direct to parser,
// else it sets image with setImage() and return to connection with go();
public void parse(InputStream is, int lenght) {
try {
if (!type.isMjpegStream()) {
setImage(is, lenght);
System.gc();
StaticVar.ActiveCam.setConnected(true);
} else {
if (parser == null) {
parser = new JpegParser(is, this);
} else {
parser.setInputSteam(is, this);
}
parser.parse();
is.close();
}
} catch (Exception e) {
}
}
and
public void setImage(InputStream is, int lenght) {
byte[] raw = new byte[lenght];
try {
is.read(raw);
currentImage = Bitmap.createBitmapFromBytes(raw, 0, raw.length, 1);
ViewCam.ViewCam=currentImage; //static var.
} catch (IOException e) {
System.out.println("catche***********");
// TODO Auto-generated catch block
e.printStackTrace();
}
}
How can I repaint the screen to show the bitmap?
And my ViewCam
public class ViewCam extends MainScreen {
Header header;
String headerString;
public static Bitmap ViewCam;// cam image shows
private static Thread My;// runs connection
void OnStart() {
My = new Thread() {
public void run() {
System.out.println("ONSTART");
StaticVar.ActiveCam.go();
};
};
My.start();
Bitmap bitmap = Bitmap.getBitmapResource("res/main.png");
Bitmap bmp2 = ResizeImage.resizeBitmap(bitmap, Display.getWidth(),
Display.getHeight());
Background bg = BackgroundFactory.createBitmapBackground(bmp2);
this.setBackground(bg);
this.getMainManager().setBackground(bg);
}
public ViewCam() {
StaticVar.ActiveCam.getIp();
OnStart();
headerString ="Cam View";
header = new Header("res/bartop.png", headerString, 0);
add(header);
ViewCam = Bitmap.getBitmapResource("res/spexco_splash.png");
ViewCam = ResizeImage.bestFit(ViewCam, Display.getWidth(), Display
.getHeight());
BitmapField bf = new BitmapField(ViewCam);
add(bf);
}
}

Try Screen.invalidate()
public void invalidate(int x, int y, int width, int height)
Invalidates a region of this screen.
This method marks a region of this screen as needing a repaint. The repainting is handled later by the main event dispatch thread.
Note: Any thread can safely invoke this method, and does not require to synchronize on the event lock.
Overrides:
invalidate in class Manager
Parameters:
x - Left edge of the region in ContentRect coordinates.
y - Top edge of the region in ContentRect coordinates.
width - Width (in pixels) of the region.
height - Height (in pixels) of the region.

Related

Camera cannot take image when app go background but work fine when app in foreground

I am making application which take image from front camera on firebase remote command. App work fine and take picture without user interaction, but when app close or go to foreground, app start giving error that Fail to connect to camera service. As soon as app open it capture the image.
I run foreground service notification which working but still same camera fail error and can not take picture.
try {
Log.d("kkkk", "Preparing to take photo");
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
int frontCamera = cam;
//int backCamera=0;
Camera.getCameraInfo(frontCamera, cameraInfo);
try {
camera = Camera.open(frontCamera);
} catch (RuntimeException e) {
Log.d("kkkk", "Camera not available: " + e.getMessage());
camera = null;
// takePicture(0);
}
try {
if (null == camera) {
Log.d("kkkk", "Could not get camera instance");
} else {
Log.d("kkkk", "Got the camera, creating the dummy surface texture");
try {
camera.setPreviewTexture(new SurfaceTexture(0));
camera.startPreview();
} catch (Exception e) {
Log.d("kkkk", "Could not set the surface preview texture");
e.printStackTrace();
}
camera.takePicture(null, null, new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.d("kkkk", "clicked");
// Encode the byte array into a base64 string
// String imageString = android.util.Base64.encodeToString(imageBytes, android.util.Base64.DEFAULT);
// Log.d("error200", imageString);
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReference();
String path = "images/"+username.toLowerCase()+device.replace(" ","");
StorageReference imageRef = storageRef.child(path);
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); // Replace this with your bitmap image
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 10, baos);
byte[] data0 = baos.toByteArray();
UploadTask uploadTask = imageRef.putBytes(data0);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
Log.d("pic","fail"+exception.getMessage());
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// Handle successful uploads
Log.d("pic","done");
}
});
camera.release();
}
});
}
} catch (Exception e) {
camera.release();
}
} catch (Exception e) {
Log.d("errorData", e.getMessage());
}
onDestroy method I release the camera but still same error.
#Override
public void onDestroy() {
super.onDestroy();
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}```
Can you add START_ACTIVITIES_FROM_BACKGROUND permission in the manifest if you have not added then you need to add this permission for using a camera in the foreground service. But I'm not sure the android newer version supports the used camera without user interaction
Please Refer Official Android Documentation here

Using Camera and include an image of a layout

I have the next code, actually I have a main layer that shows the camera preview, and 2 layouts called R.layout.overlay and R.layout.controls, the layout of controls only show a button that take a picture, and the overlay have an image, what I try to do is that at the moment I take the picture the image that is in R.layout.overlay appear on the capture of the photo.
At the moment of preview before taking the photo it displays controls an image fine.
I don't know how to do this cause when I take the picture it takes it but without the image on R.layout.overlay.
Or is there a way to take an screenshot with some code? thats other option I have been thinking, but the problem of this is that the photo will be of the size of the resolution of the screen.
This is my code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
drawingView = new DrawingView(this);
LayoutParams layoutParamsDrawing
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(drawingView, layoutParamsDrawing);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
inflater = LayoutInflater.from(getBaseContext());
View view = inflater.inflate(R.layout.overlay, null);
LayoutParams layoutParamsControl2= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(view, layoutParamsControl2);
buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
camera.takePicture(myShutterCallback, myPictureCallback_RAW, myPictureCallback_JPG);
}});
LinearLayout layoutBackground = (LinearLayout)findViewById(R.id.background);
layoutBackground.setOnClickListener(new LinearLayout.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
buttonTakePicture.setEnabled(false);
camera.autoFocus(myAutoFocusCallback);
}});
prompt = (TextView)findViewById(R.id.prompt);
}
//Termina onCreate
FaceDetectionListener faceDetectionListener
= new FaceDetectionListener(){
#Override
public void onFaceDetection(Face[] faces, Camera camera) {
if (faces.length == 0){
prompt.setText(" No Face Detected! ");
drawingView.setHaveFace(false);
}else{
prompt.setText(String.valueOf(faces.length) + " Face Detected :) ");
drawingView.setHaveFace(true);
detectedFaces = faces;
}
drawingView.invalidate();
}};
AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){
#Override
public void onAutoFocus(boolean arg0, Camera arg1) {
// TODO Auto-generated method stub
buttonTakePicture.setEnabled(true);
}};
ShutterCallback myShutterCallback = new ShutterCallback(){
#Override
public void onShutter() {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
/*Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(arg0, 0, arg0.length); */
Uri uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
OutputStream imageFileOS;
try {
imageFileOS = getContentResolver().openOutputStream(uriTarget);
imageFileOS.write(arg0);
imageFileOS.flush();
imageFileOS.close();
prompt.setText("Image saved: " + uriTarget.toString());
Toast.makeText(AndroidCamera.this, "Saved", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.startPreview();
camera.startFaceDetection();
}};
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopFaceDetection();
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
prompt.setText(String.valueOf(
"Max Face: " + camera.getParameters().getMaxNumDetectedFaces()));
camera.startFaceDetection();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
camera.setFaceDetectionListener(faceDetectionListener);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopFaceDetection();
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
private class DrawingView extends View{
boolean haveFace;
Paint drawingPaint;
public DrawingView(Context context) {
super(context);
haveFace = false;
drawingPaint = new Paint();
drawingPaint.setColor(Color.GREEN);
drawingPaint.setStyle(Paint.Style.STROKE);
drawingPaint.setStrokeWidth(2);
}
public void setHaveFace(boolean h){
haveFace = h;
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
if(haveFace){
// Camera driver coordinates range from (-1000, -1000) to (1000, 1000).
// UI coordinates range from (0, 0) to (width, height).
int vWidth = getWidth();
int vHeight = getHeight();
for(int i=0; i<detectedFaces.length; i++){
int l = detectedFaces[i].rect.left;
int t = detectedFaces[i].rect.top;
int r = detectedFaces[i].rect.right;
int b = detectedFaces[i].rect.bottom;
int left = (l+1000) * vWidth/2000;
int top = (t+1000) * vHeight/2000;
int right = (r+1000) * vWidth/2000;
int bottom = (b+1000) * vHeight/2000;
canvas.drawRect(
left, top, right, bottom,
drawingPaint);
}
}else{
canvas.drawColor(Color.TRANSPARENT);
}
}
}
You can take a screenshot of your phone by physically pressing a combination of buttons. Thus, I guess there should be a way to do this programmatically, probably by overriding a callback somewhere. Check here: How to programmatically take a screenshot in Android?
But remember that when you are taking the screenshot, the image will have the same resolution of the phone display, and on old devices it may be very low. A picture taken with the camera will have a far better resolution. You can still add your image on the picture taken by simply merging the two images together.

No able to capture image via Nokia C Series and send it to Web Server

I am making an Application in J2ME, with the use of this application user will be able to capture an image and at the same time upload that image to Web Server, but whenever I use this app in my Nokia C series I am not able to capture an image and whenever use this application via Computer able to capture an image but send command is not working please see the problem and sort out this problem, and guide what I need to do to make this app helpful and useful for me …………….Thanks Amit here
public class myMidlet extends MIDlet implements CommandListener{
private Display display;
private Form form;
private Command exit, back, capture, camera, send;
private Player player;
private VideoControl videoControl;
private Video video;
int status = 0;
byte localData[];
public myMidlet() {
display = Display.getDisplay(this);
form = new Form("My Form");
exit = new Command("Exit", Command.EXIT, 0);
camera = new Command("Camera", Command.SCREEN, 1);
back = new Command("Back", Command.BACK, 2);
capture = new Command("Capture", Command.SCREEN, 3);
send = new Command("Send", Command.OK, 1);
form.addCommand(camera);
form.addCommand(exit);
form.setCommandListener(this);
}
public void startApp() {
display.setCurrent(form);
}
public void pauseApp() {}
public void destroyApp(boolean unconditional){
notifyDestroyed();
}
public void commandAction(Command c, Displayable s){
String label = c.getLabel();
if (label.equals("Exit")){
destroyApp(true);
} else if (label.equals("Camera")) {
showCamera();
} else if (label.equals("Back"))
display.setCurrent(form);
else if (label.equals("Capture")) {
video = new Video(this);
video.start();
form.addCommand(send);
form.removeCommand(camera);
}
else if( label.equalsIgnoreCase("Send") ){
try {
startSendOperation();
} catch (Exception ex) {
}
}
}
public boolean uploadImage( String uri, byte[] rawImage)throws Exception
{
HttpConnection httpConnection;
OutputStream out;
// Open connection to the script
httpConnection = (HttpConnection)Connector.open( uri );
// Setup the request as an HTTP POST and encode with form data
httpConnection.setRequestMethod( HttpConnection.POST );
httpConnection.setRequestProperty( "Content-type", "application/
x-www-form-urlencoded" );
// Encode the imagedata with Base64
String encoded = Base64.encode( rawImage ).toString();
// Build the output and encoded string
String output = "imgdata=" + encoded;
// Set the content length header
httpConnection.setRequestProperty("Content-Length", Integer.toString
((output.getBytes().length)));
// Open the output stream and publish data
out = httpConnection.openOutputStream();
out.write( output.getBytes() );
// Flush the buffer (might not be necessary?)
out.flush();
// Here you might want to read a response from the POST to make
// sure everything went OK.
// Close everything down
if( out != null )
if( httpConnection != null )
httpConnection.close();
// All good
return true;
}
public void startSendOperation() throws Exception{
boolean res = uploadImage( "http://www.xxx.com/postFolder?", localData);
}
public void showCamera(){
try{
player = Manager.createPlayer("capture://video");
player.realize();
videoControl = (VideoControl)player.getControl("VideoControl");
Canvas canvas = new VideoCanvas(this, videoControl);
canvas.addCommand(back);
canvas.addCommand(capture);
canvas.setCommandListener(this);
display.setCurrent(canvas);
player.start();
} catch (IOException ioe) {} catch (MediaException me) {}
}
class Video extends Thread {
myMidlet midlet;
public Video(myMidlet midlet) {
this.midlet = midlet;
}
public void run() {
captureVideo();
}
public void captureVideo() {
try {
byte[] photo = videoControl.getSnapshot(null);
localData = photo;
Image image = Image.createImage(photo, 0, photo.length);
form.append(image);
display.setCurrent(form);
player.close();
player = null;
videoControl = null;
} catch (MediaException me) { }
}
};
}
class VideoCanvas extends Canvas {
private myMidlet midlet;
public VideoCanvas(myMidlet midlet, VideoControl videoControl) {
int width = getWidth();
int height = getHeight();
this.midlet = midlet;
videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);
try {
videoControl.setDisplayLocation(2, 2);
videoControl.setDisplaySize(width - 4, height - 4);
} catch (MediaException me) {}
videoControl.setVisible(true);
}
public void paint(Graphics g) {
int width = getWidth();
int height = getHeight();
g.setColor(255, 0, 0);
g.drawRect(0, 0, width - 1, height - 1);
g.drawRect(1, 1, width - 3, height - 3);
}
}
In ShowCamera method,Instead of
Manager.createPlayer("capture://video");
Try using
Manager.createPlayer("capture://image");

Camera snapshot in J2ME Null Pointer Exception

I've spent long on this but no success yet. In my application to capture image and send to the server, I get NullPointerException below;
java.lang.NullPointerException: 0
at Files.CameraMIDlet.snap(CameraMIDlet.java:120)
at Files.CameraForm.commandAction(CameraForm.java:116)
at javax.microedition.lcdui.Display$ChameleonTunnel.callScreenListener(), bci=46
at com.sun.midp.chameleon.layers.SoftButtonLayer.processCommand(), bci=74
at com.sun.midp.chameleon.layers.SoftButtonLayer.soft2(), bci=173
at com.sun.midp.chameleon.layers.SoftButtonLayer.keyInput(), bci=78
at com.sun.midp.chameleon.CWindow.keyInput(), bci=38
at javax.microedition.lcdui.Display$DisplayEventConsumerImpl.handleKeyEvent(), bci=17
at com.sun.midp.lcdui.DisplayEventListener.process(), bci=277
at com.sun.midp.events.EventQueue.run(), bci=179
at java.lang.Thread.run(Thread.java:722)
The errors happen at byte[] image = videoControl.getSnapshot("encoding = jpeg"); in the CameraMIDlet and also at midlet.snap(); in the CameraForm, in the code below.
The code for CameraForm is here:
package Files;
import javax.microedition.media.*;
import javax.microedition.lcdui.*;
import javax.microedition.media.control.*;
import java.io.IOException;
class CameraForm extends Form implements CommandListener {
private final CameraMIDlet midlet;
private final Command exitCommand;
private Command captureCommand = null;
private Command showImageCommand = null;
private Player player = null;
private static VideoControl videoControl = null;
private boolean active = false;
private StringItem messageItem;
public CameraForm(CameraMIDlet midlet) {
super("Camera");
this.midlet = midlet;
messageItem = new StringItem("Message", "start");
append(messageItem);
exitCommand = new Command("EXIT", Command.EXIT, 1);
addCommand(exitCommand);
setCommandListener(this);
try {
//creates a new player and set it to realize
player = Manager.createPlayer("capture://video");
player.realize();
//Grap the Video control and set it to the current display
videoControl = (VideoControl) (player.getControl("VideoControl"));
if (videoControl != null) {
append((Item) (videoControl.initDisplayMode(
VideoControl.USE_GUI_PRIMITIVE, null)));
captureCommand = new Command("CAPTURE", Command.SCREEN, 1);
addCommand(captureCommand);
messageItem.setText("OK");
} else {
messageItem.setText("No video control");
}
} catch (IOException ioe) {
messageItem.setText("IOException: " + ioe.getMessage());
} catch (MediaException me) {
messageItem.setText("Media Exception: " + me.getMessage());
} catch (SecurityException se) {
messageItem.setText("Security Exception: " + se.getMessage());
}
}
* the video should be visualized on the sreen
* therefore you have to start the player and set the videoControl visible
synchronized void start() {
if (!active) {
try {
if (player != null) {
player.start();
}
if (videoControl != null) {
videoControl.setVisible(true);
//midlet.snap();
}
} catch (MediaException me) {
messageItem.setText("Media Exception: " + me.getMessage());
} catch (SecurityException se) {
messageItem.setText("Security Exception: " + se.getMessage());
}
active = true;
}
}
* to stop the player. First the videoControl has to be set invisible
* than the player can be stopped
synchronized void stop() {
if (active) {
try {
if (videoControl != null) {
videoControl.setVisible(false);
}
if (player != null) {
player.stop();
}
} catch (MediaException me) {
messageItem.setText("Media Exception: " + me.getMessage());
}
active = false;
}
}
* on the captureCommand a picture is taken and transmited to the server
public void commandAction(Command c, Displayable d) {
if (c == exitCommand) {
midlet.cameraFormExit();
} else {
if (c == captureCommand) {
midlet.snap();
}
}
}
}
The code for CameraMIDlet is below:
package Files;
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import javax.microedition.media.control.*;
import java.io.IOException;
import javax.microedition.media.MediaException;
public class CameraMIDlet extends MIDlet {
private CameraForm cameraSave = null;
private DisplayImage displayImage = null;
CameraForm captureThread;
private static VideoControl videoControl;
private StringItem messageItem;
public CameraMIDlet() {
}
/*
* startApp()
* starts the MIDlet and generates cameraSave, displayImage, database
*
**/
public void startApp() {
Displayable current = Display.getDisplay(this).getCurrent();
if (current == null) {
//first call
cameraSave = new CameraForm(this);
displayImage = new DisplayImage(this);
Display.getDisplay(this).setCurrent(cameraSave);
cameraSave.start();
} else {
//returning from pauseApp
if (current == cameraSave) {
cameraSave.start();
}
Display.getDisplay(this).setCurrent(current);
}
}
public void pauseApp() {
if (Display.getDisplay(this).getCurrent() == cameraSave) {
cameraSave.stop();
}
}
public void destroyApp(boolean unconditional) {
if (Display.getDisplay(this).getCurrent() == cameraSave) {
cameraSave.stop();
}
}
private void exitRequested() {
destroyApp(false);
notifyDestroyed();
}
void cameraFormExit() {
exitRequested();
}
/**
* restart the camera again
*
*/
void displayCanvasBack() {
Display.getDisplay(this).setCurrent(cameraSave);
cameraSave.start();
}
/**
* the byte[] of the image should be transmitted to a server
*
**/
void buildHTTPConnection(byte[] byteImage) {
displayImage.setImage(byteImage);
Display.getDisplay(this).setCurrent(displayImage);
HttpConnection hc = null;
OutputStream out = null;
try {
//enode the image data by the Base64 algorithm
String stringImage = Base64.encode(byteImage);
// URL of the Sevlet
String url = new String(
"http://ip-adress:8080/C:/Users/HASENDE/Documents/NetBeansProjects/Mobile/pics");
// Obtain an HTTPConnection
hc = (HttpConnection) Connector.open(url);
// Modifying the headers of the request
hc.setRequestMethod(HttpConnection.POST);
// Obtain the output stream for the HttpConnection
out = hc.openOutputStream();
out.write(stringImage.getBytes());
} catch (IOException ioe) {
StringItem stringItem = new StringItem(null, ioe.toString());
} finally {
try {
if (out != null)
out.close();
if (hc != null)
hc.close();
} catch (IOException ioe) {
}
}
// ** end network
}
/**
* stop the camera, show the captured image and transmit the image to a server
**/
void transmitImage(byte[] image) {
cameraSave.stop();
Display.getDisplay(this).setCurrent(displayImage);
buildHTTPConnection(image);
}
public void snap(){
try {
byte[] image = videoControl.getSnapshot("encoding = jpeg");
transmitImage(image);
messageItem.setText("Ok");
} catch (MediaException me) {
messageItem.setText("Media Exception: " + me.getMessage());
}
}
}
By identifying the statement that throws NPE you get 99% close to finding the bug:
byte[] image = videoControl.getSnapshot("encoding = jpeg");
NPE in above statement means videoControl is null. Now if you look at it closer, you may notice that in CameraMIDlet, videoControl is initialized with null and never changes to anything else - that's why you are getting NPE. By the way, from CameraForm code it looks like you intended to use videoControl object that is defined there, didn't you.
Side note. CameraForm seems to be designed to used in multiple threads (there are synchronized modifiers) - if this is the case, you better make sure that videoControl is also obtained from it in a synchronized way. Also in that case, add volatile modifier in definition of active flag:
private volatile boolean active = false; // in CameraForm
For Capturing photo use canvas instead of Form,
Check follwing code for Photo Capture
public class ImageCaptureCanvas extends Canvas {
UrMidlet midlet;
VideoControl videoControl;
Player player;
SnapShotCanvas snap;
private Display display;
public ImageCaptureCanvas(UrMidlet midlet) throws MediaException {
this.midlet = midlet;
this.display = Display.getDisplay(midlet);
this.setFullScreenMode(true);
try {
player = Manager.createPlayer("capture://image");
player.realize();
videoControl = (VideoControl) player.getControl("VideoControl");
} catch (Exception e) {
dm(e.getClass().getName());
}
videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);
try {
videoControl.setDisplayLocation(0,0);
videoControl.setDisplaySize(getWidth(), getHeight());
} catch (MediaException me) {
try {
videoControl.setDisplayFullScreen(true);
} catch (MediaException me2) {
}
}
dm("icc10");
videoControl.setVisible(true);
dm("icc11");
player.start();
this.display.setCurrent(this);
}
public void dm(String message) {
Form form = new Form("Error");
form.append(message);
display.setCurrent(form);
}
public void paint(Graphics g) {
}
protected void keyPressed(int keyCode) {
boolean prv=false;
int actn=getGameAction(keyCode);
switch (keyCode) {
case KEY_NUM5:
prv=true;
Thread t = new Thread() {
public void run() {
try {
byte[] raw = videoControl.getSnapshot(null);
Image image = Image.createImage(raw, 0, raw.length);
snap = new SnapShotCanvas(image);
display.setCurrent(snap);
} catch (Exception e) {
dm(e.getClass().getName() + " " + e.getMessage());
}
}
};
t.start();
break;
}
if(!prv){
switch (actn) {
case Canvas.FIRE:
Thread t1 = new Thread() {
public void run() {
try {
byte[] raw = videoControl.getSnapshot(null);
Image image = Image.createImage(raw, 0, raw.length);
snap = new SnapShotCanvas(image);
display.setCurrent(snap);
} catch (Exception e) {
dm(e.getClass().getName() + " " + e.getMessage());
}
}
};
t1.start();
break;
}
}
}
}
SnapShotCanvas Code here
class SnapShotCanvas extends Canvas {
private Image image;
public SnapShotCanvas(Image image) {
this.image = image;
setFullScreenMode(true);
}
public void paint(Graphics g) {
g.drawImage(image, getWidth() / 2, getHeight() / 2, Graphics.HCENTER | Graphics.VCENTER);
}
}

displaying image in j2me application

How do I create and display an image in j2me application?
And in which folder can I put that image in my application?
This link has exactly what you are looking for to get started.
Basically, to create the image, you call upon Image.createImage();
Image img = Image.createImage("/imageName.png");
If it is in a sub-folder in the Jar:
Image img = Image.createImage("/subDir/imageName.png");
To display the image, you need to paint it to a Canvas through a Graphics instance that is tied to the Canvas (better visualized in the link above).
public void paint(Graphics g) {
...
g.drawImage(img, 0, 0, Graphics.TOP | Graphics.LEFT);
....
}
You could also use the Graphics.drawRegion function, but here is a link to the JavaDocs for J2ME for you to look through to see what is best for your needs.
To draw an Image on a JavaME MIDlet you need a Canvas to paint it on to. You can do as follow:
Firs you have to place the original image file inside your package (usually inside "res" or one of his subdirectories).
Secondly you need to create a class extending Canvas and implement the paint method:
import java.io.IOException;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
public class MyCanvas extends Canvas {
private Image image;
public MyCanvas(){
try {
image = Image.createImage("picture.png");
} catch (IOException e) {
e.printStackTrace();
}
}
protected void paint(Graphics g) {
g.drawImage(image, 10, 10, Graphics.TOP | Graphics.LEFT);
}
}
Now you need to create an instance of this class and tell the MIDlet di display it, for example:
import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class MyMIDlet extends MIDlet {
public MyMIDlet(){
}
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
Display.getDisplay(this).setCurrent(new MyCanvas());
}
}
Remember that this way the Canvas will be painted only one time and if you change something, you need to call the repaint() method.
This source code builds on previously posted comments:
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
public class ImageLoader extends MIDlet
implements CommandListener, Runnable {
private Display mDisplay;
private Form mForm;
public ImageLoader() {
mForm = new Form("Connecting...");
mForm.addCommand(new Command("Exit", Command.EXIT, 0));
mForm.setCommandListener(this);
}
public void startApp() {
if (mDisplay == null) mDisplay = Display.getDisplay(this);
mDisplay.setCurrent(mForm);
Thread t = new Thread(this);
t.start();
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void commandAction(Command c, Displayable s) {
if (c.getCommandType() == Command.EXIT)
notifyDestroyed();
}
public void run() {
FileConnection fc = null;
DataInputStream in = null;
DataOutputStream out = null;
try {
fc = (FileConnection)Connector.open("file:///root1/i.PNG");
int length = (int)fc.fileSize();//possible loss of precision may throw error
byte[] data = null;
if (length != -1) {
data = new byte[length];
in = new DataInputStream(fc.openInputStream());
in.readFully(data);
}
else {
int chunkSize = 512;
int index = 0;
int readLength = 0;
in = new DataInputStream(fc.openInputStream());
data = new byte[chunkSize];
do {
if (data.length < index + chunkSize) {
byte[] newData = new byte[index + chunkSize];
System.arraycopy(data, 0, newData, 0, data.length);
data = newData;
}
readLength = in.read(data, index, chunkSize);
index += readLength;
} while (readLength == chunkSize);
length = index;
}
Image image = Image.createImage(data, 0, length);
ImageItem imageItem = new ImageItem(null, image, 0, null);
mForm.append(imageItem);
mForm.setTitle("Done.");
fc = (FileConnection)Connector.open("file:///root1/x.PNG");
if(!fc.exists()){
try{
fc.create();
}catch(Exception ce){System.out.print("Create Error: " + ce);}
}
out = new DataOutputStream(fc.openOutputStream());
out.write(data);
}
catch (IOException ioe) {
StringItem stringItem = new StringItem(null, ioe.toString());
mForm.append(stringItem);
mForm.setTitle("Done.");
}
finally {
try {
if (in != null) in.close();
if (fc != null) fc.close();
}
catch (IOException ioe) {}
}
}
}
The code is modified from the link Fostah provided here.
It opens an image, displays it, then saves it as x.PNG instead of i.PNG using FileConnection. The tricky thing to watch for is where the file is being saved/loaded from. If your using J2meWTK with Netbeans, then the folder will be displayed in the output window when you run the mobile app. The folder will be something like temp.DefaultColorPhone/filesystem/root1 . That is where you will have to have an image. I'm not sure how to have the temp environment created with the image by default. That means you have to start the mobile app, check where the temp root1/ is located, in your IDE, then drop the image into the folder, then proceed with running the ImageLoader application. I'll try to find out how to automate this by posting a question. Also, Start with a small image, 50x50 (bigger images may cause problems).

Resources