I am trying to save image to Gallery from image View but getting File Not Found Exception Error
The code I tried but got File Not Found Exception.
Sorry if you didn't understand my English.
save.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
BitmapDrawable draw = (BitmapDrawable) mainImage.getDrawable();
Bitmap bitmap = draw.getBitmap();
try{
FileOutputStream outStream = null;
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File(sdCard.getAbsolutePath() "/MyFolder");
dir.mkdirs();
String fileName = String.format("%d.jpg", System.currentTimeMillis());
File outFile = new File(dir, fileName);
outStream = new FileOutputStream(outFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(Uri.fromFile(outFile));
sendBroadcast(intent);
}
catch (Exception e){
e.printStackTrace();
Toast.makeText(MainActivity.this,e.toString(),Toast.LENGTH_SHORT).show();
}
}
});
I am a beginner so I don't how to solve this Problem. Help me Please
CodePudding user response:
So let's start from scratch
Step 1: Add the permissions of Read and Write in your manifest
Step 2: Make the Bitmap of the Image you have in ImageView
Step 3: Now there is a different mechanism for saving files in the below and above Android Version Q
In Below Q:
private File saveBitmapBelowQ(Bitmap bitmap, String name) {
File imageRoot = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM), appDirectoryName);
if (!imageRoot.exists()) {
imageRoot.mkdirs();
}
File image = new File(imageRoot, name ".png");
try {
if (image.createNewFile()) {
try (FileOutputStream fos = new FileOutputStream(image)) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,
100, bos);
byte[] bitmapdata = bos.toByteArray();
fos.write(bitmapdata);
fos.flush();
imagePath = image.getPath();
}
return image;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Where AppDirectory is the Name of the Directory you want and the name is the name of the Image preferred to use live date and time. In this method,
- First, create the Directory in External Storage.
- Then create the file of your image (Try to make it unique)
- The last step is to convert your Bitmap into a byte Array and write on the file you created in (point 2)
In Android Version Q and Above:
@RequiresApi(api = Build.VERSION_CODES.Q)
public File saveBitmapAboveQ(Bitmap bitmap, Context context, String directoryName, String name) {
OutputStream fos;
ContentResolver resolver = context.getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, name);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/" directoryName);
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
try {
fos = resolver.openOutputStream(imageUri);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
imagePath = new File(getPath(imageUri)).getAbsolutePath();
return new File(getPath(imageUri));
} catch (Exception e) {
return null;
}
}
Create a Content Resolver and set the content values such as File name, type, and location then pass content values to the content resolver and pass your content resolver to FileOutputStream/ OutputStream Now write your Bitmap over the output stream
Happy Coding
CodePudding user response:
Kotlin way: You can use this extension function to save file in storage
fun Bitmap.saveAsFile(isPng: Boolean = false): File? {
val root = Environment.getExternalStorageDirectory()
val myDir = File("${root}/pic")
myDir.mkdirs()
if (myDir.exists()) {
val random = (Math.random() * (1024 - 1)).toLong()
val prefix = "IMG${random}_${System.currentTimeMillis().toTimestamp()}"
.replace(" ", "_")
.replace(":", "-")
val fileName = if (isPng) "$prefix.png" else "$prefix.jpg"
val file = File(myDir, fileName)
if (file.exists()) file.delete()
return try {
val out = FileOutputStream(file)
if (isPng) {
this.setHasAlpha(true)
this.compress(Bitmap.CompressFormat.PNG, 100, out)
} else {
this.compress(Bitmap.CompressFormat.JPEG, 100, out)
}
out.flush()
out.close()
file
} catch (e: Exception) {
e.printStackTrace()
null
}
}
return null
}
Sample Usage:
val imageFile = view.drawToBitmap().saveAsFile()