Android couldn't able to write and delete operation on sd card - java

I am working now on ImageCompressor app.
I need to delete and write (update) image file. In Internal storage works perfectly but **SD Card can't give me access to Delete and Write files.
How can my app able to do write and delete operation on sd card (removable storage)?
I've already done whole project without this, so I have to must find a way.
Update:
I am already research & discuss about this issue. And understood I have to use storage access framework But I'm new on SAF.
I used a library to compress photo that need File not Uri. For that I do Uri -> File and use Intent.ACTION_OPEN_DOCUMENT and pick image from Removable storage.
But for removable storage I can't find Image Real Path from uri.
I don't know it's the right way or not. If there have any way in SAF where I can Compress my Image using uri, let me know. Or How to get Image real path from uri of Removable Storage Photo.
Update code SAF:
// ----------- Intent -------------
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
// ------------ On Activity Result --------------
Uri uri = data.getData();
try {
ParcelFileDescriptor fileDescriptor = getContentResolver().openFileDescriptor(uri, "w");
FileOutputStream fos = new FileOutputStream(fileDescriptor.getFileDescriptor());
FileInputStream fis = new FileInputStream(getImageFilePath(uri));
FileChannel source = fis.getChannel();
FileChannel destination = fos.getChannel();
destination.transferFrom(source, 0, source.size());
fis.close();
fos.close();
fileDescriptor.close();
Toast.makeText(this, "File save successfully.", Toast.LENGTH_SHORT).show();
}
Uri to File Path, I done where pick image from media apps(like Gallary, Photos) But pick from sd card what will instead of MediaStore.Images.Media.DATA I don't know. Code:
private File getImageFilePath(Uri uri) throws IOException {
String image_id = null, imagePath = null;
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
cursor.moveToFirst();
image_id = cursor.getString(0);
image_id = image_id.substring(image_id.lastIndexOf(":") + 1);
cursor.close();
}
cursor = getContentResolver().query(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, MediaStore.Images.Media._ID + " = ? ", new String[]{image_id}, null);
if (cursor!=null) {
cursor.moveToFirst();
imagePath = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
cursor.close();
}
File file = new File(imagePath);
return new Compressor(this).setQuality(50).compressToFile(file);
}

Removable SD cards are write only on modern Android devices if you use File and FileOutputStream classes.
If you are lucky then your device using getExternalFilesDirs() returns as second item an app specific directory on the card where you still can write.
For the rest and instead use the Storage Access Framework.
Start with letting the user choose the sd card with Intent.ACTION_OPEN_DOCUMENT_TREE or a file with Intent.ACTION_OPEN_DOCUMENT.

