captureAudio example in codenameone not working on device simulator - codenameone

I am trying the captureAudio example given in the codenameone documentation https://gist.githubusercontent.com/codenameone/a347dc9dcadaa759d0cb/raw/089f171a37e43f558ce897a0b51cab46219c37c0/CaptureAudioSample.java
Copying the code here for convenience:
Form hi = new Form("Capture", BoxLayout.y());
hi.setToolbar(new Toolbar());
Style s = UIManager.getInstance().getComponentStyle("Title");
FontImage icon = FontImage.createMaterial(FontImage.MATERIAL_MIC, s);
FileSystemStorage fs = FileSystemStorage.getInstance();
String recordingsDir = fs.getAppHomePath() + "recordings/";
fs.mkdir(recordingsDir);
try {
for(String file : fs.listFiles(recordingsDir)) {
MultiButton mb = new MultiButton(file.substring(file.lastIndexOf("/") + 1));
mb.addActionListener((e) -> {
try {
Media m = MediaManager.createMedia(recordingsDir + file, false);
m.play();
} catch(IOException err) {
Log.e(err);
}
});
hi.add(mb);
}
hi.getToolbar().addCommandToRightBar("", icon, (ev) -> {
try {
String file = Capture.captureAudio();
if(file != null) {
SimpleDateFormat sd = new SimpleDateFormat("yyyy-MMM-dd-kk-mm");
String fileName =sd.format(new Date());
String filePath = recordingsDir + fileName;
Util.copy(fs.openInputStream(file), fs.openOutputStream(filePath));
MultiButton mb = new MultiButton(fileName);
mb.addActionListener((e) -> {
try {
Media m = MediaManager.createMedia(filePath, false);
m.play();
} catch(IOException err) {
Log.e(err);
}
});
hi.add(mb);
hi.revalidate();
}
} catch(IOException err) {
Log.e(err);
}
});
} catch(IOException err) {
Log.e(err);
}
hi.show();
I am using Intellij and trying to test the above code in device simulator. But when I click the mic button I see a 'file chooser' dialog box with only a cancel option enabled. On clicking cancel nothing happens. If I choose a wav file then click ok, it gets copied and i am able to play it in simulator. Is mic input not supported in simulator? Is it getting replaced with file input? Or am I doing anything wrong?

We don't capture from the mic in the simulator as we consider the file chooser more convenient for debugging and simulating actual capture cases. This allows us to reproduce failures/test cases with 100% accuracy.
Also the media API's in JavaSE are "flaky" and we don't want to rely on them anymore than we have to.
On the device you will get a recorder interface as usual.
Notice that this is true for image, video capture and picking from the picture gallery too.

Related

Display different types of files in a carousel tabs

I need to implement a carousel to show images/video/pdf/ppt files. I used Tab component to achieve it. But it's not working as expected. The first tab displays image correctly but at the same time pdf file gets opened which is there on the third tab. Second tab video does not play. I tried calling these events on tab selection but still not working. My code as below.
Form hi = new Form("Swipe Tabs", new LayeredLayout());
Tabs t = new Tabs();
t.hideTabs();
container1 = BoxLayout.encloseY();
container2 = BoxLayout.encloseY();
container3 = BoxLayout.encloseY();
InputStream is = null;
ImageViewer iv = null;
try{
is = Display.getInstance().getResourceAsStream(getClass(), "/Img1.png");
iv = new ImageViewer(Image.createImage(is));
}catch(Exception exc){
exc.printStackTrace();
}
container1 = BoxLayout.encloseY(iv);
FileSystemStorage fs = FileSystemStorage.getInstance();
fs.mkdir(fs.getAppHomePath());
String fileName = fs.getAppHomePath() + "test.mp4";
if(!fs.exists(fileName)) {
Util.downloadUrlToFile("http://localhost/app/test.mp4", fileName, true);
}
try{
Media video = MediaManager.createMedia(fileName, true);
video.setNativePlayerMode(true);
container2 = BoxLayout.encloseY(new MediaPlayer(video));
video.play();
}catch(Exception exc){
exc.printStackTrace();
}
fs = FileSystemStorage.getInstance();
fs.mkdir(fs.getAppHomePath());
final String fileName1 = fs.getAppHomePath() + "file1.pdf";
if(!fs.exists(fileName1)) {
Util.downloadUrlToFile("http://localhost/app/file1.pdf", fileName1, true);
}
container3 = BoxLayout.encloseY();
Display.getInstance().execute(fileName1);
t.addTab("Tab1", container1);
t.addTab("Tab2", container2);
t.addTab("Tab3", container3);
new ButtonGroup(firstTab, secondTab, thirdTab);
firstTab.setSelected(true);
Container tabsFlow = FlowLayout.encloseCenter(firstTab, secondTab, thirdTab);
hi.add(t);
hi.add(BorderLayout.south(tabsFlow));
hi.show();
Display.execute launches an external viewer to display something. It doesn't create a component you can embed. We don't support embedding a PDF as that isn't available on Android and is a bit flaky on iOS. If you only care about iOS you can use a BrowserComponent to show a PDF. You can use a button and invoke execute when the button is pressed to show a PDF.
Change this:
container2 = BoxLayout.encloseY(new MediaPlayer(video));
video.play();
To:
MediaPlayer mp = new MediaPlayer(video);
container2 = mp;
mp.setAutoplay(true);
mp.setLoop(true);
Finally, I would suggest using Log.e() not printStackTrace().

