Android File.listFiles() returns null - java

I am trying to access my android files through my apk and (initially) list them on my terminal. This is the code I use:
File basePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)getAbsolutePath();
File directory = new File(basePath);
System.out.println("" + directory.toString());
File[] directoryContents = directory.listFiles();
I do succeed printing this path: /storage/emulated/0/Download which actually exists in my android and has some files in it.
When listing files inside that directory using:
for (File file : directoryContents)
{
if (file.isFile())
System.out.println("" + file.getName());
else
continue;
}
I get java.lang.NullPointerException: Attempt to get length of null array
I also included <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> in android's manifest.
My smartphone runs on Android 7.0 if that's of any help.

listFiles returns an array if the File instance from which this method is called from is a directory. Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) always(i guess) returns a directory( unless you altered the os defaults). so the only thing going wrong is probably lack of permissions;
here is how to ask permissions properly

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS replace this line instance of Environment.getExternalStorageDirectory()getAbsolutePath() issue will resolved.

Related

How to move files from internal storage to app directory?

I am making a app that store files get files from Internal Storage and lock those files in app directory /data/data/[package_name]/videos/.
I try to move files files through this method but it is not working for me.
source.renameTo(new File("data/data/" + this.getPackageName() + "/files/videos/" + video_title));
TRIED BEFORE
I tried this
source.renameTo(new File("/storage/emulated/0/" + this.getPackageName() + video_title));. This worked and move file from soure to /storage/emulated/0/.
I also checked this directory exisits.
PROBLEM
Problem is file is not moving from storage to app directory.
This is the actual function I am using to move file.
private boolean moveFile(File source, File destination) {
boolean isDirectoryMade = false;
// creates directory if not exists
if (!destination.getParentFile().isDirectory()){
File parent = destination.getParentFile();
isDirectoryMade = parent.mkdirs();
}
// rename or move file.
boolean isFileRenamed = source.renameTo(destination);
return isDirectoryMade && isFileRenamed;
}
First, you'll have to copy that file to the app directory, reading the file using Storage Access Framework.
Then, still using SAF, you'll have to ask the user for delete the original one.
For both steps, Android now needs you to ask the user for accessing public directories, specifying if you read the file (the user will have to select the file manually) and delete it.
To ask the user for Document read, you'll have to use the following :
val selectFileRequest = registerForActivityResult(OpenDocument()) {
result: Uri? ->
//Your code to copy the file here, the provided Uri is the selected file's
//Then you can delete the file with the following:
if(result != null)
{
//DocumentFile.fromSingleUri(this, result)?.delete()
//or
//DocumentsContract.deleteDocument(getContentResolver(), result);
}
}
Don't forget to add the needed permissions in your Manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28"/>
In the end, just call the following in your code:
selectFileRequest.launch(
arrayOf(
//Any Mime type you want to target, like the followings :
"application/pdf",
"image/*",
"text/*"
)
)

Internal files not 'available' on Android - File.exists() returns false for any file

I am trying to access a 2.45GB Geopackage file that is stored in internal storage but whenever I try and access it I get a "File does not exist" error.
The gpkg file is being downloaded via DownloadManager into external storage before being copied into internal storage, but when I call new File(getContext().getFilesDir(), "roads.gpkg").exists();, I get 'false' returned. As well as this, when I run
File[] files = getContext().getFilesDir().listFiles();
for(File file : files){
Log.i("FILE", file.getAbsolutePath());
}
the file doesnt show.
To make sure it wasn't unexpected behaviour from the DownloadManager or my copy method, I manually copied the file into "Android/data/uk.co.alexks.greenroutes/files", as well as an 11 byte txt file, 'test.txt', using my Windows laptop. Again, none of these files return true for File.exists() or show in the above listFiles() code output (see below).
Here is the full code of when I try to access the file:
File geopackage = new File(getContext().getFilesDir(), "roads.gpkg");
Log.i("GEOPACKAGE", String.format("GPKG File: %s", geopackage.getPath()));
Log.i("GEOPACKAGE", String.format("Exists? %s", geopackage.exists()?"T":"F"));
Log.i("FILE", getContext().getFilesDir().getPath());
File[] files = getContext().getFilesDir().listFiles();
for(File file : files){
Log.i("FILE", file.getAbsolutePath());
}
//Pass geopackage to a new object that uses the Geopackage-Android library to handle it.
Here is the Logcat output:
I/GEOPACKAGE: GPKG File: /data/user/0/uk.co.alexks.greenroutes/files/roads.gpkg
I/GEOPACKAGE: Exists? F
I/FILE: /data/user/0/uk.co.alexks.greenroutes/files
/data/user/0/uk.co.alexks.greenroutes/files/DATA_disk_creation_time_its
/data/user/0/uk.co.alexks.greenroutes/files/DATA_disk_creation_time_vts_labl_uk.co.alexks.greenroutes_default
/data/user/0/uk.co.alexks.greenroutes/files/DATA_disk_creation_time_vts_no_pois_uk.co.alexks.greenroutes_default
/data/user/0/uk.co.alexks.greenroutes/files/DATA_disk_creation_time_vts_uk.co.alexks.greenroutes_default
/data/user/0/uk.co.alexks.greenroutes/files/DATA_disk_creation_time_vts_inaka_uk.co.alexks.greenroutes_default
/data/user/0/uk.co.alexks.greenroutes/files/DATA_disk_creation_time_its_ter
/data/user/0/uk.co.alexks.greenroutes/files/com.google.android.gms.maps._m_u
/data/user/0/uk.co.alexks.greenroutes/files/_m_t
I/FILE: /data/user/0/uk.co.alexks.greenroutes/files/DATA_ServerControlledParametersManager.data.uk.co.alexks.greenroutes
/data/user/0/uk.co.alexks.greenroutes/files/ZoomTables.data
And the expected output:
I/GEOPACKAGE: GPKG File: /data/user/0/uk.co.alexks.greenroutes/files/roads.gpkg
I/GEOPACKAGE: Exists? T
I/FILE: /data/user/0/uk.co.alexks.greenroutes/files
/data/user/0/uk.co.alexks.greenroutes/files/roads.gpkg
/data/user/0/uk.co.alexks.greenroutes/files/test.txt
And my Android manifest with the permissions:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
For what its worth, I know I should be using File.isFile() to check if a file is valid but that wouldnt help here.
Any help would be greatly appreciated! :)
Ok, it turns out the file really didn't exist in internal storage (I think I uninstalled the app to test permission requests, but I saw a copy of the dataset in "Android/data/package/files/" (external storage) so thought it did exist), and as #CommonWares pointed out in the comments, the Android/data/package/files folder visable from Windows is not internal storage, it is external so copying the files to there did nothing.

