file.isDirectory() always false in android with the path - android

ANSWER:
Needed the call to getExternalFilesDir(p); like so:
String p = thepathblah;
File path=context.getExternalFilesDir(p);
EDIT EDIT:
While I knew the Environment.DIRECTORY_PICTURES was returning just Pictures/ I figured this worked because in android I assumed the file pointer was already pointing to your application space (sorta like in c#). So in this:
String p = Environment.DIRECTORY_PICTURES + "/" + s.getClient().getFirstName()+s.getClient().getLastName() +
"/" + s.getPackage().getName() +
(mSession.getSessionDate().getMonth()+1) +
mSession.getSessionDate().getDate() +
(mSession.getSessionDate().getYear()+1900);
I thought was getting the full path, in fact I was writing a file out to this with no issues. It turns out though to delete individual files (and load them) I needed a fuller path which ended up being:
String p = Environment.DIRECTORY_PICTURES + "/" + s.getClient().getFirstName()+s.getClient().getLastName() +
"/" + s.getPackage().getName() +
(mSession.getSessionDate().getMonth()+1) +
mSession.getSessionDate().getDate() +
(mSession.getSessionDate().getYear()+1900);
File dir = new File("/sdcard/Android/data/com.software.oursoftware/files/"+p);
Not sure if I can take it that the above link is valid for all Honeycomb devices or not, specifically the /sdcard/Android/data/packagespace/files/
Is this safe to use this or do I have to do something more dynamic for honeycomb devices???
EDIT: This is my little test function code to just write something to a folder...
String p = Environment.DIRECTORY_PICTURES + "/" + s.getClient().getFirstName()+s.getClient().getLastName() + "/" + s.getPackage().getName() + (mSession.getSessionDate().getMonth()+1) + mSession.getSessionDate().getDate() + (mSession.getSessionDate().getYear()+1900);
File path = mContext.getExternalFilesDir(p);
File file = new File(path, "DemoPicture.jpg");
try {
// Very simple code to copy a picture from the application's
// resource into the external file. Note that this code does
// no error checking, and assumes the picture is small (does not
// try to copy it in chunks). Note that if external storage is
// not currently mounted this will silently fail.
InputStream is = getResources().openRawResource(R.drawable.ic_contact_picture);
OutputStream os = new FileOutputStream(file);
byte[] data = new byte[is.available()];
is.read(data);
os.write(data);
is.close();
os.close();
// Tell the media scanner about the new file so that it is
// immediately available to the user.
MediaScannerConnection.scanFile(mContext,
new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String arg0, Uri arg1) {
Log.i("ExternalStorage", "Scanned " + arg0 + ":");
Log.i("ExternalStorage", "-> uri=" + arg1);
}
});
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
}
Then the way I try to delete this folder:
String p = Environment.DIRECTORY_PICTURES + "/" + firstName+lastName +"/" + pName+pDate;
File dir=new File(p);
deleteRecursive(dir);
results in
Pictures/ShaneThomas/Portrait882011/
Which can write a file, tested that, but if I try to say:
void deleteRecursive(File dir)
{
Log.d("DeleteRecursive", "DELETEPREVIOUS TOP" + dir.getPath());
if (dir.isDirectory())
{
String[] children = dir.list();
for (int i = 0; i < children.length; i++)
{
File temp = new File(dir, children[i]);
if(temp.isDirectory())
{
Log.d("DeleteRecursive", "Recursive Call" + temp.getPath());
deleteRecursive(temp);
}
else
{
Log.d("DeleteRecursive", "Delete File" + temp.getPath());
boolean b = temp.delete();
if(b == false)
{
Log.d("DeleteRecursive", "DELETE FAIL");
}
}
}
dir.delete();
}
}
The dir.isDirectory is always false!? I got this delete file/directories code off stack overflow but am puzzled as to why its not working?
and I do have this set:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

There are several reasons for File.isDirectory() to return false:
The path points to file (obviously), and not to directory.
The path is invalid (i.e. there is no such file/directory exists).
There is not enough permissions granted to your application to determine whether path points to directory.
In general, if isDirectory() returns true, you've got path that points to directory. But if isDirectory() returns false, then it might be or might not be a directory.
In your particular case, the path most likely does not exist. You need to call dir.mkdirs() to create all directories in the path. But since you need that to only recursively delete them, then there is no point in calling dir.mkdirs() just to remove that directory after that.

I think you want to add
dir.mkdirs() right after File dir=new File(p). mkdirs() is the method responsible for actually creating a directory, not new File().

Ok it's answered, but sometimes the issue fires because of sample reasone:permission :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
if you forgot this permission you will always get false result.

Related

Not Able to access expansion file content

