Android and LibGDX : create XML file in local storage - android

I want to check if in my /assets/game/ directory there is a file level.xml and if it does not exist I want to create it. I use this code:
private static void LoadXML() {
ProgressFileHandle = Gdx.files.local("game/level.xml");
if (!ProgressFileHandle.exists()) {
try {
ProgressFileHandle.file().createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
} else ProgressFileHandle.file().readString();
}
This code does not work, I get the error:
java.io.IOException: No such file or directory
it works if I change
Gdx.files.local("assets/game/level.xml");
to
Gdx.files.local("level.xml"); But I don't understand why. How can I create this file in a subdirectory (assets/game)?

I'm not clear if you're expecting to read from the standard assets folder that is packaged with your game. You should be using Gdx.files.internal() to read from there in that case, though that assets folder is always going to be read-only on Android.
If you want to create another directory called assets/ in the Libgdx "local storage" (which is equivalent to the Android internal storage) you will need to create the directories before you can create a file in the new directory. Just invoke .mkdirs() on the file handle to make sure all the required parent directories are created.
ProgressFileHandle.file().mkdirs();
ProgressFileHandle.file().createNewFile();

Related

Scoped Storage Enforcement for reading and writing raw sensor data

Currently, we have an app that we are targeting Android 10 and right now are using the legacy storage API. Our app communicates via Bluetooth sensors and reads and writes raw data in CSV files in a subfolder in the main directory, with that subfolder having subfolders for each user.
I know Android 11 will enforce Scoped Storage. I would like to know, is our use case outside of the Scoped Storage requirement? It appears our use case isn't supported by MediaStore. If not, how would we go about this?
MediaStore APIs are just for media files - images, videos, and audio.
You can store all files in the app's private folder and add an export option to your app (maybe compress the whole structure to an archive). So a user will be able to store or send it wherever they want.
In this case, you need to use FileProvider to expose the file from the private directory.
reads and writes raw data in CSV files in a subfolder in the main directory,
For an Android 11 device you can create your own folders an subfolders in the Documents directory of what you call the 'main folder'.
And for using the MediaStore: you can also write any file to that Documents directory. Well in a subfolder if not directly.
I'm in a similar boat. This may help you get started.
public class FirstFragment extends Fragment {
...
public void fauxMakeCsvSurveyFile() {
File appDir = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "Field_data");
appDir.mkdirs();
try {
String storageState = Environment.getExternalStorageState();
if (storageState.equals(Environment.MEDIA_MOUNTED)) {
File file = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/Field_data/" + "OutputFile.csv");
FileOutputStream fos = new FileOutputStream(file);
String text = "Hello, world!";
fos.write(text.getBytes());
fos.close();
}
} catch (IOException e) {
Log.e("IOException", "exception in createNewFile() method");
}
}
...
}

How could I create a file in the "Internal Storage" Directory?

I have a Samsung Galaxy S6. I'm currently working on a test application where I would like quick access to a folder with my files.
Using the provided "My Files" Application, it specifies that all those folders are in the "Internal Storage" folder.
I know that internal storage is private, but I want to create a folder in the default folder that windows accesses when the phone is plugged in.
For example, the following code does not create the directory in the correct location.
File storage = new File("/testappplication");
if(!storage.exists()) {
storage.mkdir();
System.out.println("Folder Created");
}
I just want to know the path where to create the folder. Many other applications have storage here, so I know its possible.
You can't create a directory inside the internal storage of the device. Except you've a root access for the app.
So, the following code won't work:
File storage = new File("/testappplication");
Because it tell the app to create a testappplication in the root folder.
You can only create the directory inside your app private folder within the following path:
String path = getFilesDir().getAbsolutePath();
And make the folder using the path.
Or you can use something like this:
File folder = new File(context.getFilesDir(), "testappplication");
if (!folder.exists()) {
folder.mkdirs();
} else {
// folder is exist.
}
Read more at Saving Files
First just for trial make runtime permmision and then try the following code
private void createInternalFile() {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory()+"/"+getApplicationContext()
.getPackageName()+"/File/profile");
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
} }
then check your internal storage in which you will find a folder whose name is your package name
After a while later I found the answer to this question.
public void createDirectory() {
File file = new File(Environment.getExternalStorageDirectory(), "/test");
if (!file.exists()) {
file.mkdirs();
Log.w("DEBUG", "Created default directory.");
}
}
This is how you create it code wise. The reason it wasn't creating was due to Samsungs weird permissions.
Make sure you have the storage permission enabled in Settings -> Apps -> App Name -> Permissions. I needed to turn it on so it would create the folder.

Something is deleting image files from getExternalFilesDir()?

