This is a very simple question which I cannot find a solution for. I have a quite complex Android app which uses the camera and does some manipulations to the images taken. I now want to write Unit tests for some of the functions but I cannot get a file loaded.
In an Android test project where should I paste the Image to test on and how can I load that image into a File object? I have a normal junit.framework.TestCase class that needs to send a File to an class to test on. Thanks in advance!
This may not be the best solution since it could bloat your project considerably. However, short of writing code to download an image in your test cases, I'm not sure what other approach there might be.
Simply, i have 'test' drawables in my resources and I load them as bitmaps, then store them somewhere on the disc to finally reference them in my tests. This is the code I use:
public File saveResourceImageToExternalStorage(Activity activity, String picFileName, int imageId)
{
Bitmap bitmap = BitmapFactory.decodeResource(activity.getResources(), imageId);
File picFile = null;
OutputStream os = null;
try
{
picFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), picFileName);
picFile.createNewFile();
os = new FileOutputStream(picFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
}
catch (IOException e)
{
e.printStackTrace();
}
return file;
}
You'll probably want to make that method a little more robust.
Finally, you could just stash your test images in your assets folder for your project. Then you can get them from your assets folder using getAssets() in an Activity or using the path which should be something like file:///android_asset/your_file_name.jpg
EDIT
I think a better solution, after some research, would be to add your files to the assets of your test project and use InputStream input = this.getContext().getAssets().open("file.jpg");. You need to call this from a class that inherits from InstrumentationTestCase or, I suppose, ActivityInstrumentationTestCase2. You can then manipulate the input stream how you need
Related
I'm using a custom method to get pictures from the resources/ folder. The hardcoded path works well when programming during production (src/main/resources/). However when delivering, I would need to make this path relative to the .jar root. So I made this.
public static Image getImageFromFile(String file)
{
Image image = null;
try
{
String path = FileUtils.class.getClassLoader().getResource(file).toExternalForm();
System.out.println(path);
File pathToFile = new File(path);
image = ImageIO.read(pathToFile);
}
catch (IOException ex) {ex.printStackTrace();}
return image;
}
file:/C:/Users/Hugo/Desktop/Hugo/Java%20Workspace/ClashBot/bin/main/icons/level-label.png
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(Unknown Source)
at com.lycoon.clashbot.utils.FileUtils.getImageFromFile(FileUtils.java:55)
The printed path is valid and points to the corresponding picture. However, the program raises an IOException.
Why can't it find the file?
You're jumping through way too many hoops. It's quite simple:
FileUtils.class.getResource("path.png");
// -OR-
try (var in = FileUtils.class.getResourceAsStream("path.png")) {
// in is an inputstream.
}
is all you need. Note that this means the path.png file is searched for in the exact same place (and even same 'subdir') as where FileUtils lives. So if you have, say, a file on C:\Projects\Hugo\MyApp\myapp.jar, and if you were to unzip that, inside you'd find com/foo/pkg/FileUtils.class, then the string path.png would look in that jar, and for com/foo/pkg/path.png. In other words, AnyClass.class.getResource("AnyClass.class") will let a class find its own class file. If you want to go from the 'root' of the jar, add a slash, i.e. FileUtils.class.getResource("/path.png") looks in the same jar, and for /path.png inside that jar.
getResource returns a URL. getResourceAsStream returns a stream (which you need to close; use try-with-resources as I did). Just about every resource-using API out there will take one of these two as input. For example, ImageIO does so; it even takes a URL so you can use either one:
var image = ImageIO.read(FileUtils.class.getResource("imgName + ".png"));
Yes. It's a one-liner. This will load images straight from within a jar file!
You could try to use a slightly different call like this:
java.net.URL fileUrl = Thread.currentThread().getContextClassLoader().getResource(file);
String filePath = URLDecoder.decode(fileUrl.getPath(), "UTF-8");
image = ImageIO.read(filePath);
I was wondering if there is a way to access a file and it's path from my assets folder in android studio? The reason why I need to access the file and its path is because I am working with a method that REQUIRES the String path for a file, and it must access the file from its String path. However, in android studio I haven't found a way to access the file directly from the String value of its path. I decided to use a workaround and simply read the file from an InputStream and write the file to an OutputStream, but the file is about 170MB, and it is too memory intensive to write the File to an OutputStream. It takes my application about 10:00 Minutes to download the file when I implement that strategy. I have searched all over this website and numerous sources to find a solution (books and documentation) but am unable to find a viable solution. Here is an example of my code:
#Override
public Model doInBackground(String... params){
try {
String filePath = context.getFilesDir() + File.separator + "my_turtle.ttl";
File destinationFile = new File(filePath);
FileOutputStream outputStream = new FileOutputStream(destinationFile);
AssetManager assetManager = context.getAssets();
InputStream inputStream = assetManager.open("sample_3.ttl");
byte[] buffer = new byte[10000000];
int length = 0;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
outputStream.close();
inputStream.close();
model = ModelFactory.createDefaultModel();
TDBLoader.loadModel(model, filePath, false);//THIS METHOD REQUIRES THE FILE PATH.
MainActivity.presenter.setModel(model);
}catch(FileNotFoundException e){
e.printStackTrace(System.out);
}
catch(IOException e){
e.printStackTrace(System.out);
}
return model;
}
As you can see the TDBLoader.loadModel() method requires a String for the file URI as the second argument, so it would be convenient to have the ability to access the File directly from my assets folder without utilizing an InputStream. The method takes as an argument (Model model, String url, Boolean showProgress). As I mentioned, the current strategy I am using utilizes too much memory and either crashes the Application entirely, or takes 10 minutes to download the file I need. I am using an AsyncTask to perform this operation, but due to the length of time required to perform the task that kind of defeats the purpose of an AsyncTask in this scenario.
What further complicates things is that I have to use an old version of Apache Jena because I am working with Android Studio and the official version of Apache Jena is not compatible with android studio. So I have to use a port that is 8 years old which doesn't have the updated classes that Apache Jena offers. If I could use the RDFParser class I could pass an InputStream, but that class does not exist in the older version of Apache Jena that I must use.
So I am stuck at this point. The method must utilize the String url path of the file in my assets folder, but I don't know how to access this without writing to a custom file from an InputStream, but writing to the file from the InputStream utilizes too much memory and forces the App to crash. If anyone has a solution I will greatly appreciate it.
Here is an example of my code
new byte[10000000] may fail, as you may not have a single contiguous block of memory that big. Plus, you might not have that much heap space to begin with. Use a smaller number, such as 65536.
It takes my application about 10:00 Minutes to download the file when I implement that strategy
The time will vary by hardware. I would not expect it to be that slow on most devices, but it could be on some.
I was wondering if there is a way to access a file and it's path from my assets folder in android studio?
You are running your app on Android. Android Studio is not running on Android. Assets are not files on the Android device. They are entries in the APK file, which is basically a ZIP archive. In effect, your code is unZIPping 170MB of material and writing it out to a file.
If anyone has a solution I will greatly appreciate it.
Work with some people to port over an updated version of Jena that offers reading RDF from an InputStream.
Or switch to some other RDF library.
Or work with the RDF file format directly.
Or use a smaller RDF file, so the copy takes less time.
Or download the RDF file, if you think that will be preferable to copying over the asset.
Or do the asset-to-file copying in a foreground JobIntentService, updating the progress in its associated Notification, so that the user can do other things on their device while you complete the copy.
I'm programming an app for android using libgdx and simplexml to load the levels. Now I want to load the level1.xml file which is located at the android assets file but I don't know how to get the correct path to it. This is my code:
private Level currentLevel;
...
loadLevel(1);
...
private void loadLevel(int level) {
String path = Gdx.files.internal("level" + level +".xml").path();
try {
InputStream source = new FileInputStream(path);
Serializer serializer = new Persister();
currentLevel = serializer.read(Level.class, source);
} catch (Exception e) {
e.printStackTrace();
}
}
But the path I get is just "level1.xml". I know how to do this with
InputStrem source = getAssets().open("level1.xml");
Because I'm doing this in my core-module I can't use the android libraries and I want use my app on windows/linux/html too.
I hope my question is understandable. Thanks for your help!
In case of internal (read only, packed with the app, as it seems to be in your question) your files should be located at "project/android/assets", (or "project/core/assets" if not targeting android backend) and you can load them using Gdx.files.internal(), so in this case, it would be
Gdx.files.internal("level1.xml")
It will return a FileHandle, you can read the content as string directly using
Gdx.files.internal("level1.xml").readString();
Remember to set the working directory of your desktop project to "project/android/assets"
I recomend you to read the wiki, it explains it very detailed here
You can access file in assets like this
"file:///android_asset/level1.xml"
I've been putting all of my images for my Java application in a package called "rtype" inside src where I also also have my Class that deals with these images. I wanted to sort the images and put them in a folder of their own. When I do this, The images will no longer load into the class, and I know it's because I changed the file path. I've done some research and tried a few different things. This is basically what I had originally:
String walkingDown = "WalkingDown.gif";
ImageIcon ii;
Image image;
ii = new ImageIcon(this.getClass().getResource(walkingDown));
image = ii.getImage();
and It worked just fine before I moved the location of the images outside the location of the class. Now it cant find the images. Here is what I tried and found online to try (The folders Name is Sprites):
//use getClassLoader() inbetween to find out where exactly the file is
ii = new ImageIcon(this.getClass().getClassLoader().getResource(standingDown));
and
//Changing the path
String walkingDown = "src\\Sprites\\WalkingDown.gif";
//also tried a variation of other paths with no luck
I am using the C drive, but don't want to use "C" in my extension, as I want it to be accessible no matter where I put the project. I am fairly stuck at this point and have done enough looking into it to realize that It was time to ask.
I have a separate "package" for images with that name (in the src folder)
Try something like this:
try {
ClassLoader cl = this.getClass().getClassLoader();
ImageIcon img = new ImageIcon(cl.getResource("images/WalkingDown.gif"));
}
catch(Exception imageOops) {
System.out.println("Could not load program icon.");
System.out.println(imageOops);
}
Your variable is named walkingDown, but you pass in standingDown to the getResource() method.
new ImageIcon("src/Sprites/WalkingDown.gif");
I am developing web method for webservice in java. In this web method I have to read image from my images folder which resides in my webservice project folder. I am using the code as follows.
#WebMethod(operationName = "getAddvertisementImage")
public Vector getAddvertisementImage()
{
Image image = null;
Vector imageList = new Vector();
try
{
File file = new File("E:/SBTS/SBTSWebservice/web/adv_btm.jpg");
image = ImageIO.read(file);
imageList.add(image);
}
catch (IOException e)
{
e.printStackTrace();
}
return imageList;
}
I am unable to read image from images folder.I am getting error image file "input file can't read" at image = ImageIO.read(file); how to resolve this issue ? Is there any mistake in my code or is there any other way to read image ? if there is any mistake in my code then can you proide me the code or link through which i can resolve the above issue.
Is the E:\ drive mapped on your web server? The Java compiler has no idea that you might access files outside of its scope and how it could tell your web server to map a network drive or a local hard disk which is attached to your development computer.
The solution is to put the image file into the same directory as the Java source file and then use
InputStream in = getClass().getResourceAsStream("adv_btm.jpg");
Check that your IDE (or whatever you use to build your application) does copy the image file in the same directory where it creates the .class file. Then it should work.