I digged into an old Android app of mine and retrieved this :
This method convert the root of the sdcard uri, to a File path.
public File getRootPath(Context context, Uri sdcardRootUri)
{
List<String> pathSegments = sdcardRootUri.getPathSegments();
String[] tokens = pathSegments.get(pathSegments.size()-1).split(":");
for (File f : ContextCompat.getExternalFilesDirs(context, null))
{
String path = f.getAbsolutePath().substring(0, f.getAbsolutePath().indexOf("/Android/"));
if (path.contains(tokens[0]))
{
return new File(path);
}
}
return null;
}
And in order to retrieved the uri of the sdcard root, I used that :
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, SDCARD_ROOT_CODE);
Then the user would choose the root of the sdcard and then, I handled the result like this :
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == RESULT_OK && requestCode == SDCARD_ROOT_CODE)
{
// Persist access permissions
Uri sdcdardRootUri = data.getData();
grantUriPermission(getPackageName(), sdcdardRootUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
final int takeFlags = data.getFlags() & (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(sdcdardRootUri, takeFlags);
// Do whatever you want with sdcdardRootUri
}
}
I hope it's what you are looking for. With that you can read/write/delete any file you want on the sdcard.

you have try
try {
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec("mount");
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
String line;
BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
//Filter common Linux partitions
if (line.contains("secure"))
continue;
if (line.contains("asec"))
continue;
if (line.contains("media"))
continue;
if (line.contains("system") || line.contains("cache")
|| line.contains("sys") || line.contains("data")
|| line.contains("tmpfs") || line.contains("shell")
|| line.contains("root") || line.contains("acct")
|| line.contains("proc") || line.contains("misc")
|| line.contains("obb")) {
continue;
}
if (line.contains("fat") || line.contains("fuse") || (line
.contains("ntfs"))) {
String columns[] = line.split(" ");
if (columns != null && columns.length > 1) {
String path = columns[1];
if (path!=null&&!SdList.contains(path)&&path.contains("sd"))
SdList.add(columns[1]);
}
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Related

Why is ALBUM_ART the only field that returns null from MediaStore when others are fine?

I'm having trouble retrieving the album artwork path. My storage permissions can't be the problem since I can fetch all other fields, so I'm wondering what the problem might be. I'll admit I'm a bit new to ContentResolvers and the MediaStore. I just need a path to be used in BitmapFactory.decodeFile(). The code is below, followed by the Log output.
Context (if it helps)
- Method is called from SongRoomDatabase.java (not an activity) which extends RoomDatabase.
- The context is passed from the MainActivity to the DB through the DB constructor.
Test method for retrieving album data from ALBUM_ID = 209 ("Viva la Gloria!" by Greenday)
public static void getCoverArtTest(){
Cursor cursor = mContext.getContentResolver().query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[] {
MediaStore.Audio.Albums._ID,
MediaStore.Audio.Albums.ALBUM,
MediaStore.Audio.Albums.ALBUM_ART,
MediaStore.Audio.Albums.ARTIST
},
MediaStore.Audio.Albums._ID+ "=?",
new String[] {String.valueOf(209)},
null);
if (cursor != null && cursor.moveToFirst()) {
String path = "";
path += cursor.getString(0) + "/";
path += cursor.getString(1) + "/";
path += cursor.getString(2) + "/";
path += cursor.getString(3) + "/";
// do whatever you need to do
Log.d("artworkTag", "Album art path: " + path);
}
}
Output
Album art path: 209/21st Century Breakdown/null/Green Day/
Is it just stored somewhere else? Do I need to retrieve it a specific way since it's not a string like the other fields (if it's returning something other than it's path)?
I noticed recently in my app the album arts started coming up empty where it had previously worked with similar code.
I checked the developer reference and there is new information about ALBUM_ART
This constant was deprecated in API level 29. Apps may not have
filesystem permissions to directly access this path. Instead of trying
to open this path directly, apps should use
ContentResolver#loadThumbnail to gain access.
So I tried changed the targetSdkVersion version back to 28 but still no good when running on a device with android 10 Q which is api 29.
So unfortunately to support newer androids we need to use something like this instead:
String filePath = null;
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
Cursor albumCursor = context.getContentResolver().query(
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Audio.Media._ID, MediaStore.Audio.Albums.ALBUM_ART},
MediaStore.Audio.Media._ID + " = " + albumId,
null,
null);
if (albumCursor != null) {
if (albumCursor.moveToFirst()) {
filePath = albumCursor.getString(1);
}
albumCursor.close();
}
} else {
Uri albumArtUri = ContentUris.withAppendedId(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, Long.parseLong(albumId));
try {
Bitmap bitmap = context.getContentResolver().loadThumbnail(albumArtUri, new Size(1024, 1024), null);
File art = new File(context.getCacheDir(), "albumart" + albumId + ".jpg");
art.createNewFile();
FileOutputStream fos = new FileOutputStream(art);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.flush();
fos.close();
filePath = art.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
}

How do I list all file in a directory in android 10 using Android Studio?

My current code uses:
String DirectoryPath = "/storage/emulated/0";
File f = new File(DirectoryPath);
File[] file = f.listFiles();
The problem is that the array comes up as blank for anything outside:
/storage/emulated/0/Android/data/com.example.myProgram
From what I read online this no longer works with android 10+. So how would I list all files in a certain directory? (Making a file explorer as part of an App)
Just add this line of code to your manifest in the application tag.
android: requestLegacyExternalStorage= "true"
Yes, With old code it won't work. Here i found the solution
List<Uri> filesList = new ArrayList<>();
Uri collection;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
} else {
collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
String[] projection = new String[]{
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.SIZE
};
String selection = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
selection = MediaStore.Images.Media.BUCKET_DISPLAY_NAME +
" =? ";
}
String[] selectionArgs = new String[]{
"Your folder name"
};
String sortOrder = MediaStore.Images.Media.DISPLAY_NAME + " ASC";
Cursor cursor = getApplicationContext().getContentResolver().query(
collection,
projection,
selection,
selectionArgs,
sortOrder
);
if (cursor != null && cursor.moveToFirst()) {
Log.d("continue", "not null");
} else {
Log.d("continue", "null return");
return;
}
// Cache column indices.
int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
int nameColumn =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
int sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);
do {
// Get values of columns for a given Images.
long id = cursor.getLong(idColumn);
String name = cursor.getString(nameColumn);
int size = cursor.getInt(sizeColumn);
Uri contentUri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
Log.d("continue", "path-->" + contentUri);
filesList.add(contentUri);
// Stores column values and the contentUri in a local object
// that represents the media file.
} while (cursor.moveToNext());
In the above code, I written for images only if you want any other files audio video you need to replace Images with Audio and Video ...etc
Note: if you convert Uri to file or string, then you can't use those files. You will get an error in android 10
for get fileNames,try this.
File sdCardRoot = Environment.getExternalStorageDirectory();
File yourDir = new File(sdCardRoot, "path");
for (File f : yourDir.listFiles()) {
if (f.isFile())
String name = f.getName();
// Do your stuff
}
What you described is valid.
Use Storage Access Framework to be able to list all directories.
Base on https://developer.android.com/reference/android/os/Environment#getExternalStorageDirectory(), To improve user privacy, direct access to shared/external storage devices is deprecated Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.
In my case,I need to find images or any kind of documents like .docx,.xls file on user's device so I'm using ACTION_OPEN_DOCUMENT like bellow:
Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("*/*");
startActivityForResult(intent, REQUEST_CODE_INTENT_GET_CV);

