java external storage directory library - java

I want to start by saying that I am very new to java so I am having issues finding resources. I am trying to find a library that will allow for me to access files in a Moto G4 phone. I have found plenty of examples of how to do this but they never say what library they are using. The code I am interested in is the following: (Note that this is an example and not what I will be doing with these files. I just want to get this script to run)
String path = Environment.getExternalStorageDirectory().toString()+"/Pictures";
Log.d("Files", "Path: " + path);
File directory = new File(path);
File[] files = directory.listFiles();
Log.d("Files", "Size: "+ files.length);
for (int i = 0; i < files.length; i++)
{
Log.d("Files", "FileName:" + files[i].getName());
}
This was pulled from another post on how to find files on an Android phone. Any help would be greatly appreciated. It is important to note that this is just so that I can gain access to these files so that I can move them to my hard drive.

Related

Java NullPointerException only on Linux

I am working on a Java project, which runs fine on Windows 10, but when I tested it in Ubuntu, it shows
"AWT-EventQueue-0" java.lang.NullPointerException: Cannot read the array length because "allFiles" is null.
I read this answer, but could not find a fix.
What I am doing in the project is load an array of images from a certain path. Here is the faulty part of my code:
BufferedImage[] allImages;
public ImageArray(String set, int n) {
File path = new File("res/mnist_png/" + set + "/" + n);
File[] allFiles = path.listFiles();
allImages = new BufferedImage[allFiles.length];
JLabel label[] = new JLabel[allFiles.length];
for (int i = 0; i < allFiles.length; i++) {
try {
allImages[i] = ImageIO.read(allFiles[i]);
label[i] = new JLabel();
ImageIcon icon = new ImageIcon(allImages[i]);
I tried removing the variable allFiles and replacing its use with the actual code it holds but with no success. I saw in the previously answered that the use of the new / this keywords could fix the issue, but I don't seem to be able to find if and where to use them.
I printed the value of the allFiles and path.listFiles() and it is indeed null. Is there a way for the program to work if they remain null? Would changing the null somehow break their intended work?
As I mentioned, the problem occurs only on Linux, but works fine on Windows. Some help would be much appreciated.
First problem: You are using a relative file name. Relative file names have a different meaning depending on the current working directory of the Java process. This is not a Java concept; each process in a system has had its own current directory since long before Java existed.
Second problem: You are trying to list application resources. If you ever choose to package your application as a .jar file, this will not work, because a .jar is a single archive file; the data inside it is all part of one file and they do not constitute actual files.
Relative file names
Any file that does not start with a directory separator (/ on most systems, or optionally \ in Windows) is a relative file name. The actual file location that relative file name refers to depends on the current directory of the Java process. All programs, not just Java programs, work this way.
Some examples:
File name Current directory Actual file location
--------- ----------------- --------------------
res/mnist_png/A/1/image01.png /home/gosho09/project /home/gosho09/project/res/mnist_png/A/1/image01.png
mnist_png /home/gosho09/project /home/gosho09/project/mnist_png
mnist_png / /mnist_png
/home/gosho09/project/res /tmp /home/gosho09/project/res
/home/gosho09/project/res /home/gosho09 /home/gosho09/project/res
/home/gosho09/project/res /usr/local/bin /home/gosho09/project/res
/var/log /tmp /var/log
/var/log /home/gosho09 /var/log
/var/log /usr/local/bin /var/log
As you can see, if the file name does not start with a /, it is relative, and the current directory determines the actual location.
If the file name starts with /, it is considered an absolute file name. Absolute file names are not affected by the current directory.
However… you should not use file names at all.
If you ever want to distribute your application, you will most likely want it to be packaged as a .jar file. A .jar file is a single archive file which contains compiled classes, and application resource files, like your image sets.
Because a .jar file is an archive (it’s actually a specialized zip file), the entries inside it are just parts of the archive, in compressed form. They are not individual files, just sequences of bytes. You cannot read them with the File class.
Fortunately, there is a way to read application resources, which will work both when your application is packaged as a .jar file, and when it exists as regular .class files and data files: the Class.getResource method.
A typical usage might look like this:
String path = "/mnist_png/" + set + "/" + n + "/image" + i + ".png");
URL imageLocation = ImageArray.class.getResource(path);
if (imageLocation == null) {
throw new RuntimeException("Missing resource \"" + path + "\"");
}
allImages[i] = ImageIO.read(imageLocation);
You may be wondering how one is supposed to list files without the File class. The answer is: You can’t and you shouldn’t.
By design, application resources cannot be listed. This is because they are not guaranteed to be listable. Resources are loaded by ClassLoaders, and ClassLoaders may or may not read from directories or from .jar files.
(In fact, the Java SE runtime no longer includes its core classes as a .jar file; as a result, third party tools which used to assume those classes would be available as a .jar file had to be rewritten. Java did not pull the rug out from under those tools’ developers; it was never considered safe to assume classes would come from .jar files, and those developers chose not to heed that warning.)
The alternative to listing the resources is to include a resource which contains a list of the known resource paths. It’s your application; you know what’s in it. So just write a simple plain text listing, include it in your application, and read from that:
String root = "/mnist_png/" + set + "/" + n + "/";
String listingPath = root + "image-list.txt";
try (BufferedReader listing = new BufferedReader(
new InputStreamReader(
Objects.requireNonNull(
ImageArray.class.getResourceAsStream(listingPath),
"Missing resource \"" + listingPath + \""),
StandardCharsets.UTF_8))) {
List<JLabel> labelList = new ArrayList<>();
String path;
while ((path = listing.readLine()) != null) {
URL imageLocation = ImageArray.class.getResource(root + path);
if (imageLocation == null) {
throw new RuntimeException(
"Missing resource \"" + root + path + "\"");
}
labelList.add(new JLabel(new ImageIcon(imageLocation)));
}
labels = labelList.toArray(new JLabel[0]);
}

Internal Storage: Why is getFilesDir() giving me the wrong folder?

I am developing an android app. I want to download files from Firebase Storage to the internal storage and be able to play them afterwards (audio files). I use getFilesDir() to achieve that.
Everything works fine on the emulator. My audio directory is located at
/data/user/0/com.package.name/files/audio/
The problem occurs on some Huawei devices (phone and tablet) with Android API 28.
I get the error, that my audio folder can't be found at the location mentioned above and with the device file explorer I can clearly see that there is no data/user/ folder but instead the system still uses the old /data/data/com.package.name/ directories.
So my question is:
does someone have an idea why getFilesDir() is not giving me the right path and how I could fix this without hardcoding the path.
Here is some code, I have also tried to call exists() on the root folder, with no success.
String filename = document.getId() + ".m4a";
String rootPath = getFilesDir().getAbsolutePath();
File root = new File(rootPath);
//not working
if(!root.exists()){
rootPath = "/data/data/" + getPackageName() + File.separator + "files"
+ File.separator + "voice" + File.separator;
}
//
String folderPath = rootPath + File.separator + "voice" + File.separator;
File subFolder = new File(folderPath);
if(!subFolder.exists()){
subFolder.mkdir();
}
final File localFile = new File(subFolder, filename);
final StorageReference voiceRef = uploadsRef.child("voice").child(filename);
voiceRef.getFile(localFile);
getFilesDir() can and does return different absolute paths based on what device you're running on or even what user (for devices that support multiple users) is running your app (that's the user/0 you're seeing).
As long as you're operating on the directory returned by getFilesDir() or subdirectories of it (such as your new File(getFilesDir(), "voice") directory), everything will work on every device.
I was confused why getFilesDir() creates file in correct directory but not found them when need to delete, getFilesDir().getPath() worked for me.
The getFilesDir() method returns an abstract file path that will change based on the storage system.
You can get the /data/data/com.package.name/files pathway by using getCanonicalFile(). In Kotlin it would look something like this:
val filePath = context.filesDir.canonicalFile
This gives you the path name specific to the device.

how to read and edit existing pptx using Docx4j?

I am using the following code to iterate over existing pptx, but how can I edit (replace text or image) in specific slide.
Example in documentation
String inputfilepath = "C:/tmp/template.pptx";
PresentationMLPackage presentationMLPackage =
(PresentationMLPackage)OpcPackage.load(new java.io.File(inputfilepath));
for (int i=0 ; i<presentationMLPackage.getMainPresentationPart().getSlideCount(); i++) {
SlidePart slidePart = presentationMLPackage.getMainPresentationPart().getSlide(i);
SlideLayoutPart slideLayoutPart = slidePart.getSlideLayoutPart();
//System.out.println(slp.getSourceRelationships().get(0).getTarget());
System.out.println(slidePart.getPartName().getName());
String layoutName = slideLayoutPart.getJaxbElement().getCSld().getName();
System.out.println("layout: " + slideLayoutPart.getPartName().getName() + " with cSld/#name='" + layoutName + "'");
System.out.println("Master: " + slideLayoutPart.getSlideMasterPart().getPartName().getName());
}
I have done many researches on office files like docx,xlsx,ppt
I would like to suggest you one thing
Once you open your file with zip/rar you will find its internal file structure
Files
_rels
docProps
ppt
[Content_types].xml
these folders contain files are usually xml
PPt and move to slides inside slide
there will be xml files names slide1..2..3.etc
these files have every text you type in your ppt.
Replace Xml file with your content
using the java coding and place it back into zip file.
Thats it.
Its working 100% i have implemented it many times.
**summary:**
In java code just try this
1.Rename your file extension from pptx to zip
2.extract path ppt\slides\[yourslide].xml
3.do your content replacement for the extracted xml file.
4.Place it back into zip
5.rename the file extension to pptx
That is it enjoy!!!
regards,
Kishan.c.s

Using environment variables in a Java File Path

I am writing a Java program to convert an XLS file to a CSV file for some Python parsers to act on them.
Everyday on my desktop (I'm using Ubuntu btw) I have a folder called "DFiles" inside which there is another folder called "20140705" (this folder is dynamicalle generated, tomorrow some other program deletes this folder and makes a new folder called 20140706 in its place). Inside this folder there is an xls file whose name is always "data.xls". I already have the code to convert it to CSV.
So here's my problem. Tomorrow my code my run on someone else's desktop(which is also Ubuntu). So when giving the path
input_document = new FileInputStream(new File("/home/local/TNA/srini/Desktop/DFiles/20140705/data.xls"+));
This unfortunately will work only today and only on my computer.
Ideally, I would like to do some thing like set the path to "$HOME/Desktop/Dfiles/2*/data.xls" as the file path. So how can I use bash env variables and wild cards in a file path in java?
You can get the value of an environment variable using System.getenv(...):
String homeDir = System.getenv("HOME");
String directory = homeDir + "/Desktop/DFiles/...";
Wildcards: That will not work. You can use listFiles() to list the files and directories inside a certain directory.
File dir = new File(homeDir + "/Desktop/DFiles";
for (File f : dir.listFiles()) {
if (f.isDirectory()) {
System.out.println("Found subdirectory: " + f.getName());
} else {
System.out.println("Found file: " + f.getName());
}
}
You can write some code that recursively goes into the subdirectories and picks up any file of which the name ends with '.xls'.

Java Directory problems Windows vs. Mac

I'm working on a java application which is supposed to load in images from the same directory that the .jar file will be in. The code below is what I currently have, and it works fine in Windows (in the workspace I'm using and in the .jar file's directory, wherever I put it). However, when I try to run the .jar file in OS X, it doesn't work. I get a null pointer exception. Is there something that I'm missing? or some formatting thing I'm not aware of?
String dir = System.getProperty("user.dir");
File folder = new File(dir+"/");
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
if (listOfFiles[i].isFile()) {
String name = listOfFiles[i].getName();
String fileType = name.substring(name.length()-3, name.length());
if (fileType.equals("jpg")){
File file = new File(dir+"/"+name);
listMPs.add(new MusicPanel(file));
base.add(listMPs.get(count));
base.add(listMPs.get(count).switchLabel);
if(count==0){
base.add(listMPs.get(0).firstSwitchLabel);
}
assignIndexes();
assignMLs();
count++;
}
}
}
Is there something that I'm missing?
Perhaps you missed that applications should not be storing loose files in the program installation directory. In fact, Sun/Oracle has gone to extreme lengths with applets and JWS launched apps. to ensure that even trusted ones cannot discover that location. Put the files in a more accessible place. A common place is a sub-directory of user.home.
You should be using File.separator instead of manually supplying /s in your paths. Java will format the paths according to the current OS implementation.

Categories