I'm using Processing 3.5.4.
I’m trying to save() an image of the screen to data/frames (relative to my sketch file). The code I’m using works in Java mode with no problems (I can see the image saving into the correct folder on my computer), but when running it on my Android device I get java.lang.IllegalArgumentException: File data/frames/frameasdf.tif contains a path separator. I’m guessing this is because of a difference in file storage systems.
Is there any way I can avoid path separators other than saving images directly into the sketch folder?
I’m new to Java (just moved over from Javascript for more professional development), so if possible, please link to any helpful documentation.
PImage drawing;
void setup() {
size(displayWidth, displayHeight);
}
boolean clicked = false;
String name = "asdf";
void mouseReleased() {
clicked = true;
}
void draw() {
background(255);
if(drawing != null) {
image(drawing, 0, 0);
}
fill(0);
noStroke();
ellipse(mouseX, mouseY, 50, 50);
if(clicked) {
save("data/frames/frame" + name + ".tif");
drawing = loadImage("frames/frame" + name + ".tif");
}
clicked = false;
}
This is a shortened version of my code. It's a simple program that should add a dot to the screen whenever you click.
I do plan on saving more than one frame in the frames folder.
I didn't understand your question very well. Are you trying to save the file inside the specific app files or in shared storage files? the root files of the different storage systems can be got with Context.getExternalFilesDirs() that returns a vector with the files.
you can start reading the documentation here: Android storage
Related
I'm new to android developement and I'm supposed to use Java as the programming language. I have an app where I'm supposed to be able to capture images and the geographical location of the captured images and display these details. I am displaying the image in an imageView. I have a text file where I'm storing image links as well as the captured images. So, I basically have image links and captured images that are stored in an arraylist then to a text file.
Please feel free to ask for anything that I may have missed out in the question.
I tried using EXIFInterface method I found on a Stack Overflow response, I tried using Location provider but to no avail. Maybe where I'm placing the code is incorrect, as I said, I'm new to this. I tried watching YT videos and did some research online and I'm more confused than ever at this point. Another approach I tried using was capturing the current location of the device to an invisible textView then calling it to where the image name is being stored but this did not work either.
The EXIF method I tried:
`
try {
ExifInterface exifInterface = new ExifInterface(direct); //Direct is the filepath
Log.d("Latitude", exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
Log.d("Longitude", exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
} catch (IOException e) {
e.printStackTrace();
}
`
Location Provider method
#SuppressLint("MissingPermission")
private void showLocation() {
locationProvider.getLastLocation().addOnSuccessListener(this,
new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if (location != null) {
hiddenLoc.setText("Current location is: Lat:" + location.getLatitude()
+ "Lon: " + location.getLongitude());
}
}
});
}
`
EXIF location is an optional interface- most images won't have one. In fact many (most?) camera apps have stopped using it by default to protect user privacy. You can try it, but don't expect it to be there.
Your location code- lastLocation will return null unless location was already up and running (generally because another app was using it). You'd need to request location updates, rather than rely on lastLocation. Please note that this gets the location of the phone now not the location when a photo was taken. So this only works if you run it when you take the photo (the exif data gets the location where the photo was taken, if its there at all).
I currently have something working to capture screenshots on iOS for appium tests using java and junit. Before a test finishes it runs this code to get the last visible thing on the screen before killing the connection
#After
public void tearDown() throws Exception {
if (platform.equals(iOS)) {
captureScreenshot(testName.getMethodName());
}
driver.quit();
}
#SuppressWarnings("Augmenter")
public void captureScreenshot(String testName) {
String imagesLocation = "target/surefire-reports/screenshot/" + platform + "/";
new File(imagesLocation).mkdirs(); // Insure directory is there
String filename = imagesLocation + testName + ".jpg";
try {
Thread.sleep(500);
WebDriver augmentedDriver = new Augmenter().augment(driver);
File scrFile = ((TakesScreenshot)augmentedDriver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File(filename), true);
} catch (Exception e) {
System.out.println("Error capturing screen shot of " + testName + " test failure.");
// remove old pic to prevent wrong assumptions
File f = new File(filename);
f.delete(); // don't really care if this doesn't succeed, but would like it to.
}
}
This sorta works for android but lately it has completely killed the running test but this might have to do with the device it is trying to get the snapshot of. Before it would save the file but the image would come up blank or broken.
Anyone know how to get image/screen capturing working on android using appium? Perhaps something with UIAutomator?
You can use this method:
public void screenshot(String path_screenshot) throws IOException{
File srcFile=driver.getScreenshotAs(OutputType.FILE);
String filename=UUID.randomUUID().toString();
File targetFile=new File(path_screenshot + filename +".jpg");
FileUtils.copyFile(srcFile,targetFile);
}
It works fine for me.
I happened to find this via Google search with nearly the same problem - Appium screenshots in the Android emulator come up blank. I'm using both the 'native' method much like you describe above - and - the method within the ATU framework.
WebElement appArea = wd.findElementByXPath("//android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.widget.LinearLayout[1]");
ATUReports.add("Main Screen Area Screenshot", LogAs.INFO, new CaptureScreen(appArea));
and both come back blank/transparent. The marginally good news is that the dimension of that blank/transparent image is exactly the size I want to capture - avoiding the status bar where date diffs would cause error on image comparison. That said, it's not much use without actual viewable pixels (for eventual matching of object area grabs to validated baseline images).
I tried setting context to "NATIVE_APP" and nothing seems to help. I am - in a word - vexed. If you've made any progress with this I'd love to read/hear how you got it working. Maybe the next step is to go to the Appium Google Group.
EDIT: I found the core issue in my case - using HAXM acceleration causes the blank screen shots. Note this also affects test run on physical devices if the base device profile set in the test's capabilities is defined with "Host GPU" selected.
I'm trying to use Javas JFileChooser in my LibGDX scene2d project, but as soon as I launch JFileChooser my program freezes.
Here is the code I use to launch file chooser:
private String getPath(){
String path = "";
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = fc.getSelectedFile();
try {
path = file.getAbsolutePath();
} catch (Exception ex) {
System.out.println("problem accessing file" + file.getAbsolutePath() + "\n" + ex.getMessage());
}
} else {
System.out.println("File access cancelled by user.");
}
return path;
}
is it swing and libgdx compability problem or is there something I am missing? Same code works perfectly with nativa java projects.
Except instead of: fc.showOpenDialog(null);
I use: fc.showOpenDialog(button); // button is the JButton that triggers the event.
any idea what am I doing wrong?
EDIT: I don't really mind if it wont work on other platforms than Windows.
BUT if I choose to go with cross platform solution, and use LibGDX's method, do I have to create file chooser class with UI from scratch all by myself?
Ok based on your comments from the answer above I get a sense that what you are trying to do is invoke a swing window INSIDE your LibGDX game window, which is an open GL rendering scene.
Let me stop you right there. The swing toolkit invokes its own rendering engine, because it's not intended for this purpose at all - it's intended for desktop applications. So when you instantiate the dialogue, all sorts of other oracle java stuff gets instantiated along with it, like the Graphics2D class. You can't just add this class to a scene2D stage and expect that it draws. They don't implement the same interfaces or inherit from the same base classes. The draw(Graphics2D graphics) method that your JFileChooser implements is not the same as whatever draw(SomeClass foo) method that your libGDX classes implement.
So if you want to make a file chooser window, you need to start looking at the libGDX widget libraries. There might be something that someone has put together already, but my approach for my next libGDX project is going to be to extend these classes for my own UI libraries. I don't know what your project is, or what your timeline is like, but it's certainly a better approach then trying to adapt the swing toolkit to render in an OpenGL rendering scene.
edit
After some quick reading, I'm going to go one further and hazard a guess that the way the swing toolkit gets rendered is entirely dependent on the implementation of the JVM for a specific platform. Now this is where my CS knowledge starts to be a little limited, but I would hazard another guess that this is way way different than the LWJGL implementation of OpenGl by way of using Java wrappers for C libraries.
Personally I dislike the existing FileChooser UIs inside LibGDX. So I created a solution which works using the JFileChooser. Here is some quick and dirty code:
new Thread(new Runnable() {
#Override
public void run() {
JFileChooser chooser = new JFileChooser();
JFrame f = new JFrame();
f.setVisible(true);
f.toFront();
f.setVisible(false);
int res = chooser.showSaveDialog(f);
f.dispose();
if (res == JFileChooser.APPROVE_OPTION) {
//Do some stuff
}
}
}).start();
This will open the FileChooser in front of the LibGDX window without blocking the main Thread. Just tested this on Windows 7, 8, 10 and it only works in window mode ofc.
Coming late to the party but if the point of the question is to invoke a "native" ie. non-gdx file chooser from a libgdx project I made a library to do so here: https://github.com/spookygames/gdx-nativefilechooser.
Example from the readme:
// Configure
NativeFileChooserConfiguration conf = new NativeFileChooserConfiguration();
// Starting from user's dir
conf.directory = Gdx.files.absolute(System.getProperty("user.home"));
// Filter out all files which do not have the .ogg extension and are not of an audio MIME type - belt and braces
conf.mimeFilter = "audio/*";
conf.nameFilter = new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
return name.endsWith("ogg");
}
};
// Add a nice title
conf.title = "Choose audio file";
fileChooser.chooseFile(conf, new NativeFileChooserCallback() {
#Override
public void onFileChosen(FileHandle file) {
// Do stuff with file, yay!
}
#Override
public void onCancellation() {
// Warn user how rude it can be to cancel developer's effort
}
#Override
public void onError(Exception exception) {
// Handle error (hint: use exception type)
}
});
On the desktop, this example will currently launch an AWT FileDialog (not exactly what is asked) yet a Swing version is currently on the master branch and should be incorporated to the next version of the lib.
Both versions work but I am not sure which one to use and why to use that version? Do you need to dispose the TextureAtlas if you unload the assets already?
Version 1: Load the pack file (TexturePacker file with positions data) along with the png.
gameSpriteSheet = new TextureAtlas(Gdx.files.internal(DATA_DIR_PATH + "GameSpritesPack.txt"));
assetManager.load(DATA_DIR_PATH + "GameSpritesPack.txt");
assetManager.load(DATA_DIR_PATH + "GameSpritesPack.png");
// Call only if assetmanager's update method returns true
headerRegion = getTexture("MainMenuHeader", gameSpriteSheet);
To unload:
if (assetManager.isLoaded(DATA_DIR_PATH + "GameSpritesPack.txt")) {
assetManager.unload(DATA_DIR_PATH + "GameSpritesPack.txt");
}
if (assetManager.isLoaded(DATA_DIR_PATH + "GameSpritesPack.png")) {
assetManager.unload(DATA_DIR_PATH + "GameSpritesPack.png");
}
if(gameSpriteSheet != null) {
gameSpriteSheet.dispose();
}
Version 2: Load only the pack file (TexturePacker file with positions data).
assetManager.load(DATA_DIR_PATH + "GameSpritesPack.txt");
// Call only if assetmanager's update method returns true
gameSpriteSheet = assetManager.get(DATA_DIR_PATH + "GameSpritesPack.txt", TextureAtlas.class);
headerRegion = getTexture("MainMenuHeader", gameSpriteSheet);
To unload:
if (assetManager.isLoaded(DATA_DIR_PATH + "GameSpritesPack.txt")) {
assetManager.unload(DATA_DIR_PATH + "GameSpritesPack.txt");
}
if(gameSpriteSheet != null) {
gameSpriteSheet.dispose();
}
Note: I have read Mario's post on AssetManager and other blogs on that but I don't seem to get why the both versions above work fine.
The AssetManager is for loading assets "in the background". The first version you listed just loads the atlas synchronously in the current thread. Its not actually using the AssetManager at all. This is fine and will work, the downside is that if your atlas is large (or you have a lot of them that you're doing this for), your app will "hang" for a moment while:
gameSpriteSheet = new TextureAtlas(Gdx.files.internal(DATA_DIR_PATH + "GameSpritesPack.txt"));
runs. You could delete the two assetManager lines in your first example, as they're not doing anything (useful) in this case.
The second version is a "correct" usage of the AssetManager. Basically you're asking the asset manager to run the code you used in the first version ( ... new TextureAtlas(...)) on a background thread. You must wait until that background thread completes (i.e., update() returns true). The idea is that you can do other stuff on the render thread in the foreground (i.e., animate pretty patterns on the screen to distract the user while you load up game assets) while periodically checking if the loading is complete.
I have a Java Swing application which shows a list of the files/Folders that have been uploaded to the server. I have a requirement to download selected file(s)/folder(s) to native file system using Drag and Drop . I have searched links but almost every link describes the Drag and Drop within a Java Swing application. My requirement is to Drag the file from the Java Swing application and Drop it to the native file system.
I need help to know how I can get the location where user has dropped the selected file(s)/folder(s) to the native file system.
For example, let's suppose the user has dragged the file and dropped directly to the C:\Back_Up folder by restore the window of Java Application. How can I identify the location that user has dropped the file to, i.e. C:\Back_Up?
AFAIK, it's not possible to get the information, where a dragged object has been dropped. Guess, your idea was to know the drop point and copy the file to that position in a second step.
But I think, it doesn't work this way and, even worse, the whole think could be pretty OS dependant. I bet, you have to put the entire file on the transfer. I know that it's possible with SWT, but SWT ships with some native libraries...
Here's at least one link that shows an example for the other way round: Drag and drop of a group of files into a tree
Thanks Andreas..
We have a JAVA component as a Table from which we drag the file and dropped to native file system. We have code like
A> Component is JXTree. We have set following property to support Drag And Drop.
Component.setDropMode(DropMode.INSERT);
Component.setDragEnabled(true);
DragSource ds = DragSource.getDefaultDragSource();
DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer( Component,
DnDConstants.ACTION_MOVE, new FileDragGestureListener());
B> We have written a class which implements Drag Gesture Listener.
public class FileDragGestureListener extends DragSourceAdapter implements DragGestureListener {
public void dragGestureRecognized(DragGestureEvent dge) {
We get selected row from table.
Download the selected File to Native file System's TEMP directory.
FileSystemView fsv = FileSystemView.getFileSystemView();
Icon icn = fsv.getSystemIcon(File);
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension dim = tk.getBestCursorSize(icn.getIconWidth(), icn.getIconHeight());
BufferedImage buff = new BufferedImage(dim.width, dim.height,
BufferedImage.TYPE_INT_ARGB);
if (DragSource.isDragImageSupported()) {
evt.startDrag(DragSource.DefaultCopyDrop, buff, new Point(0, 0),
new TextFileTransferable(File),
this);
} else {
cursor = tk.createCustomCursor(buff, new Point(0, 0), "sString");
evt.startDrag(cursor, null, new Point(0, 0),
new TextFileTransferable(File),
this);
}
}
class TextFileTransferable implements Transferable {
File temp;
public TextFileTransferable(File temp) throws IOException {
this.temp = temp;
}
public Object getTransferData(DataFlavor flavor) {
List list = new ArrayList();
list.add(temp);
return list;
}
public DataFlavor[] getTransferDataFlavors() {
DataFlavor[] df = new DataFlavor[1];
df[0] = DataFlavor.javaFileListFlavor;
return df;
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
if (flavor == DataFlavor.javaFileListFlavor) {
return true;
}
return false;
}
}
So this is how we can able to download the file up to %TEMP% then we can not move that file to a location where is has been dropped.
Please suggest where i am wrong OR what best approach to implement this Drag And Drop.
Thanks
I believe Java Desktop API could accomplish this. Not sure about details, though...
Maybe if you knew in general what directories people would be dropping into, your application could create file objects pointed at those directories and then use the Observer design pattern to tell your application when something got dropped into them (by polling the contents, maybe) although if other programs/people dropped things into those directories you'd get notified of that too, but then you could compare the time that notification came in with the time you could know that you did some dropping. This would reduce it to the arguably low probability (yet uncomfortably still possible) case of someone else dropping into directory A at almost the exact same time you dropped into directory B.
Good luck!
Some clue can be obtained from JDesktop Integration Components: https://jdic.dev.java.net/