mkdirs() on application internal memory fails on Android - android

in my app I am seeing few crashes when I try to create a directory structure under the application internal storage, such as /data/data/[pkgname]/x/y/z....
Here is the failing code:
File clusterDirectory = new File(MyApplication.getContext().getFilesDir(), "store");
File baseDirectory = new File(clusterDirectory, "data");
if (!baseDirectory.exists()) {
if (!baseDirectory.mkdirs()) {
throw new RuntimeException("Can't create the directory: " + baseDirectory);
}
}
My code is throwing the exception when trying to create the following path:
java.lang.RuntimeException: Can't create the directory: /data/data/my.app.pkgname/files/store/data
My manifest specifies the permission <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />, even if it should not be necessary for this purpose (it is actually necessary for my apps due to Google Maps Android API v2).
It doesn't seem to be related to the phone, since I get this exception on old phones as well as on new ones (last crash report is Nexus 4 with Android 4.3).
My guess is that the directory /data/data/my.app.pkgname doesn't exist in the first place but mkdirs() can't create it because of permissions issues, could that be possible?
Any hints?
Thanks

Use getDir(String name, int mode) to create directory into internal memory. The method Retrieve, creating if needed, a new directory in which the application can place its own custom data files. You can use the returned File object to create and access files in this directory.
So example is
// Create directory into internal memory;
File mydir = context.getDir("mydir", Context.MODE_PRIVATE);
// Get a file myfile within the dir mydir.
File fileWithinMyDir = new File(mydir, "myfile");
// Use the stream as usual to write into the file.
FileOutputStream out = new FileOutputStream(fileWithinMyDir);
For nested directories, you should use normal java method. Like
new File(parentDir, "childDir").mkdir();
So updated example should be
// Create directory into internal memory;
File mydir = getDir("mydir", Context.MODE_PRIVATE);
// Create sub-directory mysubdir
File mySubDir = new File(mydir, "mysubdir");
mySubDir.mkdir();
// Get a file myfile within the dir mySubDir.
File fileWithinMyDir = new File(mySubDir, "myfile");
// Use the stream as usual to write into the file.
FileOutputStream out = new FileOutputStream(fileWithinMyDir);

Related

I can't write to the external SD card(extSdCard) in Android Studio

I have created an android app that needs to create a folder and write text files on my external SD card(extSdCard). I am using the Galaxy S4 device and have written the following codes for that. I already know the path of /mnt/.. file and have created a string for it. The android manifest.xml file uses the permission.i have checked the codes in "adb logcat" in Cmd prompt and it does not give any error but doesn't create any folder. The device has also been checked unconnected with the PC. Would appreciate if you help me. Here is the code.
String externalFilePath="/mnt/extSdCard/tmp";
Log.d(TAG, "externalFilePath is: "+externalFilePath);
File myfile = new File(externalFilePath, "Hello");
First of all make sure that you have this line inside your manifest,xml, somewhere outside application tag.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Then you can write a File doing this :
File sdcard = Environment.getExternalStorageDirectory();
File dir = new File(sdcard.getAbsolutePath() + "/tmp/");
// creates if doesn't exists
dir.mkdir();
// create a File
File file = new File(dir, "Example.txt");
FileOutputStream os = outStream = new FileOutputStream(file);
//this is the text that will be inside of the Example.txt
String data = "Hello world";
os.write(data.getBytes());
os.close();
Hope it helps :)
try this code to generate files under your application package
File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
// Replace DIRECTORY_PICTURES with your needs
File file = new File(path, "Hello");
Also make sure you have added the permissions

Removing "app_" prefix when creating subdirectories in application's internal storage

Android provides many options for storing data persistently on the device. I have opted for internal storage, so please don't make suggestions for storing on an SD card. (I've seen too many questions about internal storage have answers for SD cards!!)
I would like to create subdirectories in my application's internal storage directory. I followed this SO answer, reproduced below.
File mydir = context.getDir("mydir", Context.MODE_PRIVATE); //Creating an internal dir;
File fileWithinMyDir = new File(mydir, "myfile"); //Getting a file within the dir.
FileOutputStream out = new FileOutputStream(fileWithinMyDir); //Use the stream as usual to write into the file.
Unfortunately, that's creating subdirectories with "app_" prefixes. So, from the example, the subdirectory looks like "app_mydir" (not ideal).
The answer to this SO question suggests that you can get rid of the "app_" prefix this way:
m_applicationDir = new File(this.getFilesDir() + "");
m_picturesDir = new File(m_applicationDir + "/mydir");
But I want to write a zip to something like /data/data/com.mypackages/files/mydir/the.zip.
So, in the end, my code looks like this:
File appDir = new File(getApplicationContext().getFilesDir() + "");
File subDir = new File(appDir + "/subDir");
File outFile = new File(subDir, "/creative.zip");
But, this is creating another error: "File does not exist" when I try this:
FileOutputStream fileStream = new FileOutputStream(outFile);
How can I (1) create a subdirectory without the "app_" prefix and (2) write a zip into it?
Also, if my first demand isn't reasonable, tell me why in the comments! I'm sure "app_" prefix has some meaning that escapes me atm.
Did you create the directories?
File appDir = getApplicationContext().getFilesDir();
File subDir = new File(appDir, "subDir");
if( !subDir.exists() )
subDir.mkdir();
File outFile = new File(subDir, "creative.zip");
Note that you shouldn't use / anywhere in your app, just in case it changes. If you do want to create your own paths, use File.separator.

