This is my directory structure on my Android sdcard
sdcard/alQuranData/Reader1/Surah
Here is my code to make Directories
File SDCardRoot = new File(Environment.getExternalStorageDirectory().toString() + "alQuranData/Reader1/Surah");
Toast.makeText(getApplicationContext(), SDCardRoot.toString(), Toast.LENGTH_LONG).show();
if (!SDCardRoot.exists()) {
Log.d("DIRECTORY CHECK", "Directory doesnt exist creating directory");
SDCardRoot.mkdir();
}
Now alQuranData is already created in my sdcard root. If i only create Reader1 directory than it works fine, but when is add Reader1/Surah than it did not create.
I also tried mkdirs() but it doesn't work.
Are you getting any error or exception. Please try to check the return value of mkdirs() method call. ALso try the following code:
File SDCardRoot = new File(Environment.getExternalStorageDirectory().toString() + "/alQuranData/Reader1/Surah");
Toast.makeText(getApplicationContext(), SDCardRoot.toString(), Toast.LENGTH_LONG).show();
if (!SDCardRoot.exists()) {
Log.d("DIRECTORY CHECK", "Directory doesnt exist creating directory");
SDCardRoot.mkdirs();
}
Please also check that you have added following permission in manifest file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I just tested the following code and it is working on my end:
File SDCardRoot = new File(Environment.getExternalStorageDirectory()
.toString() + "/alQuranData/Reader1/Surah");
Toast.makeText(getApplicationContext(), SDCardRoot.toString(),
Toast.LENGTH_LONG).show();
if (!SDCardRoot.exists()) {
Log.d("DIRECTORY CHECK",
"Directory doesnt exist creating directory "
+ Environment.getExternalStorageDirectory()
.toString());
boolean outcome = SDCardRoot.mkdirs();
Log.d("DIRECTORY CHECK",
"outcome for " + SDCardRoot.getAbsolutePath() + " "
+ outcome);
}
I have added alQaranData folder manually as mentioned in your post and added the permission and it start working at my end. Please check this code.
Using Java you cannot create multiple directories all at once. You will need to declare a folder name one by one and proceed to create a directory. So first create
alQuranData
alQuranData/Reader1/
alQuranData/Reader1/Surah
Using the same piece of code you have provided.
Use this code.....)
private void createSdCatalogs(String str1){
//str1 = "/alQuranData"
File folder = new File(Environment.getExternalStorageDirectory() + str1);
boolean success = false;
if (!folder.exists()) {
success = folder.mkdir();
Log.v("Adding line", "/");
}}
private void createSdCatalogs(String str2) {
//str2 = "/alQuranData/Reader1";
File folder1 = new File(Environment.getExternalStorageDirectory() + str2);
boolean success1 = false;
if (!folder1.exists()) {
success1 = folder1.mkdir();
Log.v("Adding line", "/");
}
}
By default there is no way in android to create multiple directory at once.
you have to create one by one and check is created or not.
But I have created a below code to achieve similar objective. you can use to create multiple directory at once...
public static boolean recursivelyMakeDir(File endDirectory,File baseDir) {
if (!baseDir.exists()){
return false;
}
ArrayList<String> allDirectoryList = parseAndGetListDir(endDirectory.getAbsolutePath().substring(baseDir.getAbsolutePath().length()));
File currentDir = baseDir;
for (int i=0; i< allDirectoryList.size() ; i++){
File dir = new File(currentDir.getAbsolutePath() + "/" + allDirectoryList.get(i) );
if (!dir.exists()){
if (!dir.mkdir()){
return false;
}
}
currentDir = dir;
}
return true;
}
public static ArrayList<String> parseAndGetListDir(String data) {
ArrayList<String> allDirectoryList = new ArrayList<>();
boolean exit = false;
String dir = "";
for (int i=0; i<data.length() ; i++){
if (data.charAt(i) == '/'){
if (!dir.equals("")){
allDirectoryList.add(dir);
dir = "";
}
}else {
dir = dir + data.charAt(i);
}
}
if (!dir.equals("")){
allDirectoryList.add(dir);
}
return allDirectoryList;
}
Usage :
// you 100% sure that this directory is already exist.
File baseDir = Environment.getExternalStorageDirectory();
// desire directory wanted to create.
File endDirectory = new File(Environment.getExternalStorageDirectory() +"kkk/SSS/aaa/ddd/b");
if(recursivelyMakeDir(endDirectory ,baseDir )){
// dir created sucessessfully
}else{
// failed
}
Related
I am building a media player application and I want to make a list from all .mp3 files on the device. To do that I need the EXTERNAL REMOVABLE storage path.
This path could be different in different devices.
Environment.getExternalStorageDirectory().getAbsolutePath()
I've already tried above line of code but it returns the path of internal storage.
This has been discussed here!
It didn't help.
You can achieve it through
public static String getExternalSdCardPath() {
String path = null;
File sdCardFile = null;
List<String> sdCardPossiblePath = Arrays.asList("external_sd", "ext_sd", "external", "extSdCard");
for (String sdPath : sdCardPossiblePath) {
File file = new File("/mnt/", sdPath);
if (file.isDirectory() && file.canWrite()) {
path = file.getAbsolutePath();
String timeStamp = new SimpleDateFormat("ddMMyyyy_HHmmss").format(new Date());
File testWritable = new File(path, "test_" + timeStamp);
if (testWritable.mkdirs()) {
testWritable.delete();
}
else {
path = null;
}
}
}
if (path != null) {
sdCardFile = new File(path);
}
else {
sdCardFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
}
return sdCardFile.getAbsolutePath();
}
I have downloaded the image file and saved in a directory but it returning empty list files . Files are downloaded and stored in directory. I tried many solutions still it not solved. I am working on oreo devices and checked the runtime permission.
The below line is for checking the files inside the directory
try{
File giftFolder = new File(getApplicationContext().getFilesDir() + "/SamplePhoto/");
if (!giftFolder.exists()) {
giftFolder.mkdir();
}
File directory = new File(getApplicationContext().getFilesDir() + "/SamplePhoto/");
if(directory.isDirectory()){
Log.d("Files", "directory: "+ directory.isDirectory());
}
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());
}
}catch (Exception e){
e.printStackTrace();
}
The below code is for downloading file using download manger
public static void downloadFile(Context context, String url, String fileName) {
DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(url));
downloadRequest.setTitle(fileName);
// in order for this if to run, you must use the android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
downloadRequest.allowScanningByMediaScanner();
downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
File giftFolder = new File(context.getFilesDir() + "/SamplePhoto");
if (!giftFolder.exists()) {
giftFolder.mkdir();
}
// downloadRequest.setDestinationInExternalPublicDir(Environment.getExternalStorageState()+"/SamplePhoto/", fileName);
// downloadRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
downloadRequest.setDestinationInExternalPublicDir(context.getFilesDir() + "/SamplePhoto/", fileName);
Log.e("DownloadingPath",""+ context.getFilesDir() + "/SamplePhoto/"+ fileName);
DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(downloadRequest);
}
Try changing:
File giftFolder = new File(getApplicationContext().getFilesDir() + "/SamplePhoto/");
To
File giftFolder = new File(getApplicationContext().getFilesDir() + "/SamplePhoto");
And anywhere else you use "/SamplePhoto/" too. You dont need the tailing slash when accessing a directory.
I have this code here that saves bitmaps of images as a GIF file called test, but everytime the user saves it as test.gif so its constantly overwriting.
What are some ways to avoid overweriting and generate a new filename everytime programmatically?
if(imagesPathList !=null){
if(imagesPathList.size()>1) {
Toast.makeText(MainActivity.this, imagesPathList.size() + " no of images are selected", Toast.LENGTH_SHORT).show();
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/dir1/dir2");
dir.mkdirs();
File file = new File(dir, "test.gif");
try{
FileOutputStream f = new FileOutputStream(file);
f.write(generateGIF(list));
} catch(Exception e) {
e.printStackTrace();
}
A quick and dirty solution is to put the system time in the filename:
File file = new File(dir, "test_" + System.currentTimeMillis() +".gif");
As long as that method isn't executed at the exact same millisecond, you won't have duplicates.
You can use java.io.File.createTempFile("test", ".gif", dir)
This creates unique filename but they might get significantly long after some time.
Alternatively you can create a method that creates unique filesnames yourself:
private File createNewDestFile(File path, String prefix, String suffix) {
File ret = new File(path, prefix + suffix);
int counter = 0;
while (ret.exists()) {
counter++;
ret = new File(path, prefix + "_" + counter + suffix);
}
return ret;
}
Instead of
File file = new File(dir, "test.gif");
you call
File file = createNewDestFile(dir, "test", ".gif");
This is not thread safe. For that you need a more sophisticated method (e.g. synchronize it and create a FileOutputStream instead of a File which is creating the file already before another call checks of the method checks its existence).
I wrote a small Android App to record audio and save this on the disk of the smartphone. Now I've got the problem that it's saved on the wrong location with the wrong name and I can't see why. (I'm relative new to Android programming)
public void startRecording(View view) {
File folder = new File(Environment.getExternalStorageDirectory() + "/" + R.string.app_name);
file_name = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + R.string.app_name;
if(!folder.exists()) {
boolean created = folder.mkdirs();
if(!created) { Log.i(LOG_TAG, "Could not create folder/s."); return; }
}
if(editText.getText() != null)
file_name += editText.getText() + ".3gp";
else
file_name += Calendar.getInstance().getTime() + ".3gp";
outputFile = new File(file_name);
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile(file_name);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
Toast.makeText(CaptureActivity.this, R.string.toast_recording_start, Toast.LENGTH_SHORT).show();
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
Toast.makeText(CaptureActivity.this, R.string.toast_recording_failed, Toast.LENGTH_LONG).show();
mediaRecorder = null;
}
}
The file should be saved in a folder called TrueCapture and the file itself should be called ggj.3gp .
But the file is saved on the internal storage under the name 2131099680ggj.3gp .
The next problem there is, I can only find the file with the explorer app from my smartphone. The PC can't find the file and no other app.
Some Details:
Android 6
File Name is wrong (2131099680ggj.3gp instead of ggj.3gp)
File is saved in internal storage in no specific folder instead of the external storage (SD card is in the smartphone) in a new folder called "TrueCapture"
No other app seems to know about this file except for the explorer app of the smartphone
R.string.app_name is the ID assigned to your resource in the R class, an int.
To get your String resource, you might wanna use the getString() method of Context.
Something like this should work:
String ext = ".3gp";
File folder = new File(Environment.getExternalStorageDirectory() + "/" + getString(R.string.app_name));
if(!folder.exists()) {
folder.mkdirs();
}
file_name = folder.getAbsolutePath() + "/";
if(editText.getText().length() > 0) {
file_name += editText.getText().toString() + ext;
} else {
file_name += Calendar.getInstance().getTimeInMillis() + ext;
}
File outputFile = new File(file_name);
// ...
You also need to add the WRITE_EXTERNAL_STORAGE permission to your Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
In my assets folder, I have a directory called "maps" which contains a list of images I want to load.
When running:
Gdx.files.internal("maps").exists();
This returns true
and:
Gdx.files.internal("maps/Africa.png").exists();
also returns true
However, trying to list these files seems to be unfeasible:
Gdx.files.internal("maps").list().length;
returns a value of 0 for the number of files in that directory
Moreover:
Gdx.files.internal("maps").isDirectory();
returns false.
This is very puzzling for what could have seemed to been a very straightforward way of getting files from a directory.
Does anyone have any ideas to circumvent this?
Since desktop builds cannot use the list() method on internal directories, I created this script to write the file names to a text file. It uses Apache commons.io (you can put compile "commons-io:commons-io:2.4+" into your build.gradle to include it in your desktop module):
//directories within assets that you want a catalog of
static final String[] directories = {
"completeMaps",
"typeAMaps",
"typeBMaps",
"sfx",
"music"
};
public static void main (String[] args){
String workingDir = System.getProperty("user.dir");
for (String dir : directories){
File directory = new File(workingDir + "/" + dir);
File outputFile = new File(directory, "catalog.txt");
FileUtils.deleteQuietly(outputFile); //delete previous catalog
File[] files = directory.listFiles();
try {
for (int i = 0; i < files.length; i++) {
FileUtils.write(outputFile, files[i].getName() + (i == files.length - 1 ? "" : "\n"), true);
}
} catch (IOException e){
Util.logError(e);
}
}
}
Then to get a file list in a directory:
private FileHandle[] readDirectoryCatalogue (String directory){
String[] fileNames = Gdx.files.internal(directory + "/catalog.txt").readString().split("\n");
FileHandle[] files = new FileHandle[fileNames.length];
for (int i = 0; i < fileNames.length; i++) {
files[i] = Gdx.files.internal(directory + "/" + fileNames[i].replaceAll("\\s+",""));
}
return files;
}