FileNotFound Exception while converting Firebase uri into bitmap? - android

i'm developing an app in which i'm retrieving a profile image from firebase but while conversion into bitmap format ,it's getting FileNotFoundException so any solution for this ?
databaseReference.child(uid).child("Profile_image").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String url= (String) dataSnapshot.getValue();
Uri uri;
try {
uri = Uri.parse(url);
InputStream inputStream =getContentResolver().openInputStream(uri); //this line
Bitmap bitamp = BitmapFactory.decodeStream(inputStream);
String bitmap=saveToInternalStorage(bitamp);
loadImageFromStorage(bitmap);
}catch (NullPointerException e){
} catch (FileNotFoundException e) {
Toast.makeText(MainActivity.this, "File not Found", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

This is meant to be a comment, but I don't have a high enough reputation to comment yet:
If your String url is the http url of Firebase storage, then Uri.parse(url) is not going to get you the correct Uri. From my experience, you can only be confident that Uri.parse(String stringUri) will return the correct Uri if the string came from Uri's toString() method.
Receiving an invalid Uri would cause getContentResolver().openInputStream(uri) crash as you say it is.
With that being said, if you're storing the Uri as a String in your database, then you need to get that String value and use Uri.parse(String stringUri) on it as opposed to calling that method on the http url.

i think you have to use Picasso direcltly
Picasso.get().load(uri).into(target);

Related

Why can't this retieve the download URL of an image on Firebase Storage?

I am trying to retrieve an image from firebase storage for an android app by getting the download url of the image I want to retrieve in the onSuccessListener of the putImage call I used to upload the image in the first place. I am saving the download URL in a field variable but the issue is that the field variable is not being updated. I used toast to print out the value of the url field variable after my attempt in setting it equal to the download URl of the image I want to retrieve, but it remains unchanged. I'm not sure why this is the case so I would appreciate any help in resolving this.
//field variable that s meant to hold download url for the image I want to retrieve
String url = "never changed"
...
final String imageKey = UUID.randomUUID().toString();
StorageReference profileref = storageReference.child("contactProfiles/" + imageKey);
profileref.putFile(imageUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Task<Uri> task = taskSnapshot.getMetadata().getReference().getDownloadUrl();
task.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
//setting url equal to url of the image I want to retrieve
url = uri.toString();
}
});
Toast.makeText(ContactCreation.this, "Successful Profile Picture Upload", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(ContactCreation.this, "Failed to Upload Profile Picture", Toast.LENGTH_SHORT).show();
}
});
//Seeing if the url changed or not
Toast.makeText(ContactCreation.this, url, Toast.LENGTH_SHORT).show();
The call to getDownloadURL makes a call to the server, and thus is executed asynchronously. This means that right now in your code, the Toast.makeText(ContactCreation.this, url runs before the url = uri.toString() ever runs, which explains why it logs no value.
The solution is always the same: any code that needs the value, needs to be inside the onSuccess that is called with the value, or it needs to be called from there.
So:
task.addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
url = uri.toString();
Toast.makeText(ContactCreation.this, url, Toast.LENGTH_SHORT).show();
}
});
If you're new to such asynchronous behavior, I recommend reading some more about it. For example with:
URL generated by Firebase Storage does not allow access to the file, which shows some chaining of Task listeners.
How to get the download url from Firebase Storage?
Hello, I have problem to upload my image to my firebase storage

Fresco add Bitmap to Cache programmatically

I am uploading an image to my server and once uploaded my server responds with the new URI for it (can be the same URL as the old one), I want to remove the old cached image and insert the new one for the new URI.
I try to accomplish this by doing:
// Retrofit2 onResponse
String newImageUri = response.body().getUri();
String oldImageUri = Preferences.getUser().getImageUrl();
// Remove old image from cache
Fresco.getImagePipeline().evictFromCache(Uri.parse(oldImageUri));
Fresco.getImagePipeline().evictFromDiskCache(Uri.parse(oldImageUri));
Fresco.getImagePipeline().evictFromMemoryCache(Uri.parse(oldImageUri));
Fresco.getImagePipelineFactory().getMainFileCache().remove(new SimpleCacheKey(oldImageUri));
// Insert new image at new URI
try {
Fresco.getImagePipelineFactory().getMainFileCache().insert(new SimpleCacheKey(newImageUri), new WriterCallback() {
#Override
public void write(OutputStream os) throws IOException {
os.write(imageData); // byte[] or the new Bitmap
}
});
}
catch (Exception e) {
e.printStackTrace();
}
uriProfileImage.setImageURI(newImageUri);
There are no exceptions but I still only see the old image.
I solved it, it was an error with the Uri format for the new Uri...
Uri uri = Uri.parse("http://frescolib.org/static/fresco-logo.png");
Fresco.getImagePipelineFactory().getMainDiskStorageCache().remove(new CacheKey(uri.toString()));
Fresco.getImagePipelineFactory().getSmallImageDiskStorageCache().remove(new CacheKey(uri.toString()));

How can I convert a file Uri scheme into content Uri scheme?