Cannot reach files inside the root directory of my Android app

I have the code bellow:
String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/data/data/com.example.stavr.mydiary";
File file=new File(path);
File[] files = file.listFiles();
String arr[]=file.list();
List l=new ArrayList<>();
for(String i:arr){
if(i.endsWith(". txt")){
l.add(i);
}
}
which returns 0 files on my array (NullPointerException to be exact), Iknow that there are files in that directory. If i change the directory to just
Environment.getExternalStorageDirectory().getAbsolutePath()
the code work and it returns all the files. I thing that i have done something wrong with the permissions. Could you please help me,
Thank you very much in advance..!!!
It seems you're trying to access your internal app data folder, you can do that by using a context object:
String dir = context.getFilesDir().getAbsolutePath();
If you still want to access external storage then you should make sureyou have WRITE_EXTERNAL_STORAGE permission in your AndroidManifest.xml

File.list() returns null for directory

When executing the code
File path = new File("/data");
boolean isDir = path.isDirectory();
//isDir is true
String[] fList = path.list();
//fList == null!
on an Android 2.3 emulator, the file list is null. This seems to contradict the statement from the documentation http://developer.android.com/reference/java/io/File.html#list():
Returns null if this file is not a directory.
What's wrong here?
You can't access /data dir since you don't have root access. Without root privileges you can access just an external storage and your app's dir at internal storage.
Look at this answer: https://stackoverflow.com/a/1043722/1037294

isDirectory() returns true for a file

In my java program I copy a file and delete the new file.
In my method removeFile() I check if it is a directory:
String fileName = "G:/1310628353186Examples.csv";
File f = new File(fileName);
if (f.isDirectory()) {
System.out.println( "'" + fileName + "' is a directory" );
String[] files = f.list();
if (files != null && files.length > 0)
throw new IllegalArgumentException("Delete: directory not empty: " + fileName);
}
Sometimes I get "'G:/1310628353186Examples.csv' is a directory", sometimes I don't.
When I debug the code and f.isDirectory() is true and I check what is in f.isDirectory, the debugger says that it's false.
I'm running Eclipse SDK 3.4.0 and JDK 1.6 on Windows 7 Professional.
You check if f is a directory but you print fileName. So maybe you just check/print the wrong variable? Unless it's only a typo in your question.
Try adding a check to see if the file exists, isDirectory() will also return false in case the file doesn't exist:
if (f.exists() && f.isDirectory()) {
If the file is hidden, like the My Music link in Documents (a windows-generated shortcut file, it's not a real shortcut), then it will test as isdirectory but it won't function like a directory; you can't get a listing of the directory. A user generated shortcut will act like a file.
5/31/13:
In a recent update the 'My Music' link in 'Documents' no longer tests as is_hidden. However, a dirlist taken of the file object for 'My Music' does return a NULL, which can be tested for.
I get this same issue on OSX. I create a regular file, and the isDirectory() function returns true and isFile() returns false. (Can't find any evidence anywhere to suggest that this behaviour is expected from the API).
The way I solved it on OSX is to manually read the attributes from the file, but you can't use BasicFileAttributes either - it also for some reason returns true for isDirectory() and false for isRegularFile().
Works for OSX:
PosixFileAttributes attr = Files.readAttributes(f.toPath(), PosixFileAttributes.class);
System.out.println("File "+f.getName()+
": isDirectory="+(attr.isDirectory() ? "true" : "false")+
", isRegularFile="+(attr.isRegularFile() ? "true" : "false"));
You have to sorround with try/catch block and then try it.
It seemed to be a problem caused by Windows. Linux does not have this problem.

Categories

Resources