ContentResolver throws FileNotFoundException on API Level 18 - android

When I try to open a file just after inserting it using ContentResolver on Android API Level 18 it throws the exception FileNotFoundException.
If I try to run the same code on API Level 17 it works fine.
String fileName = DateFormat.format("yyyyMMdd_hhmmss", new Date()).toString();
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, fileName);
values.put(Images.Media.MIME_TYPE, "image/jpeg");
ContentResolver contentResolver = getContentResolver();
Uri uri = contentResolver.insert(Media.EXTERNAL_CONTENT_URI, values);
OutputStream outstream;
try {
outstream = contentResolver.openOutputStream(uri);
image.compress(Bitmap.CompressFormat.JPEG, 90, outstream);
outstream.close();
return uri;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I tried using Images.Media.insertImage() but it didn't work too. Looking source code of this method I realized that code looks much like mine.

Unfortunately using ContentResolver is not working as expected. So I decided to use other approach.
try {
String fileName = DateFormat.format("yyyyMMdd_hhmmss", new Date()).toString();
File dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
dir.mkdirs();
File file = new File(dir, fileName + ".jpg");
OutputStream out = new FileOutputStream(file);
image.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.close();
MediaScannerConnection.scanFile(this,
new String[] { file.toString() },
null,
null);
} catch (IOException e) {
e.printStackTrace();
}

Related

Trying to copy image one folder to another folder using contentResolver in android 11 but it create blank image

i m working on an application where i have list of images inside recyclerview and from recyclerview i have to copy my images from one folder to another folder my code is working fine in many android 11 and 12 device but in few device it creates blank images the size of blank image is in byte i don't understand what is wrong with my code
here is the code i used for copy image
public static String copyFile(#NonNull final String filePath, String newName, File targetFolder, Context context) {
ContentResolver contentResolver = context.getContentResolver();
FileOutputStream fos = null;
String folderName = targetFolder.getName();
String relativePath;
String fileName = new File(filePath).getName();
String mimeType = getFileType(fileName);
ArraySet<Uri> uries = new ArraySet<>();
if (isImage(mimeType)) {
uries.add(getImageUriFromFile(filePath, context));
} else {
uries.add(getVideoUriFromFile(filePath, context));
}
if (targetFolder.getPath().contains(Environment.DIRECTORY_PICTURES)) {
relativePath = Environment.DIRECTORY_PICTURES + File.separator + folderName;
} else if (targetFolder.getPath().contains(Environment.DIRECTORY_DCIM)) {
relativePath = Environment.DIRECTORY_DCIM + File.separator + folderName;
} else {
relativePath = Environment.DIRECTORY_PICTURES + File.separator + folderName;
}
try {
if (isImage(new File(filePath).getName().split("\\.")[1])) {
Bitmap bitmap = getBitmap(filePath);
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, newName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath);
Uri imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
fos = (FileOutputStream) contentResolver.openOutputStream(imageUri);
if (!bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos)) {
fos.flush();
}
return getPath(imageUri, context);
} else {
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, newName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/" + mimeType);
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath);
Uri imageUri = contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues);
fos = (FileOutputStream) contentResolver.openOutputStream(imageUri);
FileInputStream inStream = new FileInputStream(filePath);
FileChannel inChannel = inStream.getChannel();
FileChannel outChannel = fos.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
inStream.close();
fos.close();
return getPath(imageUri, context);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
and i called this method inside thread like below.
i called this method from thread because i m doing another operation on copied file
new Thread(() -> StorageUtils.copyFileOnAboveQ(
file1.getPath(),
file2.getName().split("\\.")[0],
file2.getParentFile(), context)).start();
code is working fine in many devices but in some device it create blank image

Why Captured images are not showing up in Samsung S21 (Android 11)

In our app, There is a camera photo capture feature and its capture images successfully and saved in External storage(/storage/emulated/0/DCIM/Camera/Appname/foldername). But its not showing up in Gallery.
Code we use to save the captured images;
private void saveToPublicStorage(Bitmap bitmap,File file) {
FileOutputStream out = null;
try {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
out = getFOSForPublicCameraDirectory(file.getName());
} else {
out = new FileOutputStream(file);
}
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (IOException e) {
ExceptionLogger.logException(e);
}
private FileOutputStream getFOSForPublicCameraDirectory(String fileName) {
FileOutputStream fos = null;
ContentResolver contentResolver = getContentResolver();
Uri imageUri = getURIForPublicCameraDirectory(fileName);
try {
fos = (FileOutputStream) contentResolver.openOutputStream(imageUri);
} catch (Exception e) {
ExceptionLogger.logException(e);
}
return fos;
}
private Uri getURIForPublicCameraDirectory(String fileName) {
ContentResolver contentResolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "image/png");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM + File.separator + "Camera" + File.separator + "Folder1" + File.separator + "Folder2");
return contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
}
Also this same piece of code working in Samsung S20(Android 11).The problem is only with S20.
I have followed https://www.samsung.com/us/support/troubleshooting/TSG01001310/ and checked all the given scenarios and nothing helped.

How to set ringtone in Android, using ringtone manager?