In android, when you get the uri from the gallery, it's value will be start with content://blahblahblah.blahblah.format, but if you get the uri from your phone's camera, it will be starting with file:///
Below is what I want to do:
private File uriToBitmap(Uri uri, int maxSize) throws FileNotFoundException {
try {
imageStream = getContentResolver().openInputStream(uri);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Bitmap claimBitmap = BitmapFactory.decodeStream(imageStream);
}
In this method I would like to pass a file type uri and use getContentResolver() function, but unfortunately the claimBitmap is a null, does that means the getContentResolver() method doens't accept the file type uri? Please help.
No, file scheme is supported by ContentResolver, if the uri which scheme is not support, this method will throw a FileNotFoundException. Please check the
public final InputStream openInputStream(Uri uri)
throws FileNotFoundException {
String scheme = uri.getScheme();
if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
// Note: left here to avoid breaking compatibility. May be removed
// with sufficient testing.
OpenResourceIdResult r = getResourceId(uri);
try {
InputStream stream = r.r.openRawResource(r.id);
return stream;
} catch (Resources.NotFoundException ex) {
throw new FileNotFoundException("Resource does not exist: " + uri);
}
} else if (SCHEME_FILE.equals(scheme)) {
// Note: left here to avoid breaking compatibility. May be removed
// with sufficient testing.
return new FileInputStream(uri.getPath());
} else {
AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r", null);
try {
return fd != null ? fd.createInputStream() : null;
} catch (IOException e) {
throw new FileNotFoundException("Unable to create stream");
}
}
}
this is the source code of ContentResolver, hope this can help you
Follow this URL . It will helps you
If you stored as in local drive.
String filePath = null;
Uri _uri = data.getData();
Log.d("","URI = "+_uri);
if(_uri!=null&&"content".equals(_uri.getScheme())){
Cursor cursor=this.getContentResolver().query(_uri,new String[]{android.provider.MediaStore.Images.ImageColumns.DATA},null,null,null);
cursor.moveToFirst();
filePath=cursor.getString(0);
cursor.close();
}else
{
filePath=_uri.getPath();
}

Android Unable to get path for Cloud image from Photos Application

I have tried to getting absolute path and I got the success too but when I try with the cloud images to get that image and used in application file is not find and getting null. I am implementing to receive files from another app like when you select image from Photos, Gallery or File application and share image by using my application.
Here I got the Uri content://com.google.android.apps.photos.contentprovider/0/1/mediaKey%3A%2FAF1QipOFLMMm8uXbeDMQk-P4S0Hx1dlmRDMr4SFABfVi/ACTUAL/61235243
When I select image which is on Google Photos cloud and it'll be first download and then given me above URI. From that point I directly execute in query and getting the name of the file "Filename.png" in all the columns but not the full path.
When same things I tried with the Facebook to share it will display in compose exact which I want to share.
I have also refer this from this link to get the path from Photos application, but the problem is with cloud image.
Anybody have solution or suggestion will be appriciated.
Try getting the Bitmap first:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
Uri selectedImage = data.getData();
InputStream inputStreamBitmap = null;
Bitmap imageBitmap = null;
try {
inputStreamBitmap = getContentResolver().openInputStream(inputStreamBitmap);
imageBitmap = BitmapFactory.decodeStream(inputBitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (inputStreamBitmap != null) {
inputStreamBitmap.close();
}
} catch (IOException ignored) {
}
}
if (imageBitmap != null) {
processImageBitmap(imageBitmap);
} else {
Log.e("ImageIntent", "Error: couldn't open the specified image.");
}
}
}
Then you could save the Bitmap to a temp file if you want to.
More details here.

How to share image that is downloaded and cached with Volley?

In my app I download images from server using Volley and its ImageLoader (with BitmapLruCache). I want to create a share option, researched a little bit, and found that share intent can only share localy stored images. First question, is this right?
Second, if that is right, what should I do? Should I download image again and save it to local storage? Or put it in MediaStore? Or I can pull image from cache and share cached version? What are the best practices?
Any suggestion is welcome, or code snippet.
What I did is made another request for getting the image, and added an ImageListener which provides ImageContainer containing bitmap.
MyApplication.getImageLoader(activity).get(imageURL, new ImageListener() {
#Override
public void onErrorResponse(VolleyError error) {}
#Override
public void onResponse(ImageContainer response, boolean isImmediate) {
Bitmap mBitmap = response.getBitmap();
ContentValues image = new ContentValues();
image.put(Media.MIME_TYPE, "image/jpg");
Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, image);
try {
OutputStream out = getContentResolver().openOutputStream(uri);
boolean success = mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.close();
if (!success) {
} else {
imageUri = uri;
mShareActionProvider = (ShareActionProvider) item.getActionProvider();
// Create the share Intent
Intent shareIntent = ShareCompat.IntentBuilder.from(activity).setType("image/jpg").setText(shareText).getIntent();
shareIntent.putExtra(Intent.EXTRA_STREAM, imageUri);
mShareActionProvider.setShareIntent(shareIntent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
As image is already downloaded and cached (using BitmapLRU cache and ImageLoader), this new request gives me bitmap from cache so no new network data is made.

Categories

Resources