MediaManager api not working on android phone

when i got to know of the mediamanager api I used it to create a video player just as it was said the tutorial. It runs on the simulator but does not work on my phone.
What do you think is the problem.My Computer runs with a Windows 8 Pro and I tried the app on x-tigi phone and tablet. I got the code from a pdf named Codename One Developer Guide This is the code:
final Form hi = new Form("MediaPlayer", new BorderLayout());
hi.setToolbar(new Toolbar());
Style s = UIManager.getInstance().getComponentStyle("Title");
FontImage icon = FontImage.createMaterial(FontImage.MATERIAL_VIDEO_LIBRARY, s);
hi.getToolbar().addCommandToRightBar("", icon, (evt) -> {
Display.getInstance().openGallery((e) -> {
if(e != null && e.getSource() != null) {
String file = (String)e.getSource();
try {
Media video = MediaManager.createMedia(file, true);
hi.removeAll();
hi.add(BorderLayout.CENTER, new MediaPlayer(video));
hi.revalidate();
} catch(IOException err) {
Log.e(err);
}
}
}, Display.GALLERY_VIDEO);
});
hi.show();
}

Implement download progress bar

While downloading a file, it shows download progress in the notification or somewhere.
But i think it is not by default in cn1 app. I want to add progress listener. How to make it work??
if (!FileSystemStorage.getInstance().exists(filename)) {
com.codename1.io.Util.downloadUrlToFile(PdfUrl, filename, true);
}
In my case used the code below.
/**
* Adaptation of Util.downloadUrlTo
*/
private boolean downloadUrlToAdapt(String url, final String fileName, boolean storage, final Slider slider) {
final ConnectionRequest cr = new ConnectionRequest();
cr.setPost(false);
cr.setFailSilently(true);
cr.setUrl(url);
if (storage) {
cr.setDestinationStorage(fileName);
} else {
cr.setDestinationFile(fileName);
}
NetworkManager.getInstance().addProgressListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (evt instanceof NetworkEvent) {
NetworkEvent e = (NetworkEvent) evt;
if (e.getProgressPercentage() >= 0) {
slider.setText(e.getProgressPercentage() + "%");
slider.setProgress(e.getProgressPercentage());
}
}
}
});
NetworkManager.getInstance().addToQueueAndWait(cr);
return cr.getResponseCode() == 200;
}
I needed to show video download progress. I hope it helps.
The way the browser downloads a file locally is a special case for browsers and unrelated to apps. You can just invoke Display.execute with a file and the browser will download it that way although I'm guessing its not what you want since it will not be accessible to you after the fact.
You can show progress using NetworkManager's progress listener. Showing the progress in the notification area is an Android specific behavior and uncommon on iOS. But you might be able to use some of the local notification features https://www.codenameone.com/blog/local-notifications.html
I used it the same way as Sadart Abukari.
Only thing I changed is I used the ToastBar.Status instead to display the progress
[...]
NetworkManager.getInstance().addProgressListener((evt) -> {
if (evt instanceof NetworkEvent) {
NetworkEvent e = (NetworkEvent) evt;
if (e.getProgressPercentage() >= 0) {
status.setProgress(e.getProgressPercentage());
}
}
});
NetworkManager.getInstance().addToQueueAndWait(cr);
//Clear the ToastBar
status.clear();
return cr.getResponseCode() == 200;
}

How to attach Failed Test Case screen shot using reporter.log() in the TestNG Index.html report

