Cant save image to gallery - android

I am trying to save bitmap as an image to the phone storage with MediaStore like this:
MediaStore.Images.Media.insertImage(contentResolver, bitmap, "title" , "description")
The image was not saved inside the device storage, I have checked on both emulator and physical devices.
What I did so far:
Checked that the bitmap that I am passing is my wanted bitmap:
For this, I have checked its value with the help of the debugger like this:
1) Put a breakpoint on the line that supposed to save the image and check what bitmap I am passing, the bitmap was the same bitmap that I wanted to save:
2) This is how the bitmap looks like:
Made sure that the permission for writing files to the external storage (the line below) was granted from the user
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Made sure that the image was not saved at the end of the gallery or in any other place inside the device storage
I know that I can probably save the image without using MediaStore as mentioned in this thread but I want to know what I am doing wrong here and why I can't save the bitmap as an image inside the device storage.

I tried this but not worked for me too. So I used Android Download Manager, which is simple and easy ;-)
Here is the code
/*
This method can be used to download an image from the internet using a url in Android. This use Android Download Manager to
download the file and added it to the Gallery. Downloaded image will be saved to "Pictures"
Folder in your internal storage
*/
private void downloadImageNew(String filename, String downloadUrlOfImage){
try{
DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadUri = Uri.parse(downloadUrlOfImage);
DownloadManager.Request request = new DownloadManager.Request(downloadUri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false)
.setTitle(filename)
.setMimeType("image/jpeg") // Your file type. You can use this code to download other file types also.
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES,File.separator + filename + ".jpg");
dm.enqueue(request);
Toast.makeText(this, "Image download started.", Toast.LENGTH_SHORT).show();
}catch (Exception e){
Toast.makeText(this, "Image download failed.", Toast.LENGTH_SHORT).show();
}
}

For some reason even after WRITE_EXTERNAL_STORAGE was granted, after looking a bit on the logs I have noticed that I am getting this error:
Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=11218, uid=10079 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
It looked weird to me because I have checked that this permission got granted before saving the image to the gallery.
What solved it for me was to delete the app and reinstall it again

Related

Flutter image-picker explicitly ask permission

Imagepicker package says
No configuration required - the plugin should work out of the box.
It is no longer required to add
android:requestLegacyExternalStorage="true" as an attribute to the
tag in AndroidManifest.xml, as image_picker has been
updated to make use of scoped storage.
reading images from gallery.
so I think I need to ask some permission from the user as playstore also says this
New package is just working and not asking for any permission.
What permissions I need to explicitly ask
And I don't want to save it on any external directory I just want to upload image to firebase storage
Edit: image picker is not asking any permission from the user is this wrong
Permission needed to read and write files in the android are.
These permission are required to be added to your AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
In your scenario, you don't need to do anything as this is already handled by the library
https://pub.dev/packages/image_picker
Above mentioned library doesn't save the image in external storage.
Note: Images and videos picked using the camera are saved to your
application's local cache, and should therefore be expected to only be
around temporarily. If you require your picked image to be stored
permanently, it is your responsibility to move it to a more permanent
location.
For more info you can refer to this link
https://guides.codepath.com/android/Accessing-the-Camera-and-Stored-Media#accessing-stored-media
Update : How image picking is handled internally in image_picker for Android
For Gallery pick it opens in inbuild file picker intent using ACTION_GET_CONTENT(about action get content)
When opening file using ACTION_GET_CONTENT - Because the user is involved in selecting the files or directories that your app can access, this mechanism doesn't require any system permissions. You can read more about when permission is needed and when not in google docs
Intent pickImageIntent = new Intent(Intent.ACTION_GET_CONTENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
pickImageIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}
pickImageIntent.setType("image/*");
activity.startActivityForResult(pickImageIntent, REQUEST_CODE_CHOOSE_MULTI_IMAGE_FROM_GALLERY);
and copies the result URI in temp file in cache directory and return the path
String extension = getImageExtension(context, uri);
inputStream = context.getContentResolver().openInputStream(uri);
file = File.createTempFile("image_picker", extension, context.getCacheDir());
file.deleteOnExit();
outputStream = new FileOutputStream(file);
if (inputStream != null) {
copy(inputStream, outputStream);
success = true;
}
For Camera library request the camera permission android.permission.CAMERA from the user and save the camera image in app cache directory.
private void handleCaptureImageResult(int resultCode) {
if (resultCode == Activity.RESULT_OK) {
fileUriResolver.getFullImagePath(
pendingCameraMediaUri != null
? pendingCameraMediaUri
: Uri.parse(cache.retrievePendingCameraMediaUriPath()),
new OnPathReadyListener() {
#Override
public void onPathReady(String path) {
handleImageResult(path, true);
}
});
return;
}
// User cancelled taking a picture.
finishWithSuccess(null);
}
This code is as per version image_picker: ^0.8.4+4 code present on their github page - image picker code
You’ll have to add the above-mentioned permissions to your AndroidManifest.xml file. That is still required to access user storage.