I'm having a hard time figuring out what is going on with my app. Various users have reported that the app generated image files are gone. However, the database data isn't gone and it is stored at the common location Context.getDatabasePath(). Also, all folders are kept intact just images missing.
So I'm thinking there is some routine in Android causing this? Or some other app cleaning up *.png files? I know my app isn't removing them since I don't have any routine to recursively remove all image files.
Also, the parent folder has the .nomedia file so all child folders shouldn't be touched by the gallery right?
I'm storing these files inside the following path structure where %d is a unique number:
getExternalFilesDir()/projects/p_%d/l_%d/%d.png
This is how I get the projects path creates:
public static File getProjectsDir(Context context)
{
// External app directory handled by the OS. Meaning that when the app is uninstalled all
// the data inside this folder will be also removed.
File appRoot = context.getExternalFilesDir(null);
if (null == appRoot) {
Log.e(TAG,"getProjectsDir() -> External storage not accessible!");
return null;
}
File projectsDir = new File(appRoot, "projects");
// create projects directory
if (!projectsDir.exists()) {
if (!projectsDir.mkdir()) {
Log.e(TAG,"getProjectsDir() -> Unable to create projects folder!");
return null;
} else {
File noMediaFile = new File(projectsDir, ".nomedia");
if (!noMediaFile.exists()) {
try {
if (!noMediaFile.createNewFile()) {
Log.e(TAG,"getProjectsDir() -> no media file failed to be created!");
}
} catch (IOException e) {
Log.e(TAG,"getProjectsDir() -> no media file failed to be created!",e);
}
}
}
}
return projectsDir;
}
According to this, it appears that the DownloadManager deletes any files from third-party apps that haven't been accessed (i.e. "UI-Visible") in over 7 days.
The workaround would be to rename the file after it's downloaded so the DownloadManager can no longer track it.

Android 6.0 Permissions

I am working on a big project with a reasonably big code base. What I want to ask you is hints on how to reliably check where I have to provide a solution to adapt for android 6.0 . What i have used is Analyze > Inspect Code , it does a static analysis of the code and than shows missing checks in the section :
Android > Constant and Resource Type Mismatches. It looks somewhat not the right place to find those problems and that is why I am asking to make sure I am using the right thing and am looking at the right thing, plus I am a bit confused because I have parts of code which write files and i am not getting notified about permissions checks there(is it a normal behaviour?!)
public static boolean write(String folderName, String filename, Object objToWrite) {
// serialize cardModel
FileOutputStream file = null;
ObjectOutputStream o = null;
File dirFile = AppController.getInstance().getApplicationContext().getDir(folderName, Context.MODE_PRIVATE);
try {
// Create archiveDir
File mypath = new File(dirFile, filename);
file = new FileOutputStream(mypath, false);
o = new ObjectOutputStream(file);
o.writeObject(objToWrite);
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
try {
o.close();
file.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
return true;
}
Should I get a warning for Write permission here ?
Another thing that makes me ask is this issue that i have posted on google regarding an Android Studio bug:
Android Studio Bug
Not every write to a file needs a permission - only the one to external storage - this function might also write to the app file space - this needs no permission. Depends on the parameters
Interestingly enough, the definition of what "external storage" vs "internal storage" has changed quite a bit since Android Lollipop. What does this mean?
This call will require you to have storage permissions in the external public directory:
public File getAlbumStorageDir(String albumName) {
// Get the directory for the user's public pictures directory.
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
However, if you do the following, you won't need STORAGE Permissions.
public File getAlbumStorageDir(Context context, String albumName) {
// Get the directory for the app's private pictures directory.
File file = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created");
}
return file;
}
According to Google:
`If none of the pre-defined sub-directory names suit your files, you can instead call getExternalFilesDir() and pass null. This returns the root directory for your app's private directory on the external storage.
Remember that getExternalFilesDir() creates a directory inside a directory that is deleted when the user uninstalls your app. If the files you're saving should remain available after the user uninstalls your app—such as when your app is a camera and the user will want to keep the photos—you should instead use getExternalStoragePublicDirectory().
Regardless of whether you use getExternalStoragePublicDirectory() for files that are shared or getExternalFilesDir() for files that are private to your app, it's important that you use directory names provided by API constants like DIRECTORY_PICTURES. These directory names ensure that the files are treated properly by the system. For instance, files saved in DIRECTORY_RINGTONES are categorized by the system media scanner as ringtones instead of music.
`

How to save folder in specific folder in Google Drive

I can save/copy a file in any folder of Google Drive using the below code
.But when i apply this method to save the folder in any other folder, then it can't save folder, and nothing happens. I want to copy a folder and save it at another place
String LocationID="0B-WFTScd2afSFS34TC-223";//getting the id of the parent folder where we have to make the new file as its child
File orgnlFile =global_file;
File copiedFile = new File();
copiedFile.setTitle(orgnlFile.getTitle());
copiedFile.setMimeType(orgnlFile.getMimeType());
copiedFile.setParents(Arrays.asList(new ParentReference().setId(LocationID)));
try
{
mService.files().copy(orgnlFile.getId(), copiedFile).execute();
} catch (IOException e)
{
System.out.println("An error occurred: " + e);
}
But unfortunately it doesn't work for copy-paste folder in some other directory
This is because copy is duplicating the media contents of a file into a new file. Since a folder has no media contents, there is nothing to copy.
When you say "I want to copy a folder", do you mean (1) copy only the folder, or (2) copy the folder and all files within the folder, and do you mean (3) duplicate or simply make a second reference?
Depending on exactly what you want to achieve, the Drive API calls you need to make are different.
Perhaps the best way to explain what you want would be to express it in terms of the *nix commands "cp", "mv" and "ln"
To create a duplicate of a folder-a (which is under folder-b) and its children within folder-c, (in *nix, "cp -R /folder-b/folder-a /folder-c") you will need to :-
Make a new folder-a under the new parent folder (folder-c). NB although folder-a has the same name as the original. It is a different folder.
Make a note of the file-id of the new folder-a
Get a list of the children of the original folder-a (children feed)
For each child, copy it
Update the parents property of each new file to be the new folder-a
If there are folders within folder-a, you will need to do the above recursively

Categories

Resources