am using a static method to take screen shot and using reporter.log function attaching the screen shot to the index.html report of testNg. Here is the code for taking screen shot.
public class GenericHelper extends CNLogin {
public static String takeScreenShot(String methodName){
try {
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
// C:\Users\499290\AppData\Local\Temp\screenshot7520341205731631960.png
String FilePath = "C:\\Users\\499290\\Downloads\\CNProject1\\CNProject\\test-output\\";
new File(FilePath);
FileUtils.copyFile(scrFile, new File( FilePath +methodName +".jpg") );
System.out.println("***Placed screen shot in "+scrFile+" ***");
}
catch(IOException e) {
e.printStackTrace();
}
return methodName+".jpg";
}
}
Am attching the screen shot by using the below code in the index.html report
String TakescreenShot = GenericHelper.takeScreenShot("AddNewPr");
Reporter.log("<a href=\"" + TakescreenShot + "\"><p align=\"left\">Add New PR screenshot at " + new Date()+ "</p>");
am not able to take screen shot when a test case is failed neither the screen shot is getting attached to the report.
Here is my test case if it got passed my screen shot method will take the screen shot and attach the screen shot in the report but when its failed not sure how to take the screen shot.
public void MultipleServiceDelete() throws InterruptedException {
driver.findElement(By.id("page:frm:pageB:repeatUpper:0:repeat:0:chkIsDelete")).click();
Thread.sleep(5000);
driver.findElement(By.id("page:frm:pageB:btnDeleteMultipleServices")).click();
String DeleteService = ScreenShot.takeScreenShot("MultipleServiceDelete");
Reporter.log("<a href=\"" + DeleteService + "\"><p align=\"left\"> Delete Service screenshot at " + new Date()+ "</p>");
}
You will want to add a TestNG listener that takes a screenshot when the test fails. Here is some code for a listener taken from my Selenium Maven Template:
package com.lazerycode.selenium.listeners;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.Augmenter;
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import static com.lazerycode.selenium.DriverFactory.getDriver;
public class ScreenshotListener extends TestListenerAdapter {
private boolean createFile(File screenshot) {
boolean fileCreated = false;
if (screenshot.exists()) {
fileCreated = true;
} else {
File parentDirectory = new File(screenshot.getParent());
if (parentDirectory.exists() || parentDirectory.mkdirs()) {
try {
fileCreated = screenshot.createNewFile();
} catch (IOException errorCreatingScreenshot) {
errorCreatingScreenshot.printStackTrace();
}
}
}
return fileCreated;
}
private void writeScreenshotToFile(WebDriver driver, File screenshot) {
try {
FileOutputStream screenshotStream = new FileOutputStream(screenshot);
screenshotStream.write(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES));
screenshotStream.close();
} catch (IOException unableToWriteScreenshot) {
System.err.println("Unable to write " + screenshot.getAbsolutePath());
unableToWriteScreenshot.printStackTrace();
}
}
#Override
public void onTestFailure(ITestResult failingTest) {
try {
WebDriver driver = getDriver();
String screenshotDirectory = System.getProperty("screenshotDirectory");
String screenshotAbsolutePath = screenshotDirectory + File.separator + System.currentTimeMillis() + "_" + failingTest.getName() + ".png";
File screenshot = new File(screenshotAbsolutePath);
if (createFile(screenshot)) {
try {
writeScreenshotToFile(driver, screenshot);
} catch (ClassCastException weNeedToAugmentOurDriverObject) {
writeScreenshotToFile(new Augmenter().augment(driver), screenshot);
}
System.out.println("Written screenshot to " + screenshotAbsolutePath);
} else {
System.err.println("Unable to create " + screenshotAbsolutePath);
}
} catch (Exception ex) {
System.err.println("Unable to capture screenshot...");
ex.printStackTrace();
}
}
}
The bit you will probably be most interested in is the method called onTestFailure. This is the part that will be triggered when a test fails. I have a driver factory that provides my access to my driver object, the call to getDriver is getting my driver object from the factory. If you have just got a statically defined driver object you can probably ignore the line:
WebDriver driver = getDriver();
The other methods are just convenience methods to create a file and write the screenshot to it. You'll obviously need to tweak this a bit to allow it to take the location that the screenshot has been written and pass it into your reported log.
I would suggest giving the listener access to your Reporter object and changing:
System.out.println("Written screenshot to " + screenshotAbsolutePath);
to:
Reporter.log("<a href=\"" + screenshotAbsolutePath + "\"><p align=\"left\">Add New PR screenshot at " + new Date()+ "</p>");
In the code above, the directory that the screenshots are saved into is set using a system property called "screenshotDirectory". You will either need to set his system property, or change the following line to a hard coded location where you would like to save your screenshots. To do that this line:
String screenshotDirectory = System.getProperty("screenshotDirectory");
Will need to change to something like:
String screenshotDirectory = "/tmp/screenshots";
or if you use windows, something like:
String screenshotDirectory = "C:\\tmp\\screenshots";

CodeName One IOS CaptureAudio

I called captureAudio method from Capture class.
It opens an empty dialog box on IOS 7, with save/cancel buttons.
No audio bar shown to user understands recording.
It's ok on android.
Since iOS doesn't have a capture UI like Androids this is implemented entirely in Java. You can write your own implementation of this rather easily e.g. this is from the Codename One IOSImplementation.java file that does exactly that:
public void captureAudio(ActionListener response) {
String p = FileSystemStorage.getInstance().getAppHomePath();
if(!p.endsWith("/")) {
p += "/";
}
try {
final Media media = MediaManager.createMediaRecorder(p + "cn1TempAudioFile", MediaManager.getAvailableRecordingMimeTypes()[0]);
media.play();
boolean b = Dialog.show("Recording", "", "Save", "Cancel");
final Dialog d = new Dialog("Recording");
media.pause();
media.cleanup();
d.dispose();
if(b) {
response.actionPerformed(new ActionEvent(p + "cn1TempAudioFile"));
} else {
FileSystemStorage.getInstance().delete(p + "cn1TempAudioFile");
response.actionPerformed(null);
}
} catch(IOException err) {
err.printStackTrace();
response.actionPerformed(null);
}
}

Resources