Voice or Audio player for .amr file in Java ME - java-me

I am working on audio recording in Nokia S40 series mobiles. I am able to record the message, but I am not able to play the recorded audio message.
Can anyone help me how to code for voice player for recorded .amr audio files?
Did any one come across this issue?

Here is my working example of recording and playing sound,
public class VoiceRecordMidlet extends MIDlet {
private Display display;
public void startApp() {
display = Display.getDisplay(this);
display.setCurrent(new VoiceRecordForm());
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
notifyDestroyed();
}
}
class VoiceRecordForm extends Form implements CommandListener {
private StringItem message;
private StringItem errormessage;
private final Command record, play;
private Player player;
private byte[] recordedAudioArray = null;
public VoiceRecordForm() {
super("Recording Audio");
message = new StringItem("", "Select Record to start recording.");
this.append(message);
errormessage = new StringItem("", "");
this.append(errormessage);
record = new Command("Record", Command.OK, 0);
this.addCommand(record);
play = new Command("Play", Command.BACK, 0);
this.addCommand(play);
this.setCommandListener(this);
}
public void commandAction(Command comm, Displayable disp) {
if (comm == record) {
Thread t = new Thread() {
public void run() {
try {
player = Manager.createPlayer("capture://audio");
player.realize();
RecordControl rc = (RecordControl) player.getControl("RecordControl");
ByteArrayOutputStream output = new ByteArrayOutputStream();
rc.setRecordStream(output);
rc.startRecord();
player.start();
message.setText("Recording...");
Thread.sleep(5000);
message.setText("Recording Done!");
rc.commit();
recordedAudioArray = output.toByteArray();
player.close();
} catch (Exception e) {
errormessage.setLabel("Error");
errormessage.setText(e.toString());
}
}
};
t.start();
}
else if (comm == play) {
try {
ByteArrayInputStream recordedInputStream = new ByteArrayInputStream(recordedAudioArray);
Player p2 = Manager.createPlayer(recordedInputStream, "audio/basic");
p2.prefetch();
p2.start();
} catch (Exception e) {
errormessage.setLabel("Error");
errormessage.setText(e.toString());
}
}
}
}

Related

Recording with BluetoothHeadset Mic

