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" />
Related
I would like to move a file from the download folder to a folder in my app, I have seen that you can use the Files.move (source, destination) function, but I don't know how to get the source and destination path.
When y try
String sdCard = Environment.getExternalStorageDirectory().toString();
File ficheroPrueba = new File(sdCard + "/pau_alem18je_compressed.pdf");
if(ficheroPrueba.exists())
Log.v(TAG, "Hola")
}
Despite having downloaded the file (it is seen in the android emulator in downloads) it does not print the log.v
Use Environment.getExternalStorageDirectory() to get to the root of external storage (which, on some devices, is an SD card).
String sdCard = Environment.getExternalStorageDirectory().toString();
// the file to be moved or copied
File sourceLocation = new File (sdCard + "/sample.txt");
// make sure your target location folder exists!
File targetLocation = new File (sdCard + "/MyNewFolder/sample.txt");
// just to take note of the location sources
Log.v(TAG, "sourceLocation: " + sourceLocation);
Log.v(TAG, "targetLocation: " + targetLocation);
try {
// 1 = move the file, 2 = copy the file
int actionChoice = 2;
// moving the file to another directory
if(actionChoice==1){
if(sourceLocation.renameTo(targetLocation)){
Log.v(TAG, "Move file successful.");
}else{
Log.v(TAG, "Move file failed.");
}
}
// we will copy the file
else{
// make sure the target file exists
if(sourceLocation.exists()){
InputStream in = new FileInputStream(sourceLocation);
OutputStream out = new FileOutputStream(targetLocation);
// Copy the bits from instream to outstream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
Log.v(TAG, "Copy file successful.");
}else{
Log.v(TAG, "Copy file failed. Source file missing.");
}
}
} catch (NullPointerException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
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 know with Kit Kat you can only write to your applications package specific directory on SD Cards. I was however under the impression you could still copy files from an SD card to local storage with the:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I am simply testing if I can copy one file. If I am able to do that I will add the code to search the entire SD card DCIM folder. For now I have the following code (please forgive the messiness of the code, I have written C# and vb.net but java is still very new to me):
String dirPath = getFilesDir().getAbsolutePath() + File.separator + "TCM";
File projDir = new File(dirPath);
if (!projDir.exists())
projDir.mkdirs();
String CamPath = projDir + File.separator + tv2.getText();
File projDir2 = new File(CamPath);
if (!projDir2.exists())
projDir2.mkdirs();
File LocalBuck = new File(projDir2 + File.separator );
String imageInSD = Environment.getExternalStorageDirectory().getAbsolutePath();
File directory1 = new File (sdCard.getAbsolutePath() + "/DCIM");
File directory = new File(directory1 + "/100SDCIM");
File Buckfile = new File(directory, "/BigBuck.jpg");
try {
exportFile(Buckfile, LocalBuck);
} catch (IOException e) {
e.printStackTrace();
}
Here is my code for the export function/application:
private File exportFile(File src, File dst) throws IOException {
//if folder does not exist
if (!dst.exists()) {
if (!dst.mkdir()) {
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyy_MM_dd_HHmmss").format(new Date());
File expFile = new File(dst.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
FileChannel inChannel = null;
FileChannel outChannel = null;
try {
//Straight to Error Handler
inChannel = new FileInputStream(src).getChannel();
outChannel = new FileOutputStream(expFile).getChannel();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
inChannel.transferTo(0, inChannel.size(), outChannel);
} finally {
if (inChannel != null)
inChannel.close();
if (outChannel != null)
outChannel.close();
}
return expFile;
}
Here is what my emulator looks like:
Looking for: Debug of SD Location
Should Find It?: EmulatorShowingSd
Question: Am I even able to copy a file from the SD card to local storage after KitKat; if so what is wrong in the code causing the exception to be thrown when it tries to access the SD card file?
In my app After user clicks on a button ,the download manager starts to download a file from internet and saving it to the internal sd card using this code:
void startDownload()
{
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).mkdirs();
download_req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle(PersianReshape.reshape("Downloading"))
.setDescription(PersianReshape.reshape("currently downloading the file..."))
.setDestinationInExternalPublicDir(Environment.getExternalStorageDirectory().getAbsolutePath() , packageId + ".sqlite");
download_ID = mgr.enqueue(download_req);
}
After it is downloaded, I plan to check its existance everytime app runs with this code:
String DatabaseAddress =
Environment.getExternalStorageDirectory().getAbsolutePath() +
"/ee.sqlite";
File file = new File(DatabaseAddress);
Log.d("PATH File: ", DatabaseAddress);
if (file.exists()){
Toast.makeText(getApplicationContext(), "found", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(), "not found", Toast.LENGTH_SHORT).show();
}
Now when I run this code it returns "not found" message whereas the file is already there (I checked its existance using a file manager).
the device I test on is nexus 7 and path used in saving the download file is: /storage/emulated/0/ee.sqlite
ee.sqlite is the filename of downloaded file.
/storage/emulated/0/ is the default path returned by app
Permissions added to manifest for this code are:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Q: Why does file.exists() returns false when there is a file?
UPDATE:
WHEN I USE HARDCODE
File temp = new File("/sdcard/storage/emulated/0/", "ee.sqlite");
it works but when I use Environment.getExternalStorageDirectory().getPath() it doesn't.
Just initialize the File like this:
Updated:
This is just because of the separator missing there:
public static File getExternalStorageDirectory() {
return EXTERNAL_STORAGE_DIRECTORY;
}
and EXTERNAL_STORAGE_DIRECTORY is:
private static final File EXTERNAL_STORAGE_DIRECTORY
= getDirectory("EXTERNAL_STORAGE", "/sdcard");
static File getDirectory(String variableName, String defaultPath) {
String path = System.getenv(variableName);
return path == null ? new File(defaultPath) : new File(path);
}
String baseDir = EXTERNAL_STORAGE_DIRECTORY ;
String fileName = "ee.sqlite";
// Not sure if the / is on the path or not
File file = new File(baseDir + File.separator + fileName);
if (file.exists()) {
Toast.makeText(getApplicationContext(), "found", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "not found", Toast.LENGTH_SHORT).show();
}
2nd Possibilites: As you are running it in emulator you have to make sure you have external storage enabled Like this:
In Eclipse, go to Window > Android SDK and AVD Manager. Select the appropriate AVD and then click Edit.
Make sure you have SD card support enabled. If you do not, click the "New" button and select the "SD Card Support" option.
Finally got it to work by changing the File object.
The solution is to change the File object to the following:
File file = new File(Environment.getExternalStorageDirectory().getPath() + dirName + File.separator , fileName);
where dirName is:
String dirName = Environment.getExternalStorageDirectory().getAbsolutePath();
and fileName is:
String fileName = "ee.sqlite";
so I could easily check whether file exist or not using my criteria function.
if (file.exists()){
Toast.makeText(getApplicationContext(), "found", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(), "not found", Toast.LENGTH_SHORT).show();
}
I like to thank #andru for helping me.
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
}