I am using this code, but I am not able to access the expansion file content, i want to show gif image from expansion file, how can i do?
String packageName = getPackageName();
File root = Environment.getExternalStorageDirectory();
File expPath = new File(root.toString() + "/Android/obb/" + packageName);
try {
if (expPath.exists()) {
String strMainPath = expPath
+ File.separator
+ "main."
+ getPackageManager().getPackageInfo(
getPackageName(), 0).versionCode + "."
+ packageName + ".obb";
File f = new File(strMainPath);
if (f.exists()) {
Log.e("Path ", "=====>Exists");
} else {
Log.e("Path ", "=====> Not Exists");
}
ZipResourceFile zip = new ZipResourceFile(strMainPath);
InputStream iStream = zip.getInputStream("stage1_popup.gif");
BitmapFactory.Options option = new BitmapFactory.Options();
option.inPurgeable = true;
Bitmap bitmap = BitmapFactory.decodeStream(iStream, null, option);
Glide.with(SampleDownloaderActivity.this).load(bitmap).into(image);
}
} catch (Exception e) {
}
http://prntscr.com/kp25qz
The Play APK expansions files library is completely open source, and you can see the sourcecode for ZipResourceFile here.
It looks like stage1_popup.gif is not in your obb file. To investigate it, why not use adb pull to get the file off your device and see what it actually contains. Or download the source code and attach to your IDE so you can step into the getInputStream() call and see where it is going wrong.
As mentioned in this answer, ZipResourceFile isn't able to deal with too much little files and neither is ZipFile. So try to divide your files in more directories.
Also, it's quite possible that there isn't any file with the name, stage1_popup.gif.
Alternatively, you can get all Entries via zipResourceFile.getAllEntries() and findout if the file exists.

File.renameTo return false

I want to rename my png file. Image current path like this:
/storage/emulated/0/Android/data/sample.png
I want to save this image under app's file directory. I give write external storage permission on runtime.
File toFileDir = new File(getFilesDir() + "images");
if(toFileDir.exists()) {
File file = new File("/storage/emulated/0/Android/data/sample.png");
File toFile = new File(getFilesDir() + "images/sample-1.png");
file.renameTo(toFile);
}
renameTo returns false. But I couldn't understand the reason.
Internal and external memory is two different file systems. Therefore renameTo() fails.
You will have to copy the file and delete the original
Original answer
You can try the following method:
private void moveFile(File src, File targetDirectory) throws IOException {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!src.renameTo(new File(targetDirectory, src.getName()))) {
// If rename fails we must do a true deep copy instead.
Path sourcePath = src.toPath();
Path targetDirPath = targetDirectory.toPath();
try {
Files.move(sourcePath, targetDirPath.resolve(sourcePath.getFileName()), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException ex) {
throw new IOException("Failed to move " + src + " to " + targetDirectory + " - " + ex.getMessage());
}
}
} else {
if (src.exists()) {
boolean renamed = src.renameTo(targetDirectory);
Log.d("TAG", "renamed: " + renamed);
}
}
}

mkdir return false in android?

This is my code
String DATA_PATH="/mnt/sdcard/";
String[] paths = new String[] { DATA_PATH, DATA_PATH + "tessdata/" };
for (String path : paths) {
File dir = new File(path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
Log.v("", "ERROR: Creation of directory " + path + " on sdcard failed");
} else {
Log.v("", "Created directory " + path + " on sdcard");
}
}
}
I've tried using Environment.getExternalDirectory() but it still return false. The most confusing thing is it always said "ERROR: Creation of directory mounted on sdcard failed" on the logcat. How can the path changed into mounted? Can someone please give me a solution?
if the mobile is connected to the system then we are not able to create folders so remove it and run the application
Why are you using mkdirs in the first place ? You should just do:
File file = new File(Environment.getExternalStorageDirectory(), "tessdata");
if (!file.exists()) file.mkdir();
Also, make sure you have the WRITE_EXTERNAL_STORAGE permission in the manifest.

Android - Unable to save images