Save and Insert video to gallery on Android 10

I'm trying to save a video to the gallery,the following code works well an all Android versions except the Android Q:
private void getPath() {
String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ContentResolver resolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, videoFileName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/mp4");
contentValues.put(
MediaStore.MediaColumns.RELATIVE_PATH,
"Movies/" + "Folder");
contentValues.put(MediaStore.Video.Media.IS_PENDING, 1);
Uri collection =
MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
Uri videoUri = resolver.insert(collection, contentValues);
if (videoUri != null) {
try (ParcelFileDescriptor pfd = resolver.openFileDescriptor(videoUri, "w", null)) {
OutputStream outputStream = null;
if (pfd != null) {
outputStream = resolver.openOutputStream(videoUri);
outputStream.flush();
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
contentValues.clear();
contentValues.put(MediaStore.Video.Media.IS_PENDING, 0);
if (videoUri != null) {
resolver.update(videoUri, contentValues, null, null);
}
} else {
File storageDir = new File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)
+ "/Folder");
boolean success = true;
if (!storageDir.exists()) {
success = storageDir.mkdirs();
}
if (success) {
File videoFile = new File(storageDir, videoFileName);
savedVideoPath = videoFile.getAbsolutePath();
}
}
}
I also tried using get getExternalFilesDir() , but doesn't work, no video created in the gallery
String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
File imageFile = null;
File storageDir = new File(
getExternalFilesDir(Environment.DIRECTORY_DCIM),
"Folder");
boolean success = true;
if (!storageDir.exists()) {
success = storageDir.mkdirs();
}
if (success) {
imageFile = new File(storageDir, videoFileName);
}
savedVideoPath = imageFile.getAbsolutePath();
I use a 3rd-party library to record SurfaceView, this library requires a path to save the recorded video :
mRenderPipeline = EZFilter.input(this.effectBmp)
.addFilter(new GalleryEffects().getEffect(VideoMaker.this, i))
.enableRecord(savedVideoPath, true, false)
.into(mRenderView);
When record video finished, the recorded video saved with the given path savedVideoPath , everything works just fine on all android version except the Android Q
After saving the video, when I check, I get an empty video in the gallery
I have answered you to your other post to... You need an inputstream (file, bitmap etc.) and write an outputstream from the inputfile.
You have to change the library to make it work with Android Q . If you cannot do this you could copy the video to the media gallery and then delete the old video created in getExternalFilesDir(). After this you have the uri of the video and can do what you want with the uri
If you have saved the video with getExternalFilesDir() you could use my example here : The media uri you get is "uriSavedVideo" . This is only an example. A large video should also be copied in the background.
String videoFileName = "video_" + System.currentTimeMillis() + ".mp4";
ContentValues valuesvideos;
valuesvideos = new ContentValues();
valuesvideos.put(MediaStore.Video.Media.RELATIVE_PATH, "Movies/" + "Folder");
valuesvideos.put(MediaStore.Video.Media.TITLE, videoFileName);
valuesvideos.put(MediaStore.Video.Media.DISPLAY_NAME, videoFileName);
valuesvideos.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
valuesvideos.put(
MediaStore.Video.Media.DATE_ADDED,
System.currentTimeMillis() / 1000);
valuesvideos.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 1);
ContentResolver resolver = mContext.getContentResolver();
Uri collection =
MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
Uri uriSavedVideo = resolver.insert(collection, valuesvideos);
ParcelFileDescriptor pfd;
try {
pfd = mContext.getContentResolver().openFileDescriptor(uriSavedVideo, "w");
FileOutputStream out = new FileOutputStream(pfd.getFileDescriptor());
// Get the already saved video as fileinputstream from here
File storageDir = new File(
mContext.getExternalFilesDir(Environment.DIRECTORY_MOVIES),
"Folder");
File imageFile = new File(storageDir, "Myvideo");
FileInputStream in = new FileInputStream(imageFile);
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.close();
in.close();
pfd.close();
} catch (Exception e) {
e.printStackTrace();
}
valuesvideos.clear();
valuesvideos.put(MediaStore.Video.Media.IS_PENDING, 0);
mContext.getContentResolver().update(uriSavedVideo, valuesvideos, null, null);
I want to create a path to use it
You are getting a Uri from MediaStore. There is no "path". Not only can a Uri not be converted to a path, but you do not have filesystem access to that location on Android 10 and higher.
Get rid of this:
if (videoUri != null) {
savedVideoPath = getRealPathFromURI(videoUri);
}
as it will not work.
Replace it with your code to write out your video to the location identified by the Uri. Use resolver.openOutputStream() to get an OutputStream to that location. In particular, do this before you call resolver.update() for an IS_PENDING of 0, as that specifically says "I am done writing to the Uri; you can use the content now".
Or, use one of the filesystem locations that you do have access to, such as getExternalFilesDir() on Context, and get rid of the MediaStore stuff.