Hei there,
I m trying to make an App with Android-Studio that can record sound using a Bluetooth-HS.
I know there are a lot of posts close to this, but i tried all the answers and it wont work for me.
My code gives me back a filled bytebuffer, however testing proves, its always the Phones Mic not the Headset-Mic.
If anyone could take a look at my code and point out why it wont use the BT-HS, that would be a huge help for me.
public class Inhalation extends AppCompatActivity {
AudioManager audioManager;
AudioRecord audioRecord=null;
Button mrecord;
Button mpause;
boolean isRecording=false;
private Thread recordingThread = null;
private int bufferSize = AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inhalation);
mrecord= findViewById(R.id.Button_Record_ID);
mpause=findViewById(R.id.Button_Pause_ID);
audioManager =(AudioManager) this.getSystemService(this.AUDIO_SERVICE);
}
//is supposed to start recording using the BT MIC. Can only be called if BTSCO is connected
private void startRecording() {
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
audioRecord.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
public void run() {
writeAudioDataToFile();
}
}, "AudioRecorder Thread");
recordingThread.start();
}
//picks up the recorded audiobuffer and writes it into a file
private void writeAudioDataToFile() {
String filename="record";
byte saudioBuffer[] = new byte[bufferSize];
FileOutputStream os = null;
// TODO (4) Audiorecord Filecreation
try {
os = openFileOutput(filename, Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.d("headset_rec","false filepath");
}
while (isRecording) {
audioRecord.read(saudioBuffer, 0, bufferSize);
try {
os.write(saudioBuffer, 0, bufferSize);
// os.write(saudioBuffer);
Log.d("headset_rec","writing"+saudioBuffer[0]);
} catch (IOException e) {
e.printStackTrace();
Log.d("headset_rec","writefail");
}
}
try {
os.close();
} catch (IOException e) {
Log.d("headset_rec","close");
e.printStackTrace();
}
}
//stops the recording
private void stopRecording() {
// stops the recording activity
if (null != audioRecord) {
isRecording = false;
audioRecord.stop();
audioRecord.release();
audioRecord = null;
recordingThread = null;
}
}
public void Record_On_Click(View view){
mpause.setEnabled(true);
mrecord.setEnabled(false);
requestRecordAudioPermission();
startRecording();
}
//Button to pause
public void Record_Pause_Click(View view){
stopRecording();
// readFromFile();
mrecord.setEnabled(true);
mpause.setEnabled(false);
}
//if BluetoothSCO is connected enables recording
private BroadcastReceiver mBluetoothScoReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
System.out.println("ANDROID Audio SCO state: " + state);
if (AudioManager.SCO_AUDIO_STATE_CONNECTED == state) {
Log.d("SCOO","connected");
mrecord.setEnabled(true);
}
if(AudioManager.SCO_AUDIO_STATE_DISCONNECTED==state){
Log.d("SCOO","disconnected");
mrecord.setEnabled(false);
}
}
};
//connects to the bluetoothHeadset doing the following:
#Override
protected void onResume() {
// TODO (5) Bluetooth Mik
// Start Bluetooth SCO.
if(isRecording){
mpause.setEnabled(true);
mrecord.setEnabled(false);
}
IntentFilter intentFilter = new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
registerReceiver(mBluetoothScoReceiver, intentFilter);
audioManager.setMode(audioManager.MODE_NORMAL);
audioManager.setBluetoothScoOn(true);
audioManager.startBluetoothSco();
// Stop Speaker.
audioManager.setSpeakerphoneOn(false);
super.onResume();
}
//Disconnects from the Bluetoothheadset doing the following
#Override
protected void onDestroy() {
audioManager.stopBluetoothSco();
audioManager.setMode(audioManager.MODE_NORMAL);
audioManager.setBluetoothScoOn(false);
// Start Speaker.
audioManager.setSpeakerphoneOn(true);
unregisterReceiver(mBluetoothScoReceiver);
super.onDestroy();
}
private void requestRecordAudioPermission() {//gets the permission to record audio
//check API version, do nothing if API version < 23!
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion > android.os.Build.VERSION_CODES.LOLLIPOP){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
Log.d("Activity_Request", "Wastn granted!");
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
Log.d("Activity_Request", "request!");
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
Log.d("Activity_Request", "take!");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1);
}
}
}
}

RecordControl with platformRequest could they work?