Loading images from internal memory to an imageview

How do I display images from the phone's internal storage in an ImageView on android?
No image is loaded using the following code on my phone running on Marshmallow.
String path = Environment.getExternalStorageDirectory()+ "/MyFolder/final_photo";
File imgFile = new File(path);
if (imgFile.exists()) {
imageView.setImageBitmap(decodeFile(imgFile));
}
Your path doesn't contain a String to an Actual Image!
Images end with .jpg, .png etc.
As you also said that your Phone is on Marshmallow, you should also Allow the Storage permissions to your App!

Load image from gallery doesn't works twice

I select an image from the gallery. Now I load it in a temp-file and can show it in a ImageView. Everything works fine.
Uri uri = data.getData();
File file = new File(uri+"");
String fileName = file.getName();
String filePath = file.getParent();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), uri);
//here come's the code to save the temp-file and so on
In the fileName and filePath I save the name and path for later use. Because if the user want to save the image I want to make a copy of them.
URI shown in the debugger: content:/media/external/images/media/12345
filePath: content:/media/external/images/media
fileName: 12345
If I want to save the image I use the fileName and filePath to build the URI and want to do the same like above. But it doesn't works. I get a FileNotFoundException "no content provider" from the MediaStore. Hmm - before I deleted the App for a fresh testing there comes "No such file or directory" and I thought I eliminate the "no content provider" Exception with the READ_EXTERNAL_STORAGE permission.
Uri uri = Uri.parse(filePath +"/"+ fileName);
Bitmap bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
Here I see also the correct URI in the debugger.
What is wrong?
I've set the permissions READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE in the AndroidManifest.
In the fileName and filePath I save the name and path for later use
A Uri is not a file, and yours most certainly is not a file.
What is wrong?
Your Uri has a content scheme. This is being served by a ContentProvider. You do not indicate where this Uri comes from, but I am going to guess that it is from ACTION_GET_DOCUMENT or something similar. In that case, like a Web URL that requires a working session, your access to the content identified by that Uri is short.
If you want to have longer-term access to the content, download it into your app, just as you would download content from a Web URL.

How to pick file from external storage using file picker in Android

