This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I have already seen many questions in stackoverflow but none of them able to solve my problem. Here is my code.There is no error in code but app is crashing at runtime giving this error in Logcat - Attempt to invoke virtual method 'android.graphics.Bitmap android.graphics.drawable.BitmapDrawable.getBitmap()' on a null object reference
public void SaveImageInFirebase(){
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl("gs://opiniondonkey-9c20e.appspot.com");
SimpleDateFormat df = new SimpleDateFormat("ddMMyyHHmmss");
Date dataobj = new Date();
String imagePath = df.format(dataobj) + ".jpg";
StorageReference ImageRef = storageRef.child("images/" + imagePath);
mPic.setDrawingCacheEnabled(true);
mPic.buildDrawingCache();
Drawable drawable = mPic.getDrawable();
//TODO:: error in below line.
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG,100, baos);
byte[] data = baos.toByteArray();
UploadTask uploadTask = ImageRef.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getApplicationContext(),"Welcome To Opinion Donkey",Toast.LENGTH_LONG).show();
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Task<Uri> downloadUrl = taskSnapshot.getStorage().getDownloadUrl();
myRef.child("Users").child(name).child("ProfileUrl").setValue(downloadUrl);
}
});
}
I want when someone logins again then google id picture should not overrides over my user picture.
May be mPic.getDrawable(); is returning null. so drawable is null and you are accessing it by ((BitmapDrawable)drawable).getBitmap();
It might be because Picasso loads image in ImageView async and you are trying to access that before it is loaded/downloaded.
so mPic.getDrawable() returns null.
Add check before accessing if(drawable != null) there.
Also, this needs to be called only after Picasso done with it's loading. so you can add listener there and access image only after it is done loading.
Related
This question already has answers here:
How to get URL from Firebase Storage getDownloadURL
(13 answers)
Closed 2 years ago.
I'm trying to get the download url of the image uploaded to firebase database. But Task Uri imageURL = storageReference.getDownloadUrl(); doesn't gives the actual download URL of an image stored in the firebase storage i.e it gives this - com.google.android.gms.tasks.zzu#27da5837
getdownloadUrl() doesn't work in case of as it is deprecated:
Uri imageUrl = storagereference.getdownloadUrl(); //Gives error
please see the code here:
final StorageReference storageReference = FirebaseStorage.getInstance().getReference().child("images").child(imageName);
final UploadTask uploadTask = storageReference.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
Toast.makeText(CreateSnapActivity.this, "Upload Failed", Toast.LENGTH_SHORT).show();
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(final UploadTask.TaskSnapshot taskSnapshot) {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, etc.
//Task<Uri> imageURL = storageReference.getDownloadUrl();
//Log.i("URL", imageURL.toString()); // gives this url - com.google.android.gms.tasks.zzu#27da5837 which is not correct
Task<Uri> urlTask = storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
Log.i("Url", String.valueOf(uri));
imageUrl = uri.toString(); //Gives the correct url but it cannot store this uri value outside this function i.e for Intent shown below outside this func.
}
});
Toast.makeText(CreateSnapActivity.this, "Uploaded", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(CreateSnapActivity.this, ChooseUserActivity.class);
intent.putExtra("imageName", imageName);
intent.putExtra("imageURL", imageUrl);
intent.putExtra("message", captionEditText.getText().toString());
startActivity(intent);
}
});
Calling getDownloadUrl() starts an asynchronous operation, which may take some time to complete. Because of this, your main code continues to run while the download URL is being retrieved to prevent blocking the user. Then when the download URL is available, your onSuccess gets called. Because of this, by the time your intent.putExtra("imageURL", imageUrl) now runs, the imageUrl = uri.toString() hasn't run yet.
To see that this indeed true, I recommend putting some logging in the code to just show the flow, or running it in a debugger and setting breakpoints on the lines I indicated above.
To fix it, any code that needs the download URL, needs to be inside the onSuccess, or be called from there. This applies not just here, but to all code that runs asynchronously, which includes most modern cloud APIs. So I recommend spending some time now studying this behavior, so that you're more comfortable with it going forward.
In your code:
final StorageReference storageReference = FirebaseStorage.getInstance().getReference().child("images").child(imageName);
final UploadTask uploadTask = storageReference.putBytes(data);
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Toast.makeText(CreateSnapActivity.this, "Upload Failed", Toast.LENGTH_SHORT).show();
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(final UploadTask.TaskSnapshot taskSnapshot) {
Task<Uri> urlTask = storageReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
imageUrl = uri.toString();
Toast.makeText(CreateSnapActivity.this, "Uploaded", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(CreateSnapActivity.this, ChooseUserActivity.class);
intent.putExtra("imageName", imageName);
intent.putExtra("imageURL", imageUrl);
intent.putExtra("message", captionEditText.getText().toString());
startActivity(intent);
}
});
}
});
Also see:
URL generated by Firebase Storage does not allow access to the file
How to get download url for firebase storage and update firestore document?
imageURL is a task.You are trying to print a task. not task's result. please try this code:
Task<Uri> imageURL = storageReference.getDownloadUrl();
Log.i("URL", imageURL.toString());
Log.i("URL", imageURL.result.toString());
This question already has answers here:
How to display image from URL on Android
(10 answers)
Closed 4 years ago.
Heyho,
currently im working on my Firebase Database (android sdk). I managed to upload the image to the storage and save the url in my database (under the user ID).
Now im really out of ideas how to display the image from the database into a imageView.
Probably you already understand that im trying create some type of "profile picture".
Btw. is would be really nice if someone can help me without using Glide. If Glide is needed i will get Glide then instead.
Thank you all for reading my question and helping me!
Database Image
Firstly you can put an image using an url by using:
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
If you use the Firebase storage why don't you just download the file directly from there?
StorageReference mStorageRef = FirebaseStorage.getInstance().getReference();
StorageReference riversRef = mStorageRef.child("images/name.jpg");
File localFile = null;
try {
localFile = File.createTempFile("images", "jpg");
} catch(IOException e) {
e.printStackTrace();
}
riversRef.getFile(localFile)
.addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
// Successfully downloaded data to local file
// ...
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle failed download
// ...
}
});
If you do need to use the url then you will need to use an AsyncTask to get the image.
I have the following code snippet in my onSuccessListener() to save the download URL of the file I uploaded.
DatabaseReference downloadURLRef = rootRef.child("Child").child(value);
Uri downloadUrl = taskSnapshot.getDownloadUrl();
downloadURLRef.setValue(downloadUrl);
I get this error:
Error TaskSnapshot - Method should only be accessed within private scope while using android studio 2.3.
When I followed this post and suppressed the warning, my app crashes on upload, and the upload fails. Here's the error for that.
What gives? This is straight from the Firebase documentation too.
EDIT: Upload code.
storage = FirebaseStorage.getInstance();
storageRef = storage.getReference(date + "/" + filename);
uploadTask = storageRef.putFile(Uri.fromFile(file));
// Register observers to listen for when the download is done or if it fails
uploadTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle unsuccessful uploads
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// TODO: Fix this bullshit
DatabaseReference downloadURLRef = rootRef.child("Child").child(value);
Uri downloadUrl = taskSnapshot.getDownloadUrl();
downloadURLRef.setValue(downloadUrl);
}
});
Save downloadUrl as a string, not a Uri object:
DatabaseReference downloadURLRef = rootRef.child("Child").child(value);
Uri downloadUrl = taskSnapshot.getDownloadUrl();
downloadURLRef.setValue(downloadUrl.toString()); // <= CHANGE
I'm trying to get an image URI that is stored in Firebase storage, in order to process it using another method.
I'm using the following:
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl(this.getString(R.string.storage_path));
Uri uri = storageRef.child("groups/pizza.png").getDownloadUrl().getResult();
and getting an error "java.lang.IllegalStateException: Task is not yet complete"
You can get the download URL for a file with:
storageRef.child("groups/pizza.png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
// TODO: handle uri
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
}
});
See the Firebase documentation for downloading data via a URL.
Hello having trouble to fix this issue.
I already have a imageReader.close called inside the ImageAvailable callback but still having the error:
java.lang.IllegalStateException: maxImages (1) has already been acquired, call #close before acquiring more.
Code I have is here:
private ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener()
{
#Override
public void onImageAvailable(ImageReader reader) {
Image img = mReader.acquireLatestImage();
mReader.close();
}
};
ps. I also use the argument reader as well but not seem to solve the problem
Ok I have solved my problem. I need to close the img object not the ImageReader.
private ImageReader.OnImageAvailableListener imageAvailableListener = new ImageReader.OnImageAvailableListener() {
#Override
public void onImageAvailable(ImageReader reader) {
String status = Environment.getExternalStorageState();
if (!status.equals(Environment.MEDIA_MOUNTED)) {
Toast.makeText(getApplicationContext(), "your SD card is not available", Toast.LENGTH_SHORT).show();
return;
}
Image image = reader.acquireNextImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] data = new byte[buffer.remaining()];
buffer.get(data);
image.close();//after you use the image's content ,you can close it
String filePath = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";
String picturePath = System.currentTimeMillis() + ".jpg";
imgFile = new File(filePath, picturePath);
Uri uri = Uri.fromFile(imgFile);
try {//Store to folder
FileOutputStream fileOutputStream = new FileOutputStream(imgFile);
fileOutputStream.write(data);
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
startEditPictureActivity(uri, imgFile);
}
};
close() needs to be called on the Image object that acquireLatestImage() returns.
So, going from the OP's implementation of onImageAvailable() in his sample, just adding .close() after the acquireLatestImage() should do the trick.
Like so:
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage().close(); // Note the added `close()` call.
}
I should also add that the image will no longer be usable after you call close() on it (see docs).
So the solution I've mentioned above will get you rid off the exception OP mentioned, but you also won't be able to do anything with the image. This is obviously easy to fix by first doing whatever you want with the image and only then calling close() on it.