I am using the following code, but it doesn't seem to change the ringtone. What am I doing wrong, or is there an easier way to set an mp3 to ringtone? I have a uri that parses the location, and I call the following function. I know the uri is correct because it functions correctly with a file share method I have.
private void setRingtone(Uri uri) {
AssetFileDescriptor openAssetFileDescriptor;
((AudioManager) getActivity().getSystemService(AUDIO_SERVICE)).setRingerMode(2);
File file = new File(Environment.getExternalStorageDirectory() + "/appkeeda", mp3s[position]);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
ContentResolver contentResolver = getActivity().getContentResolver();
try {
openAssetFileDescriptor = contentResolver.openAssetFileDescriptor(uri, "r");
} catch (FileNotFoundException e2) {
openAssetFileDescriptor = null;
}
try {
byte[] bArr = new byte[1024];
FileInputStream createInputStream = openAssetFileDescriptor.createInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(file);
for (int read = createInputStream.read(bArr); read != -1; read = createInputStream.read(bArr)) {
fileOutputStream.write(bArr, 0, read);
}
fileOutputStream.close();
} catch (IOException e3) {
e3.printStackTrace();
}
ContentValues contentValues = new ContentValues();
contentValues.put("_data", file.getAbsolutePath());
contentValues.put("title", "nkDroid ringtone");
contentValues.put("mime_type", "audio/mp3");
contentValues.put("_size", Long.valueOf(file.length()));
contentValues.put("artist", Integer.valueOf(R.string.app_name));
contentValues.put("is_ringtone", Boolean.valueOf(true));
contentValues.put("is_notification", Boolean.valueOf(false));
contentValues.put("is_alarm", Boolean.valueOf(false));
contentValues.put("is_music", Boolean.valueOf(false));
try {
//Toast.makeText(this, new StringBuilder().append("Ringtone set successfully"), Toast.LENGTH_LONG).show();
RingtoneManager.setActualDefaultRingtoneUri(getActivity().getBaseContext(), 1, contentResolver.insert(MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath()), contentValues));
} catch (Throwable th) {
//Toast.makeText(this, new StringBuilder().append("Ringtone feature is not working"), Toast.LENGTH_LONG).show();
}
}
Solution: This tutorial worked for me: http://blog.nkdroidsolutions.com/set-default-ringtone-raw-folder-programmatically-android/

android: saving files to specific folder for later retrieval

I am working on a drawing part, and have written the following code to save the image to the designated camera folder. However, I would rather like to create a new folder using the app name and save the image to the folder. How could that be made?
I would also like to later on retrieve the image files from that specific folder too.
Thanks!
Current code:
String fileName = "ABC";
// create a ContentValues and configure new image's data
ContentValues values = new ContentValues();
values.put(Images.Media.TITLE, fileName);
values.put(Images.Media.DATE_ADDED, System.currentTimeMillis());
values.put(Images.Media.MIME_TYPE, "image/jpg");
// get a Uri for the location to save the file
Uri uri = getContext().getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
try
{
OutputStream outStream = getContext().getContentResolver().openOutputStream(uri);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush(); // empty the buffer
outStream.close(); // close the stream
Try this it might help you.
public void saveImageToExternalStorage(Bitmap image) {
String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/directoryName";
try
{
File dir = new File(fullPath);
if (!dir.exists()) {
dir.mkdirs();
}
OutputStream fOut = null;
File file = new File(fullPath, "image.png");
if(file.exists())
file.delete();
file.createNewFile();
fOut = new FileOutputStream(file);
// 100 means no compression, the lower you go, the stronger the compression
image.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
}
catch (Exception e)
{
Log.e("saveToExternalStorage()", e.getMessage());
}
}
This Method works after so many try.
private String getFilename() {
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".mp3");
}

Android - set file name while saving image using Bitmap.compress

I'm saving an image onto sd card using the following code:
ContentValues values = new ContentValues();
values.put(MediaColumns.TITLE, mFileName);
values.put(MediaColumns.DATE_ADDED, System.currentTimeMillis());
values.put(MediaColumns.MIME_TYPE, "image/jpeg");
resultImageUri = ApplyEffects.this.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
try{
OutputStream out = ApplyEffects.this.getContentResolver().openOutputStream(resultImageUri);
mResultBitmaps[positionSelected].compress(Bitmap.CompressFormat.JPEG, 70, out);
out.flush();
out.close();
} catch(FileNotFoundException e){
e.printStackTrace();
} catch(Exception e){
e.printStackTrace();
}
But the image file name is always the System.currentTimeMills. How do I specify a name for it?
Here's my complete working code based on dipu's suggestion:
private Uri saveToFileAndUri() throws Exception{
long currentTime = System.currentTimeMillis();
String fileName = "MY_APP_" + currentTime+".jpg";
File extBaseDir = Environment.getExternalStorageDirectory();
File file = new File(extBaseDir.getAbsoluteFile()+"/MY_DIRECTORY");
if(!file.exists()){
if(!file.mkdirs()){
throw new Exception("Could not create directories, "+file.getAbsolutePath());
}
}
String filePath = file.getAbsolutePath()+"/"+fileName;
FileOutputStream out = new FileOutputStream(filePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, JPEG_QUALITY, out); //control the jpeg quality
out.flush();
out.close();
long size = new File(filePath).length();
ContentValues values = new ContentValues(6);
values.put(Images.Media.TITLE, fileName);
// That filename is what will be handed to Gmail when a user shares a
// photo. Gmail gets the name of the picture attachment from the
// "DISPLAY_NAME" field.
values.put(Images.Media.DISPLAY_NAME, fileName);
values.put(Images.Media.DATE_ADDED, currentTime);
values.put(Images.Media.MIME_TYPE, "image/jpeg");
values.put(Images.Media.ORIENTATION, 0);
values.put(Images.Media.DATA, filePath);
values.put(Images.Media.SIZE, size);
return ThisActivity.this.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
}
Try the following approach.
String fileName = "my_file.jpg";
File extBaseDir = Environment.getExternalStorageDirectory();
File file = new File(extBaseDir.getAbsoluteFile() + "APP_NAME");
if(!file.exists()){
if(!file.mkdirs()){
throw new Exception("Could not create directories, "+file.getAbsolutePath());
}
}
String filePath = file.getAbsolutePath()+"/"+fileName;
FileOutputStream out = new FileOutputStream(filePath);
//now write your bytes into this outputstream.

Categories

Resources