I can't add the image from firebase to the navigation drawer I'm getting the url of the image after the navigation drawer has been created because of the async method of getting url from firebase the method to get the url is called after the navigation drawer has been created hence can't update it.
I'm getting the url of the image after the navigation drawer has been created because of the async method of getting url from firebase the method to get the url is called after the navigation drawer has been created hence can't update it. I have tried to create a class and method that does that but then they are called after the onCreate method has executed of which thats where im trying to get the image url
if (profileImageUrlRef != null)
{
profileImageUrlRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri)
{
urlImage=uri.toString();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
}
});
}
DrawerImageLoader.init(new AbstractDrawerImageLoader() {
@Override
public void set(ImageView imageView, Uri uri, Drawable placeholder, String tag) {
Glide.with(imageView.getContext()).load(uri).placeholder(placeholder).into(imageView);
}
@Override
public void cancel(ImageView imageView) {
Glide.with(Client_Services.this).clear(imageView);
}
@Override
public Drawable placeholder(Context ctx, String tag) {
//define different placeholders for different imageView targets
//default tags are accessible via the DrawerImageLoader.Tags
//custom ones can be checked via string. see the CustomUrlBasePrimaryDrawerItem LINE 111
if (DrawerImageLoader.Tags.PROFILE.name().equals(tag)) {
return DrawerUIUtils.getPlaceHolder(ctx);
} else if (DrawerImageLoader.Tags.ACCOUNT_HEADER.name().equals(tag)) {
return new IconicsDrawable(ctx).iconText(" ").backgroundColorRes(com.mikepenz.materialdrawer.R.color.primary).sizeDp(56);
} else if ("customUrlItem".equals(tag)) {
return new IconicsDrawable(ctx).iconText(" ").backgroundColorRes(R.color.md_red_500).sizeDp(56);
}
//we use the default one for
//DrawerImageLoader.Tags.PROFILE_DRAWER_ITEM.name()
return super.placeholder(ctx, tag);
}
});
final AccountHeader headerResult = new AccountHeaderBuilder()
.withActivity(this)
.withHeaderBackground(R.drawable.background)
.addProfiles(
new ProfileDrawerItem().withName("Ceo AtRalk").withEmail("info@atralk.co.zam").withIcon(urlImage)
)
.withOnAccountHeaderListener(new AccountHeader.OnAccountHeaderListener() {
@Override
public boolean onProfileChanged(View view, IProfile profile, boolean currentProfile) {
return false;
}
})
.build();
Im expecting the urlImage variable to be populated with the url when its passed to withIcon method
I've once wrote an AsyncTask
which caches the profile image to SD card:
/**
* AsyncTask: Profile Image
* @author Martin Zeitler
**/
public class ProfileImageTask extends AsyncTask<String, Void, Uri> {
private static final String LOG_TAG = ProfileImageTask.class.getSimpleName();
private static final boolean mDebug = BuildConfig.DEBUG;
private String fileName = "photo.jpg";
private boolean enforce = false;
private String sdPath;
private String url;
/** {@link IProfileImageTask} listener */
private IProfileImageTask listener;
/** Constructor */
@RequiresPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
public ProfileImageTask(@NonNull Context context, @NonNull String url, @NonNull IProfileImageTask listener) {
this.sdPath = context.getExternalFilesDir(context.getResources().getString(R.string.app_name)) + "/";
this.listener = listener;
this.url = url;
}
@Override
protected void onPreExecute() {
/* setup destination directory */
File directory = new File(this.sdPath + Constants.FILESYSTEM_DIRECTORY_IMAGES);
if (! directory.exists()) {
//noinspection ResultOfMethodCallIgnored
directory.mkdirs();
}
/* setup file name */
String[] parts = this.url.split("/");
this.fileName = parts[parts.length - 1];
}
@Override
protected Uri doInBackground(String... arguments) {
File file = new File(this.sdPath + Constants.FILESYSTEM_DIRECTORY_IMAGES, this.fileName);
if(file.exists() && this.enforce) {
if(mDebug) {
Log.d(LOG_TAG, "delete profile image: " + file.getPath() + ", size: " + file.length() + " bytes.");
}
//noinspection ResultOfMethodCallIgnored
file.delete();
}
if (! file.exists()) {
try {
URLConnection conn = new URL(this.url).openConnection();
conn.connect();
InputStream in = conn.getInputStream();
FileOutputStream out = new FileOutputStream(file);
byte[] b = new byte[1024]; int c;
while ((c = in.read(b)) != -1) {out.write(b, 0, c);}
out.close();
in.close();
} catch (IOException e) {
if(mDebug) {Log.e(LOG_TAG, "" + e.getMessage());}
} finally {
if(mDebug) {
Log.d(LOG_TAG, "new cached profile image: " + file.getPath() + ", size: " + file.length() + " bytes.");
}
}
} else if(mDebug) {
Log.d(LOG_TAG, "existing profile image: " + file.getPath() + ", size: " + file.length() + " bytes.");
}
return Uri.fromFile(file);
}
@Override
protected void onPostExecute(Uri uri) {
if (listener != null && uri != null) {
this.listener.OnImageAvailable(uri);
}
}
}
Usage example:
if (this.currentUser != null && this.currentUser.getPhotoUrl() != null) {
new ProfileImageTask(this, this.currentUser.getPhotoUrl(), this).execute();
}
This is the callback interface
, which sets the image when the task is done:
public interface IProfileImageTask {
/**
* indicates that the operation has finished.
* @param localUri
**/
void OnImageAvailable(@NonNull Uri localUri);
}
And it's implementation:
@Override
public void OnImageAvailable(@NonNull Uri uri) {
/* the Main {@link DrawerLayout} */
this.mDrawerLayout = this.findViewById(resIdLayout);
if (! this.mDrawerLayout.isInEditMode()) {
/* the {@link NavigationView} Drawer Menu */
this.mNavigationDrawer = this.findViewById(resIdDrawer);
/* the {@link NavigationView} Drawer Header */
View header = this.mNavigationDrawer.getHeaderView(0);
AppCompatImageView photoUrl = header.findViewById(R.id.photoUrl);
/* setting the photo-url */
if (this.currentUser != null && this.currentUser.getPhotoUrl() != null) {
photoUrl.setImageURI(uri);
}
}
}