I'm currently trying to get image saving to happen using the device built in camera. This is the code I'm using:
PackageManager pm = getActivity().getPackageManager();
if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// * Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(pm) != null) {
// * Create the File where the photo should go
File photoFile = null;
try {
photoFile = ImageFileHelper.createImageFile();
} catch (IOException ex) {
// * Error occurred while creating the File
Timber.d("An error occurred while creating file: " + ex.getLocalizedMessage());
}
// * Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_CODE_TAKE_PICTURE);
} else {
alertUserOfError(0);
}
}
} else {
// * Inform user that they need a camera
// * to use this feature
alertUserOfError(1);
}
And here is the ImageFileHelper.createImageFile() function:
public static File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyy-MM-dd.ss", Locale.getDefault()).format(new Date());
String imageFileName = "Original_Avatar_" + timeStamp;
// * Create MyApp folder if not exist
String path = Environment.getExternalStorageDirectory() + File.separator + Environment.DIRECTORY_PICTURES;
File dir = new File(path + "/MyApp/Originals/");
dir.mkdirs();
File image = File.createTempFile(
imageFileName, /* prefix */
".png", /* suffix */
dir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
filePath = "file:" + image.getAbsolutePath();
Timber.d("image created at: " + filePath);
return image;
}
My permissions & features:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
This seems to work just fine on my test devices and the majority of my beta tester devices. However, there is one guy who reports that he gets an error message generated by alertUserOfError(0) (you'll see that in the above code), essentially that the photoFile is null.
He is using a rooted HTC One (M8) (htc_m8). Could this be an issue due to the device being rooted?
Any help is appreciated.
UPDATE 2015-05-30
I haven't had a chance to add reporting to the catch statement yet, but I did add a method to test for valid paths/directories. Here is how it works:
StringBuilder build = new StringBuilder();
String path_1 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + File.separator + "MyApp" + File.separator + "Cropped" + File.separator;
File dir_1 = new File(path_1);
dir_1.mkdirs();
if (dir_1.exists()) {
build.append("path 1 valid, ");
} else {
build.append("path 1 invalid, ");
}
Using this same setup I also tested the following dirs:
Environment.getExternalStorageDirectory() + File.separator + "MyApp" + File.separator + "Cropped" + File.separator;
Environment.getDataDirectory() + File.separator + "MyApp" + File.separator + "Cropped" + File.separator;
The StringBuilder.toString() is then used as the message in an alert for the tester to send the results back to us.
The above resulted in all paths being invalid:
path_1 invalid, path_2 invalid, path_3 invalid
So does this mean that those directories just don't exist on the HTC One (M8) (htc_m8) and cannot be created?
I had a similar situation. You are implementing the example given in the official docs. There is a problem implementing that example in some devices. This is how I solved it.
Replace:
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
With:
private File createImageFile() throws IOException {
// Create an image file name
Finally, make sure you call:
mkdirs() // and not mkdir()
Here's the code that should work for you:
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = new File(Environment.getExternalStorageDirectory().toString(), "whatever_directory_existing_or_not/sub_dir_if_needed/");
storageDir.mkdirs(); // make sure you call mkdirs() and not mkdir()
File image = File.createTempFile(
imageFileName, // prefix
".jpg", // suffix
storageDir // directory
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
Log.e("our file", image.toString());
return image;
}
I had a bad experience following the example given in Android Studio Documentation and I found out that there are many others experiencing the same about this particular topic here in stackoverflow, that is because even if we set
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
the problem persists in some devices.
My experience was that the example worked when I tried it in debug mode, after that 3 more tests passed, it so happened that my SD was suddenly corrupted, but I don't think it had to do with their example (funny). I bought a new SD card and tried it again (because I could not reformat my sd, however I tried), only to realize that still both release and debug mode did the same error log: directory does not exist ENOENT. Finally, I had to create the directories myself whick will contain the captured pictures from my phone's camera. And I was right, it works just perfect.
I hope this will help the ones out there searching for answers, because obviously, considering the age of your enquiry, you must have already solved this issue.

file.mkdirs() not working

i want to write to a file in the sdcard of my phone.i used the below code to do this.
private CSVWriter _writer;
private File _directory;
public String _fileTestResult;
private String PATH_FILE_EXPORT = "/applications/foru/unittestframework/";
public ExportData(){
_writer=null;
_directory = new File(Environment.getExternalStorageDirectory () +PATH_FILE_EXPORT);
if(!_directory.exists())
_directory.mkdirs();
}
public void exportResult(String testcaseNum,String testcase,String status){
try {
if(_directory.exists()){
//do something
}
but mkdirs() is not working.so i could not excecute following code in the if condition.please help me.
note:i have given the permission in manifest file.
EDIT:
i am using this file write option for storing the result of automation testing using robotium.i have created a normal project and tried to create directory in sdcard.but the same code when i am using in this testproject it is not working.why like that?dont unit testing framework support this?
have you add the correct permission in your manifest ?
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Edit : ok, i just read your note for permission.
If it's help you this is my sdcard cache code :
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){
String evtDir = "";
if(evt > 0){
evtDir = File.separator + evt;
}
cacheDir = new File(
android.os.Environment.getExternalStorageDirectory()
+ File.separator
+ "Android"
+ File.separator
+ "data"
+ File.separator
+ Application.getApplicationPackageName()
+ File.separator + "cache"
+ evtDir);
}else
cacheDir=context.getCacheDir();
if(!cacheDir.exists())
cacheDir.mkdirs();
}
Try below code
try {
File root = Environment.getExternalStorageDirectory();
if (root.canWrite()) {
imagefolder = new File(root,
mycontext.getString(R.string.app_name));
imagefolder.mkdirs();
}
} catch (Exception e) {
Log.e("DEBUG", "Could not write file " + e.getMessage());
}
Try with:
if(!_directory.exists())
_directory.mkdir();
Also check this - Creating a directory in /sdcard fails

Categories

Resources