public class Midlet extends MIDlet implements CommandListener{
Player p;
public void startApp() {
Display.getDisplay(this).setCurrent(new SongsList(this));
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
notifyDestroyed();
}
public void commandAction(Command cmnd, Displayable dsplbl) {
if (cmnd.getLabel().equals("Exit"))
{
destroyApp(true);
}
else
{
try {
//InputStream is = getClass().getResourceAsStream("/res/getlucky.mpeg");
//p = Manager.createPlayer(is, "audio/mpeg");
p = Manager.createPlayer("http://puu.sh/6n9jC.mp3");
p.realize();
p.start();
} catch (IOException ex) {
ex.printStackTrace();
} catch (MediaException ex) {
ex.printStackTrace();
}
}
}
}
this is the songslist class :
public class SongsList extends List{
public SongsList(Midlet midlet)
{
super("Songs", List.IMPLICIT);
append("get lucky", null);
addCommand(new Command("Exit", Command.EXIT, 0));
addCommand(new Command("Select", Command.OK, 0));
setCommandListener(midlet);
}
}
tried use via file stored in project (its under src/res):
inputStream = getClass().getResourceAsStream("res/getlucky.mpg");
audioPlayer = Manager.createPlayer(inputStream, "audio/mpg");
as well as from HTTP:
//audioPlayer = Manager.createPlayer("http://puu.sh/6n9jC.mp3");
Nothing works, what am I doing wrong?
EDIT:
I've tried to delete my application and just copy paste it to a new project and it worked for some reason.. now I encounter new problems:
1) I try to play a song - this is the link http://puu.sh/6n9jC.mp3
its not playing so I guess there's a limited file size for what can be played can someone tell me what is this limit ?
2) Im trying to record the audio with RecordPlayer but its always null
public AudioAnalyzer()
{
try {
thread = new Thread(this);
recordFinished = false;
//inputStream = getClass().getResourceAsStream("res/getlucky.mpg");
//audioPlayer = Manager.createPlayer(inputStream, "audio/mpg");
audioPlayer = Manager.createPlayer("http://puu.sh/35YTG.mp3");
//audioPlayer = Manager.createPlayer("http://puu.sh/6n9jC.mp3");
audioPlayer.realize();
System.out.println(System.getProperty("supports.audio.capture"));
recordControl = (RecordControl)audioPlayer.getControl("RecordControl");
recordOutput = new ByteArrayOutputStream();
recordControl.setRecordStream(recordOutput);
recordControl.startRecord();
audioPlayer.start();
//thread.start();
} catch (MediaException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
I even tried to print if the system is supporting audio capture and the result were true but I get NullPointException at this line :
recordOutput = new ByteArrayOutputStream();
although I tried to get the recordcontrol from the player it is still null :
recordControl = (RecordControl)audioPlayer.getControl("RecordControl");
I think I read that it'll always give NullPointerException unless you run it on a real device and not an emulator is that true ? can someone verify it ? and if so what can I do if I don't own a device currently any other way to use recordcontrol feature in emulator (assuming recordcontrol isn't working on emulators).
File size is 8MB (maybe play on your phone), try to this code
public void initMedia(final String aFileUrl) {
if (m_player == null) {
try {
m_player = Manager.createPlayer(aFileUrl);
m_player.addPlayerListener(this);
m_player.realize();
m_player.prefetch();
m_volumeControl = (VolumeControl) m_player.getControl("VolumeControl");
} catch (IOException ex) {
} catch (Exception ex) {
} catch (OutOfMemoryError e) {
}
}
}
In your code, i guess you miss "m_player.prefetch()", try this. And print your Exception message...
This code in general for file, resourcce, http...
public void initMedia(final String aProtocol, final String aMediaSource) {
if (m_player == null) {
try {
if (aMediaSource.indexOf("file://") == 0) {
InputStream iRecordStream = Connector.openInputStream(aMediaSource);
m_player = Manager.createPlayer(iRecordStream, "audio/amr");
} else {
m_player = Manager.createPlayer(aProtocol);
}
m_player.addPlayerListener(this);
m_player.realize();
boolean isPrefetch = true;
try {
m_player.prefetch();
} catch (Exception ex) {
isPrefetch = false;
}
// trick to pass prefetch error
if (!isPrefetch) {
if (m_player != null) {
m_player.close();
m_player = null;
}
if (aMediaSource.indexOf("file://") == 0) {
InputStream iRecordStream = Connector.openInputStream(aMediaSource);
m_player = Manager.createPlayer(iRecordStream, "audio/amr");
} else {
m_player = Manager.createPlayer(aProtocol);
}
m_player.addPlayerListener(this);
m_player.realize();
m_player.prefetch();
}
m_volumeControl = (VolumeControl) m_player.getControl("VolumeControl");
} catch (IOException ex) {
} catch (Exception ex) {
} catch (OutOfMemoryError e) {
}
}
}
In general when it comes to J2ME development, you should always test your app on multiple real devices.
Emulators can't be trusted.
Also, J2ME is very fragmented, and various devices have various bugs and behaves differently with the same code. This will affect any app on many areas. One area being audio playback.
For example, some devices requires that you use the realize() and prefetch() methods, while other devices will crash if you use prefetch(). The only possible solution (if you wish to support as many devices as possible) is to use multiple try/catch blocks.
See this link for a detailed explanation and other tips'n'tricks on audio playback with MIDP2.0
http://indiegamemusic.com/help.php?id=1
Related
I have to create a simple rotating proxy application where 100 requests get evenly distributed to 10 devices. I've got the following structure:
WebServer with a Java-SocketServer running. All Android devices are connected to this Socket-Server to be able to know which devices are currently online and for determining which device should be used for the next request.
10 Android devices in different networks. They are connected to the Socket Server and are waiting for requests that should be forwarded to the remote address and then sent back to the SocketServer.
In easy words: I basically have to create an application similar like Honeygain, Peer2Profit or IPRoyal Pawns so that I can later do requests like this:
//Use "-x" to set Proxy-IP and Proxy-Port
curl -x ANDROID_DEVICE_IP:PORT -L https://www.google.com
I managed to have an always running proxy service in an Android application. It basically looks like this and just forwards HTTP-Requests from Port 1440 to the desired remote address and then sends the response back to the original client. The Proxy basically works fine.
public class ProxyServerThread extends Thread {
public static void main(String[] args) {
(new ProxyServerThread()).run();
}
public ProxyServerThread() {
super("Server Thread");
}
#Override
public void run() {
try (ServerSocket serverSocket = new ServerSocket(1440)) {
Socket socket;
try {
while ((socket = serverSocket.accept()) != null) {
(new Handler(socket)).start();
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
return;
}
}
public static class Handler extends Thread {
public static final Pattern CONNECT_PATTERN = Pattern.compile("CONNECT (.+):(.+) HTTP/(1\\.[01])", Pattern.CASE_INSENSITIVE);
private final Socket clientSocket;
private boolean previousWasR = false;
public Handler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
try {
String request = readLine(clientSocket);
System.out.println(request);
Matcher matcher = CONNECT_PATTERN.matcher(request);
if (matcher.matches()) {
String header;
do {
header = readLine(clientSocket);
} while (!"".equals(header));
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(clientSocket.getOutputStream(), "ISO-8859-1");
final Socket forwardSocket;
try {
forwardSocket = new Socket(matcher.group(1), Integer.parseInt(matcher.group(2)));
System.out.println(forwardSocket);
} catch (IOException | NumberFormatException e) {
e.printStackTrace(); // TODO: implement catch
outputStreamWriter.write("HTTP/" + matcher.group(3) + " 502 Bad Gateway\r\n");
outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
outputStreamWriter.write("\r\n");
outputStreamWriter.flush();
return;
}
try {
outputStreamWriter.write("HTTP/" + matcher.group(3) + " 200 Connection established\r\n");
outputStreamWriter.write("Proxy-agent: Simple/0.1\r\n");
outputStreamWriter.write("\r\n");
outputStreamWriter.flush();
Thread remoteToClient = new Thread() {
#Override
public void run() {
forwardData(forwardSocket, clientSocket);
}
};
remoteToClient.start();
try {
if (previousWasR) {
int read = clientSocket.getInputStream().read();
if (read != -1) {
if (read != '\n') {
forwardSocket.getOutputStream().write(read);
}
forwardData(clientSocket, forwardSocket);
} else {
if (!forwardSocket.isOutputShutdown()) {
forwardSocket.shutdownOutput();
}
if (!clientSocket.isInputShutdown()) {
clientSocket.shutdownInput();
}
}
} else {
forwardData(clientSocket, forwardSocket);
}
} finally {
try {
remoteToClient.join();
} catch (InterruptedException e) {
e.printStackTrace(); // TODO: implement catch
}
}
} finally {
forwardSocket.close();
}
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
}
}
private static void forwardData(Socket inputSocket, Socket outputSocket) {
try {
InputStream inputStream = inputSocket.getInputStream();
try {
OutputStream outputStream = outputSocket.getOutputStream();
try {
byte[] buffer = new byte[4096];
int read;
do {
read = inputStream.read(buffer);
if (read > 0) {
outputStream.write(buffer, 0, read);
if (inputStream.available() < 1) {
outputStream.flush();
}
}
} while (read >= 0);
} finally {
if (!outputSocket.isOutputShutdown()) {
outputSocket.shutdownOutput();
}
}
} finally {
if (!inputSocket.isInputShutdown()) {
inputSocket.shutdownInput();
}
}
} catch (IOException e) {
e.printStackTrace(); // TODO: implement catch
}
}
private String readLine(Socket socket) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int next;
readerLoop:
while ((next = socket.getInputStream().read()) != -1) {
if (previousWasR && next == '\n') {
previousWasR = false;
continue;
}
previousWasR = false;
switch (next) {
case '\r':
previousWasR = true;
break readerLoop;
case '\n':
break readerLoop;
default:
byteArrayOutputStream.write(next);
break;
}
}
return byteArrayOutputStream.toString("ISO-8859-1");
}
}
}
Here comes the Problem:
Everything works fine but only on the local network. I cannot manage to get this to work without port forwarding. Since all devices are on their mobile cellular data I need a way to be able to connect to the device anyway.
How do the mentioned apps manage to connect to the devices?
I use the following code to record and play sounds with Java, but the volume is too low, how to make it louder, at least 2,3 times louder ?
public void Record_Audio(String File_Path,AudioFileFormat.Type File_Type)
{
try
{
audioFormat=getAudioFormat(); // Get things set up for capture
DataLine.Info dataLineInfo=new DataLine.Info(TargetDataLine.class,audioFormat);
targetDataLine=(TargetDataLine)AudioSystem.getLine(dataLineInfo);
//Create a thread to capture the microphone data into an audio file and start the thread running. It will run
// until the Stop button is clicked. This method will return after starting the thread.
new Record_Thread(File_Path,File_Type).start();
}
catch (Exception e)
{
System.out.println(e);
System.exit(0);
}
}
private void Play_Audio_Recording()
{
File Audio_File=new File(Current_Folder_Path+File_Name_ComboBox.getSelectedItem().toString().trim()+"."+Get_Audio_File_Type());
try
{
Audio_Clip=Applet.newAudioClip(Audio_File.toURI().toURL());
Audio_Clip.play();
}
catch (Exception e) { e.printStackTrace(); }
}
class Record_Thread extends Thread
{
String File_Path;
AudioFileFormat.Type File_Type;
Record_Thread(String File_Path) { this(File_Path,AudioFileFormat.Type.WAVE); }
Record_Thread(String File_Path,AudioFileFormat.Type File_Type)
{
this.File_Path=File_Path;
this.File_Type=File_Type;
}
public void run()
{
Audio_File=new File(File_Path);
try
{
targetDataLine.open(audioFormat);
targetDataLine.start();
AudioSystem.write(new AudioInputStream(targetDataLine),File_Type,Audio_File);
}
catch (Exception e) { e.printStackTrace(); }
}
}
You would use the FloatControl.Type (https://docs.oracle.com/javase/7/docs/api/javax/sound/sampled/FloatControl.Type.html) to set either the volume or the master gain. Something like:
targetDataLine=(TargetDataLine)AudioSystem.getLine(dataLineInfo);
javax.sound.sampled.FloatControl c = (FloatControl)targetDataLine.getControl(FloatControl.Type.VOLUME);
c.setValue(c.getMaximum());
might work.
A project source code has a Java method for SQL handling. The method does work, but it uses a questionable workaround: try-catch block at the very end of the method for normal execution. What is the correct way to implement it?
public void run() {
if (running) {
return;
}
running = true;
while(null == Common.server || null == Common.database || !ConnectionsPool.isInitialized()) {
// Wait until the database is set before continuing...
try {
Thread.sleep(1000);
}
catch(Exception ex) {}
}
while(running) {
final Connections cs = ConnectionsPool.getConnections();
Connection c = null;
while(!entries.isEmpty()) {
if (null == c) {
c = cs.getConnection();
}
SQLLogEntry entry = entries.remove();
if (null != entry) {
try {
write(entry, c); //find usages
}
catch (SQLException ex) {
writeLogFile("Could not write entry to SQL", ex);
}
}
}
if (null != c) {
try {
c.commit();
}
catch (SQLException ex) {
writeLogFile("Could commit to SQL", ex);
try {
c.rollback();
}
catch (SQLException ex1) {
}
// log
final StringWriter err = new StringWriter();
ex.printStackTrace(new PrintWriter(err));
EditorTransactionUtil.writeLogFile(err.toString());
// for user
final String msg = "Exception: " + EditorUtil.getErrorMessage(ex.getMessage());
try {
SwingUtilities.invokeAndWait(() -> {
JOptionPane.showMessageDialog(null, msg);
});
}
catch (Throwable ex1) {
}
}
finally {
cs.returnConnection(c);
}
c = null;
}
synchronized(entries) {
try {
entries.wait(1000);
}
catch (InterruptedException ex) {
// This is a workaround to process this loop...
}
}
}
writeLogFile("SQLMsgLogger run loop stopping...");
}
Problems with this code start here.
If(running) return;
running=true;
This is clearly an attempt to make sure that only one thread executes. This is a wrong way to check concurrency. Second tread might kick in right when if check ended, but assignment didn't start yet. You need to use syncronizible interface.
As for the disposed try catch block - as Konrad pointed out it will not be executed without Thread.interrupt() call. It might be dead code left from previous versions.
I am trying to make an application to scan documents from a scanner and i have found an application based on the mmscomputing free library that i found in github https://github.com/ashishkataria/browserWebScanning
It shows a panel from where you can choose a scanner from a list of available ones and scan the document.
public void getScan()
{
try
{
scanner.acquire();
}
catch (ScannerIOException e1)
{
IJ.showMessage("Access denied! \nTwain dialog maybe already opened!");
e1.printStackTrace();
}
}
public Image getImage()
{
Image image = imp.getImage();
return image;
}
public void update(ScannerIOMetadata.Type type, ScannerIOMetadata metadata) {
if (type.equals(ScannerIOMetadata.ACQUIRED))
{
if(imp!=null)
{
jContentPane.remove(ipanel);
jContentPane.remove(cpanel);
jContentPane.remove(crpdpanel);
}
imp = new ImagePlus("Scan", metadata.getImage());
im = imp.getImage();
imagePanel = new ImagePanel(im);
imagePanel.updateUI();
imagePanel.repaint();
imagePanel.revalidate();
ClipMover mover = new ClipMover(imagePanel);
imagePanel.addMouseListener(mover);
imagePanel.addMouseMotionListener(mover);
ipanel = imagePanel.getPanel();
ipanel.setBorder(new LineBorder(Color.blue,1));
ipanel.setBorder(BorderFactory.createTitledBorder("Scanned Image"));
ipanel.setBounds(0, 30,600, 600);
ipanel.repaint();
ipanel.revalidate();
ipanel.updateUI();
jContentPane.add(ipanel);
jContentPane.getRootPane().revalidate();
jContentPane.updateUI();
cpanel = imagePanel.getUIPanel();
cpanel.setBounds(700, 30,300, 150);
cpanel.repaint();
cpanel.setBorder(new LineBorder(Color.blue,1));
cpanel.setBorder(BorderFactory.createTitledBorder("Cropping Image"));
cpanel.setBackground(Color.white);
jContentPane.add(cpanel);
jContentPane.repaint();
jContentPane.revalidate();
metadata.setImage(null);
try {
new uk.co.mmscomputing.concurrent.Semaphore(0, true).tryAcquire(2000, null);
} catch (InterruptedException e) {
IJ.error(e.getMessage());
}
}
else if (type.equals(ScannerIOMetadata.NEGOTIATE)) {
ScannerDevice device = metadata.getDevice();
try {
device.setResolution(100);
} catch (ScannerIOException e) {
IJ.error(e.getMessage());
}
try{
device.setShowUserInterface(true);
device.setResolution(100); }catch(Exception e){
e.printStackTrace(); }
}
else if (type.equals(ScannerIOMetadata.STATECHANGE)) {
System.out.println("Scanner State "+metadata.getStateStr());
System.out.println("Scanner State "+metadata.getState());
if ((metadata.getLastState() == 3) && (metadata.getState() == 4)){}
} else if (type.equals(ScannerIOMetadata.EXCEPTION)) {
IJ.error(metadata.getException().toString());
}
}
I am trying to make it handle multiple documents and save in a pdf file, this library handles only 1 document right now.
i want to know how can i save the images in a buffer or something else and rescan until the user is done .
and is there a function that can save those images in a pdf file ?
Recently I added "adb devices" in the nano ./bash_profile so that I can run it from any directory.
I used one java application to run
public static void main(String [] args) {
executeCmd("adb devices");
}
private static void executeCmd(String string) {
InputStream pipedOut = null;
try {
Process aProcess = Runtime.getRuntime().exec(string);
// These two thread shall stop by themself when the process end
Thread pipeThread = new Thread(new StreamGobber(aProcess.getInputStream()));
Thread errorThread = new Thread(new StreamGobber(aProcess.getErrorStream()));
pipeThread.start();
errorThread.start();
aProcess.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
class StreamGobber implements Runnable {
private InputStream Pipe;
public StreamGobber(InputStream pipe) {
if(pipe == null) {
throw new NullPointerException("bad pipe");
}
Pipe = pipe;
}
public void run() {
try {
byte buffer[] = new byte[2048];
int read = Pipe.read(buffer);
while(read >= 0) {
System.out.write(buffer, 0, read);
read = Pipe.read(buffer);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(Pipe != null) {
try {
Pipe.close();
} catch (IOException e) {
}
}
}
when I run any other commands such as "ls" it's working fine!!
I'm using mac ..
thanks :)
Maybe global path problem on mac. You can try run with absolute adb program path as command.