My goal is to produce an application that dial a phone number then record the conservation.
I have tested this code which record voice and then play it on my 5310 correctly.
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.media.*;
import javax.microedition.media.control.*;
public class VoiceRecordMidlet extends MIDlet {
private Display display;
public void startApp() {
display = Display.getDisplay(this);
display.setCurrent(new VoiceRecordForm());
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
notifyDestroyed();
}
}
class VoiceRecordForm extends Form implements CommandListener {
private StringItem message;
private StringItem errormessage;
private final Command record, play;
private Player player;
private byte[] recordedAudioArray = null;
public VoiceRecordForm() {
super("Recording Audio");
message = new StringItem("", "Select Record to start recording.");
this.append(message);
errormessage = new StringItem("", "");
this.append(errormessage);
record = new Command("Record", Command.OK, 0);
this.addCommand(record);
play = new Command("Play", Command.BACK, 0);
this.addCommand(play);
this.setCommandListener(this);
}
public void commandAction(Command comm, Displayable disp) {
if (comm == record) {
System.getProperty("audio.encodings");
System.getProperty("supports.audio.capture");
System.getProperty("supports.recording");
t.start();
}
else if (comm == play) {
try {
ByteArrayInputStream recordedInputStream = new ByteArrayInputStream(recordedAudioArray);
Player p2 = Manager.createPlayer(recordedInputStream, "audio/amr");
p2.prefetch();
p2.start();
}
catch (Exception e) {
errormessage.setLabel("Error");
errormessage.setText(e.toString());
}
}
}
Thread t = new Thread() {
public void run() {
try {
System.getProperty("audio.encodings");
player = Manager.createPlayer("capture://audio");
player.realize();
RecordControl rc = (RecordControl) player.getControl("RecordControl");
ByteArrayOutputStream output = new ByteArrayOutputStream();
rc.setRecordStream(output);
rc.startRecord();
player.start();
message.setText("Recording...");
Thread.sleep(5000);
message.setText("Recording Done!");
rc.commit();
recordedAudioArray = output.toByteArray();
player.close();
} catch (Exception e) {
errormessage.setLabel("Error");
errormessage.setText(e.toString());
}
};
};
}
Then I made some changes in my code to record conservations
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.media.*;
import javax.microedition.media.control.*;
public class VoiceRecordMidlet extends MIDlet {
private Display display;
Form f = new VoiceRecordForm();
public void startApp() {
display = Display.getDisplay(this);
display.setCurrent(f);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
notifyDestroyed();
}
class VoiceRecordForm extends Form implements CommandListener {
private MIDlet m;
private StringItem message;
private StringItem errormessage;
private final Command record, play;
private Player player;
private byte[] recordedAudioArray = null;
private TextField phoneField;
private String n;
public VoiceRecordForm() {
super("Recording Audio");
message = new StringItem("", "Select Record to start recording.");
this.append(message);
errormessage = new StringItem("", "");
this.append(errormessage);
record = new Command("Record", Command.SCREEN, 0);
this.addCommand(record);
play = new Command("Play", Command.BACK, 0);
this.addCommand(play);
this.phoneField =new TextField("number","",20,phoneField.PHONENUMBER);
append(phoneField);
this.setCommandListener(this);
}
public void commandAction(Command comm, Displayable disp) {
if (comm == record) {
System.getProperty("audio.encodings");
System.getProperty("supports.audio.capture");
System.getProperty("supports.recording");
t.start();
try
{
n=phoneField.getString().trim();
platformRequest("tel:"+n);
}
catch(javax.microedition.io.ConnectionNotFoundException e)
{
e.printStackTrace();
}
}
else if (comm == play) {
try {
ByteArrayInputStream recordedInputStream = new ByteArrayInputStream(recordedAudioArray);
Player p2 = Manager.createPlayer(recordedInputStream, "audio/amr");
p2.prefetch();
p2.start();
}
catch (Exception e) {
errormessage.setLabel("Error");
errormessage.setText(e.toString());
}
}
}
Thread t = new Thread() {
public void run() {
try {
System.getProperty("audio.encodings");
player = Manager.createPlayer("capture://audio");
player.realize();
RecordControl rc = (RecordControl) player.getControl("RecordControl");
ByteArrayOutputStream output = new ByteArrayOutputStream();
rc.setRecordStream(output);
rc.startRecord();
player.start();
message.setText("Recording...");
Thread.sleep(5000);
message.setText("Recording Done!");
rc.commit();
recordedAudioArray = output.toByteArray();
player.close();
} catch (Exception e) {
errormessage.setLabel("Error");
errormessage.setText(e.toString());
}
};
};
}}
But when pressing record command following error getted
**Error: javax.microedition.media.MediaException: RecordControl**
Any help please?

how to Implement a MIDlet that gets invoked when a SMS is sent to port 50000....the code is not working