How to include external WAV files in Android

A few WAV files used by my app are currently located in res/raw. These files need to be accessible by the user after the app is installed. So ideally my app should create a folder on the device and put the files in it. Any idea/suggestions on how to do this?
soundIds[0] = soundPool.load(test2Activity, R.raw.snare, 1);
soundIds[1] = soundPool.load(test2Activity, R.raw.snare2, 1);
You can access the sd_card, so you can create a directory and put there your files
// create a File object for the parent directory
File yourDirectory = new File("/sdcard/YourDirectory/");
// have the object build the directory structure, if needed.
yourDirectory.mkdirs();
// create a File object for the output file
File outputFile = new File(yourDirectory, filename);
// now attach the OutputStream to the file object, instead of a String representation
FileOutputStream fos = new FileOutputStream(outputFile);
The output file should be your sound that you have loaded from res/raw.
My advice would be to just copy the sound to the folder, and still use the sound from res/raw from within your app because
1) it is easier since you can access it as a resources
2) you are sure the user didn't deleted the directory.
Remember to put the user permission "android.permission.WRITE_EXTERNAL_STORAGE" in the manifest

Android how to check if file exist and else create one?

I have following question. I'd like to place a file named data.xml into sdcard/appname folder and use it for read and write application data.
So, when my main activity creates I need to check if this file exist:
public class appname extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.no_elements_l);
File file = getBaseContext().getFileStreamPath("/sdcard/appname/data.xml");
if(file.exists()) {
return;
} else {
// create a File object for the parent directory
File MTdirectory = new File("/sdcard/appname/");
// have the object build the directory structure, if needed.
MTdirectory.mkdirs();
// create a File object for the output file
File outputFile = new File(MTdirectory, "data.xml");
// now attach the OutputStream to the file object, instead of a String representation
FileOutputStream DataFile = new FileOutputStream(outputFile);
}
But I have Unhandled exception type FileNotFoundException in last line. What's the problem? Uses permission WRITE_EXTERNAL_STORAGE is added to manifest.
Don't hardcode SDCard file path. It can be different for different devices and APIs.
For example it's /mnt/sdcard/ for Froyo while that of my Galaxy Nexus (JellyBean) is /storage/sdcard0/
Android Developer's Guide recommends using Environment.getExternalStorageDirectory()
Try doing it like this:
// Some Code
String path = Environment.getExternalStorageDirectory().getPath() + "/appname/";
File file = getBaseContext().getFileStreamPath(path);
// More Code
Does the path '/sdcard/appname' exist? You check for the file before you check for the sub-directory 'appname'. You need to check if that exists before you try to access a file inside it.
Also if you simply need the file to read-write application data why not just go with internal storage - one less manifest permission :) -> read here for internal storage

How to create a file on Android Internal Storage?

I want to save a file on internal storage into a specific folder. My code is:
File mediaDir = new File("media");
if (!mediaDir.exists()){
mediaDir.createNewFile();
mediaDir.mkdir();
}
File f = new File(getLocalPath());
f.createNewFile();
FileOutputStream fos = new FileOutputStream(f);
fos.write(data);
fos.close();
getLocalPath returns /data/data/myPackage/files/media/qmhUZU.jpg but when I want to create the media folder I'm getting the exception "java.io.IOException: Read-only file system". Any ideas how to write my files on internal phone storage in in folder media? Thanks.
You should use ContextWrapper like this:
ContextWrapper cw = new ContextWrapper(context);
File directory = cw.getDir("media", Context.MODE_PRIVATE);
As always, refer to documentation, ContextWrapper has a lot to offer.
You should create the media dir appended to what getLocalPath() returns.
I was getting the same exact error as well. Here is the fix. When you are specifying where to write to, Android will automatically resolve your path into either /data/ or /mnt/sdcard/. Let me explain.
If you execute the following statement:
File resolveMe = new File("/data/myPackage/files/media/qmhUZU.jpg");
resolveMe.createNewFile();
It will resolve the path to the root /data/ somewhere higher up in Android.
I figured this out, because after I executed the following code, it was placed automatically in the root /mnt/ without me translating anything on my own.
File resolveMeSDCard = new File("/sdcard/myPackage/files/media/qmhUZU.jpg");
resolveMeSDCard.createNewFile();
A quick fix would be to change your following code:
File f = new File(getLocalPath().replace("/data/data/", "/"));
Hope this helps
Write a file
When saving a file to internal storage, you can acquire the appropriate directory as a File by calling one of two methods:
getFilesDir()
Returns a File representing an internal directory for your app.
getCacheDir()
Returns a File representing an internal directory for your
app's temporary cache files.
Be sure to delete each file once it is no longer needed and implement a reasonable
size limit for the amount of memory you use at any given time, such as 1MB.
Caution: If the system runs low on storage, it may delete your cache files without warning.
Hi try this it will create directory + file inside it
File mediaDir = new File("/sdcard/download/media");
if (!mediaDir.exists()){
mediaDir.mkdir();
}
File resolveMeSDCard = new File("/sdcard/download/media/hello_file.txt");
resolveMeSDCard.createNewFile();
FileOutputStream fos = new FileOutputStream(resolveMeSDCard);
fos.write(string.getBytes());
fos.close();
System.out.println("Your file has been written");

Categories

Resources