get a file object from google drive with URI android

I have tried numerous methods of getting a file object from a google drive URI but most result in the following error:
java.lang.SecurityException: Permission Denial: reading com.google.android.apps.docs.storagebackend.StorageBackendContentProvider uri content://com.google.android.apps.docs.storage/document/acc=1;doc=4235 from pid=32140, uid=10149 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
So I added android.permission.MANAGE_DOCUMENTS and it did not work, so I tried to use grantUriPermission() and got the following error:
java.lang.SecurityException: Uid 10151 does not have permission to uri 0 # content://com.google.android.apps.docs.storage/document/acc=1;doc=4235
This file plugin has a nice way of getting files from just about anywhere, except google drive: aFileChooser.
So I took to stack overflow for answers:
Open a Google Drive File Content URI after using KitKat Storage Access Framework
Android KitKat securityException when trying to read from MediaStore
Getting Permission Denial Exception
No permission for UID to access URI error on Android Application
and there are about 15 others, but none helped
I am using Cordova so this is a cross platform app so it restricts me a bit. Here is how I get my URI, I press a button in my webview app, and then a new page is loaded allowing me to select my video from somewhere on my phone and I select google drive, then select a video, and then a URI is sent back to my webview I was on, I then send the URI to a java file to try and download the file. here is the different methods I have tried to download the file:
String filePath = null;
Log.d(TAG,"URI = "+ uri);
if (uri != null && "content".equals(uri.getScheme())) {
Log.d(TAG, "got inside if");
Cursor cursor = context.getContentResolver().query(uri, new String[] { android.provider.MediaStore.Files.FileColumns.DATA }, null, null, null);
cursor.moveToFirst();
filePath = cursor.getString(0);
cursor.close();
} else {
Log.d(TAG, "got inside else");
filePath = uri.getPath();
}
Log.d("","Chosen path = "+ filePath);
This method is similar, but fails the same:
String mimeType = context.getContentResolver().getType(uri);
Log.d(TAG,mimeType);
Cursor returnCursor = getContentResolver().query(returnUri, null, null, null, null);
int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE);
returnCursor.moveToFirst();
Log.d(TAG,returnCursor.getString(nameIndex));
Log.d(TAG,Long.toString(returnCursor.getLong(sizeIndex)));
This method game the same error as the previous
try{
InputStream input = context.getContentResolver().openInputStream(uri);
try {
File file = new File(context.getCacheDir(), "cacheFileAppeal.mp4");
OutputStream output = new FileOutputStream(file);
try {
try {
byte[] buffer = new byte[4 * 1024]; // or other buffer size
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
output.flush();
} finally {
output.close();
}
} catch (Exception e) {
e.printStackTrace(); // handle exception, define IOException and others
}
} finally {
input.close();
}
}
catch(Exception e){
e.printStackTrace();
}
all three game me
java.lang.SecurityException: Permission Denial: reading com.google.android.apps.docs.storagebackend.StorageBackendContentProvider uri content://com.google.android.apps.docs.storage/document/acc=1;doc=4235 from pid=32140, uid=10149 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
The following code for some reason did not crash, but gave me the mimeType:
String mimeType = context.getContentResolver().getType(uri);
I think the problem is that I am not using the URI in the original intent where the URI was retrieved from google drive, but I am not sure.
Does anyone know how to get a file object from google drive URI?