How to Implement a MIDlet that gets invoked when a SMS is sent to port 50000?
The code is not working. SMS can't be received on the phone, SMS is sent through the emulator (JAVA Me SDK).
What settings should be done to receive the SMS ?
my code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
import java.io.IOException;
import javax.microedition.io.PushRegistry;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;
/**
* #author bonni
*/
public class Midletsms extends MIDlet implements CommandListener{
protected Display display;
//boolean started=false;
Form form = new Form("Welcome");
Command mCommandQuit;
public void startApp() {
String url = "sms://:50000";
try {
PushRegistry.registerConnection(url,this.getClass().getName(), "*");
// PushRegistry.registerConnection(url,"Midletsms.class", "*");
} catch (IOException ex) {
} catch (ClassNotFoundException ex) {
}
form.append("This midlet gets invoked when message is sent to port:50000");
display = Display.getDisplay(this);
display.setCurrent(form);
mCommandQuit = new Command("Quit", Command.EXIT, 0);
form.addCommand(mCommandQuit);
form.setCommandListener(this);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
public void commandAction(Command c, Displayable d) {
// throw new UnsupportedOperationException("Not supported yet.");
String label = c.getLabel();
if(label.equals("Quit"))
{
destroyApp(false);
notifyDestroyed();
}
}
}
Not sure I fully understand the problem. But you need to read about PushRegistry.
So there are two types of push registration, static and dynamic.
The code example you have given uses dynamic registration. You will need to manually invoke this MIDlet at least once in order for the push registration to happen. (Aside: In your example you are doing this in the startApp method, this is a very bad idea! Push registration is a potentially blocking operation, and therefore should not be done in a lifecycle method such as startApp. You should do this in a new thread).
The alternative is static registration, where you include the push information in the jad. The push port will be registered when the MIDlet is installed, without the need to run it.
Finally, you say
sms is sent through the emulator
what does this mean? In order for the app to start you need to send an SMS on the relevant port number from another MIDlet (this could be on the same handset if you want).
I found this code on net from Jimmy's blog and it is perfectly working. You can try it your self,
SMSSender.java
public class SMSSender extends MIDlet implements CommandListener {
private Form formSender = new Form("SMS Sender");
private TextField tfDestination = new TextField("Destination", "", 20, TextField.PHONENUMBER);
private TextField tfPort = new TextField("Port", "50000", 6, TextField.NUMERIC);
private TextField tfMessage = new TextField("Message", "message", 150, TextField.ANY);
private Command cmdSend = new Command("Send", Command.OK, 1);
private Command cmdExit = new Command("Exit", Command.EXIT, 1);
private Display display;
public SMSSender() {
formSender.append(tfDestination);
formSender.append(tfPort);
formSender.append(tfMessage);
formSender.addCommand(cmdSend);
formSender.addCommand(cmdExit);
formSender.setCommandListener(this);
display = Display.getDisplay(this);
}
protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
display.setCurrent(formSender);
}
public void commandAction(Command c, Displayable d) {
if (c==cmdSend) {
SendMessage.execute(tfDestination.getString(), tfPort.getString(), tfMessage.getString());
} else if (c==cmdExit) {
notifyDestroyed();
}
}
}
class SendMessage {
public static void execute(final String destination, final String port, final String message) {
Thread thread = new Thread(new Runnable() {
public void run() {
MessageConnection msgConnection;
try {
msgConnection = (MessageConnection)Connector.open("sms://"+destination+":" + port);
TextMessage textMessage = (TextMessage)msgConnection.newMessage(
MessageConnection.TEXT_MESSAGE);
textMessage.setPayloadText(message);
msgConnection.send(textMessage);
msgConnection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
}
}
SMSReceiver.java
public class SMSReceiver extends MIDlet implements CommandListener, MessageListener {
private Form formReceiver = new Form("SMS Receiver");
private TextField tfPort = new TextField("Port", "50000", 6, TextField.NUMERIC);
private Command cmdListen = new Command("Listen", Command.OK, 1);
private Command cmdExit = new Command("Exit", Command.EXIT, 1);
private Display display;
public SMSReceiver() {
formReceiver.append(tfPort);
formReceiver.addCommand(cmdListen);
formReceiver.addCommand(cmdExit);
formReceiver.setCommandListener(this);
display = Display.getDisplay(this);
}
protected void destroyApp(boolean unconditional)
throws MIDletStateChangeException {
}
protected void pauseApp() {
}
protected void startApp() throws MIDletStateChangeException {
display.setCurrent(formReceiver);
}
public void commandAction(Command c, Displayable d) {
if (c==cmdListen) {
ListenSMS sms = new ListenSMS(tfPort.getString(), this);
sms.start();
formReceiver.removeCommand(cmdListen);
} else if (c==cmdExit) {
notifyDestroyed();
}
}
public void notifyIncomingMessage(MessageConnection conn) {
Message message;
try {
message = conn.receive();
if (message instanceof TextMessage) {
TextMessage tMessage = (TextMessage)message;
formReceiver.append("Message received : "+tMessage.getPayloadText()+"\n");
} else {
formReceiver.append("Unknown Message received\n");
}
} catch (InterruptedIOException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ListenSMS extends Thread {
private MessageConnection msgConnection;
private MessageListener listener;
private String port;
public ListenSMS(String port, MessageListener listener) {
this.port = port;
this.listener = listener;
}
public void run() {
try {
msgConnection = (MessageConnection)Connector.open("sms://:" + port);
msgConnection.setMessageListener(listener);
} catch (IOException e) {
e.printStackTrace();
}
}
}

How to work with LWUIT TABs click events

UPDATE:
My Requirement is to display two Rss files as Tabs on my LWUIT Form
Initially by default first Rss file titles and images should be displayed on first tab
if an end user click on second tab,we should be able to load the second rss file titles and images
I am able to load first Rss File titles,but i am not able to load the second tab if i click on it
How to capture the click event for LWUIT Tab?
Here my code which is not working:
String topNewsurl="TopNews.rss";
String topStoryurl="TopStory.rss";
public class XMLMidlet extends MIDlet{
public void startApp() {
Display.init(this);
Process p;
try {
p = new Process(this);
p.process();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public class Process extends Form {
Process(XMLMidlet midlet) throws IOException {
this.midlet=midlet;
topnews = new Vector();
topstory = new Vector();
tabs = new Tabs();
form1 = new Form();
form2=new Form();
form1.setLayout(new BorderLayout());
form1.setScrollable(false);
image = Image.createImage("/res/Tone.jpg");
Label icon = new Label(image);
form1.setTitleComponent(icon);
form2.setTitleComponent(icon);
form1.setTransitionInAnimator(Transition3D.createRotation(250, true));
try {
newsList = new List(topnews);
newsList.setScrollVisible(false);
newsList.setRenderer(new NewsListCellRenderer());
myNewsList = new List(topstory);
myNewsList.setScrollVisible(false);
myNewsList.setRenderer(new NewsListCellRenderer());
tabs.addTab("Topstory", newsList);
tabs.addTab("TopNews", myNewsList);
tabs.setChangeTabOnFocus(true);
form1.addComponent(BorderLayout.CENTER, tabs);
}
try{
String url = "http:topnews-20.rss";
form1.show();
ParseThread myThread = new ParseThread(this);
myThread.getXMLFeed(url);
} catch (Exception e) {
e.printStackTrace();
}
}
public void addNews(News newsItem) {
//log.debug("addnews");
//System.out.println("addNews");
topnews.addElement(newsItem);
newsList.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
List source = (List) ae.getSource();
News selectedNewsItem = (News) source.getSelectedItem();
if (selectedNewsItem != null) {
displayCompleteNewsScreen(selectedNewsItem);
}
}
});
form1.show();
}
public void keyReleased(int keyCode) {
System.out.println("str");
Component p=this.getFocused();
String str= p.getClass().getName();
if(str.toLowerCase().indexOf("radiobutton")!=-1){
process();
}
From the very vague question it seems you want to capture key presses on a LWUIT Form.
jobsForm.addGameKeyListener(Display.GAME_FIRE,
new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//do something here
}
});
jobsForm.addPointerPressedListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
pointer_click = true;
}
});
jobsForm.addPointerReleasedListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (pointer_click) {
//
}
pointer_click = false;
}
});
jobsForm.addPointerDraggedListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//System.out.println("POINTER DRAGGED");
pointer_click = false;
}
});

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);
}
}

Resources