I am having a problem with selecting image file from external storage using file picker in Android. This question is the consequence of this question - No such file or diectory error in image file upload using Retrofit in Android. What my problem is opening and reading file from external storage on activity result. I want to convert result URI into File.
I read a pdf file from download folder on activity result
Uri bookUri = data.getData();
if(bookUri!=null)
{
String filePath = bookUri.toString();//bookUri.toString()
String mime = app.getMimeType(filePath);
if(mime!=null && !mime.isEmpty() && (mime.toLowerCase()=="application/pdf" || mime.toLowerCase()=="application/txt" || mime.toLowerCase()=="application/text"))
{
bookFile = new File(bookUri.getPath());
ivBookFile.setImageResource(R.drawable.book_selected);
}
else{
Toast.makeText(getBaseContext(),"Unable to process file you have chosen.",Toast.LENGTH_SHORT).show();
}
}
As you can see I used new File(bookUri.getPath()); to convert into File. The above code works well. It is working. The problem is now I am trying to open an image file in DCIM/Camera folder on activity result.
This is the code I used
Uri selectedImageUri = data.getData();
if(selectedImageUri!=null)
{
try{
bmpCoverImage = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImageUri);
imageFile = new File(selectedImageUri.getPath());
if(bmpCoverImage!=null)
{
ivCoverImage.setImageBitmap(bmpCoverImage);
}
}
catch (IOException e)
{
Toast.makeText(getBaseContext(),"An error occurred with the file selected",Toast.LENGTH_SHORT).show();
}
}
As you can see I used new File(selectedImageUri.getPath()); like I did in reading pdf file. This time the code is not working. When I do operation with the file like in previous question, it gives me error.
I used this way also
imageFile = new File(Environment.getExternalStorageDirectory(),selectedImageUri.getPath());
I got the same error. How can I open the image file correctly from external storage? How can I convert the chosen file URI from external storage into File?
I am having a problem with selecting image file from external storage using file picker in Android
If you are referring to the code that you are using in this question, you are not "using file picker". You are using ACTION_GET_CONTENT, which has never been a "file picker", nor will it ever be a "file picker".
I want to convert result URI into File.
Usually, that is not necessary. But, if that is what you want to do:
use ContentResolver and openInputStream() to get an InputStream on the content represented by the Uri
create a FileOutputStream on your desired file
use Java I/O to copy the bytes from the InputStream into the FileOutputStream
The above code works well. It is working.
It works for the small number of devices that you tested, for the specific activities that the user chose to handle the ACTION_GET_CONTENT request. It will not work on most Android devices, and it will not work in most circumstances. The only time that code will work is if the Uri has a file scheme. Most of the time, it will not. Instead, it will have a content scheme, representing content supplied by a ContentProvider.
Please how can I open the image file correctly from external storage?
If you wish to continue using ACTION_GET_CONTENT, please understand that this has nothing to do with external storage specifically. You are not getting a file, on external storage or elsewhere. You are getting a Uri. This is akin to a URL, such as the URL for this Web page. Just as a URL does not necessarily point to a file on your hard drive, a Uri does not necessarily point to a file on the filesystem. Use a ContentResolver and DocumentFile to work with the Uri and the content that it identifies.
If you want to always get files on external storage (and nowhere else), then use an actual file picker library.

Android KitKat MediaScannerConnection not finding images saved to private app folder

I have an app which performs processing on an image selected by the user using from the gallery, after processing the modified image is then saved back to the original image's folder with a modified filename. On specific devices (mainly Samsungs) the new KitKat permission limitations severely limit where a non system app can write to e.g. external SD card or back to typical gallery locations.
The documentation advises to write to the private package specific folder obtained via
getExternalFilesDir(null)
This is fine and the image is saved correctly but then a subsequent call to
MediaScannerConnection.scanFile
fails to update the central media database correctly as the modified image doesn't appear in the gallery, even a reboot of the device which should force a full scan of all media doesn't trigger the image to be displayed.
In other words the following code doesn't work:
File appDir = MyActivity.this.getExternalFilesDir(null);
File file = new File(appDir, "new_image.jpeg");
// Process image and write file away...
MediaScannerConnection.scanFile(this, new String[] { file.getAbsolutePath() }, null, new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
Log.i(LOG_TAG, String.format("Scanned file: %s", path));
}
});
The onScanCompleted method fires but the gallery doesn't show the new image.
Has anyone seen this behaviour, does MediaScanner not scan 'private' app folders and if so how else do I get the gallery to detect and display the new image.
If you want images to be picked up by the gallery, you should put them in the proper public location. You can get the proper location using Environment.getExternalStoragePublicDirectory().

Categories

Resources