Java: replacing a new file

I draw an image on a panel by using BufferedImage, and now I want to export that image.
But how can I detect if the new file is created or replace the old one? right now my output is:
old filename: image.jpeg
new filename: image.jpeg.jpeg
How can I do it?? I put a detect code after the file is created, using createNewFile method, but it doesn't seem to work :(
This is pattern that do the saving, user can choose various types of image (bmp, jpeg ...):
imageFile is File
private void saveImage(){
JFileChooser savefile = new JFileChooser("~/");
savefile.setFileSelectionMode(JFileChooser.FILES_ONLY);//Chose file only
savefile.setFileFilter(new pngSaveFilter());//Save in PNG format
savefile.addChoosableFileFilter(new jpegSaveFilter());//Save in JPEG format
savefile.addChoosableFileFilter(new bmpSaveFilter());//Save in BMP format
savefile.addChoosableFileFilter(new gifSaveFilter());//Save in GIF format
savefile.setAcceptAllFileFilterUsed(false);
int returnVal = savefile.showSaveDialog(null);//Show save dialog
String EXT="";
String extension="";
if (returnVal == JFileChooser.APPROVE_OPTION) {
imageFile = savefile.getSelectedFile();
extension = savefile.getFileFilter().getDescription();
if (extension.equals("JPEG file images *.jpeg,*.JPEG")) {
EXT = "JPEG";
imageFile = new File(imageFile.getAbsolutePath() + ".jpeg");
}
if (extension.equals("PNG file images *.png,*.PNG")) {
EXT = "PNG";
imageFile = new File(imageFile.getAbsolutePath() + ".png");
}
if (extension.equals("Bitmap file images *.bmp,*.BMP")) {
EXT = "BMP";
imageFile = new File(imageFile.getAbsolutePath() + ".bmp");
}
if (extension.equals("GIF file images *.gif,*.GIF")) {
EXT = "GIF";
imageFile = new File(imageFile.getAbsolutePath() + ".gif");
}
try {
if(imageFile != null){
topViewImagePanel.drawToSave();
System.out.println(imageFile.createNewFile());
//ImageIO.write(topViewImagePanel.getSavingImage(), EXT, imageFile);
// the code detection is below
if (imageFile.createNewFile()){
int value = JOptionPane.showConfirmDialog(null, "Image existed! Replace?", "Warning!", JOptionPane.YES_NO_OPTION);
if (value == JOptionPane.YES_OPTION){
imageFile.delete();
ImageIO.write(topViewImagePanel.getSavingImage(), EXT, imageFile);
}else if (value == JOptionPane.NO_OPTION){
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
if(imageFile.exists())
Do a simple check to see if a file already exists or not.
Don't append file extension manually to the file name.
It is already present in the absolute path.
To handle files already present, use else clause of
if (imageFile.createNewFile())
Hope this helps.
If you use Java 7, use the new API:
if (imageFile != null) {
final Path path = imageFile.toPath();
if (Files.exists(path)) {
int value = JOptionPane.showConfirmDialog(null,
"Image existed! Replace?", "Warning!", JOptionPane.YES_NO_OPTION);
if (value == JOptionPane.YES_OPTION)
Files.delete(path);
}
ImageIO.write(topViewImagePanel.getSavingImage(), EXT,
Files.newOutputStream(path));
}
Also, as to your original question:
I put a detect code after the file is created, using createNewFile method, but it doesn't seem to work :(
This is normal, you call .createNewFile() twice:
System.out.println(imageFile.createNewFile()); // <-- CALL 1
//ImageIO.write(topViewImagePanel.getSavingImage(), EXT, imageFile);
// the code detection is below
if (imageFile.createNewFile()){ // <-- CALL 2
It will always fail the second time!

Categories