How to display contact photo in widget Android 4+? - android-widget

I am trying to show contact pictures on a home screen widget using RemoteViews.setImageViewUri() but nothing is shown.
I log the picture URI and it is correct, like content://com.android.contacts/contacts/293/photo
Here is my getViewAt method:
// Create and populate the View to display at the given index.
public RemoteViews getViewAt(int index) {
// Create a view to display at the required index.
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.item_layout);
// Populate the view with contact name.
rv.setTextViewText(R.id.name, items.get(index).getString("first_name"));
//check if we have a photo set
if (items.get(index).getString("photo_url") != null) {
Log.i("parsed uri", String.valueOf(Uri.parse(items.get(index).getString("photo_url"))));
rv.setImageViewUri(R.id.photo_url, Uri.parse(items.get(index).getString("photo_url")));
}
// Create an item-specific fill-in Intent that will populate
// the Pending Intent template created in the App Widget Provider (GridWidgetProvider).
Intent fillInIntent = new Intent();
fillInIntent.putExtra(Intent.EXTRA_TEXT, items.get(index));
rv.setOnClickFillInIntent(R.id.name, fillInIntent);
return rv;
}
It shows the contact names fine, but no pictures...
Any idea why? Thanks
Edit: xml for ImageView:
<ImageView
android:id="#+id/photo_url"
android:layout_width="match_parent"
android:layout_height="125dp"
android:layout_above="#id/name"
android:gravity="center"
android:background="#FFFF0000"
/>

Figured it out by myself, here is the code:
//check if we have a photo set
if (items.get(index).getString("photo_url") != null) {
rv.setImageViewUri(R.id.photo_url, Uri.parse(items.get(index).getString("photo_url")));
}
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, items.get(index).getLong("contact_id"));
InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(context.getContentResolver(), contactUri);
if (input != null) {
Log.i("input", String.valueOf(input));
image = BitmapFactory.decodeStream(input);
} else {
image = BitmapFactory.decodeResource(context.getResources(), R.drawable.default_dark);
}
rv.setImageViewBitmap(R.id.photo_url, image);

Related

Where to call an Action when user removes an uploaded image in GWTUpload?

I am using GWTUpload , the library is in here https://code.google.com/p/gwtupload/
The Example code at client side found on that website has this structure:
// Attach an image to the pictures viewer
private OnLoadPreloadedImageHandler showImage = new OnLoadPreloadedImageHandler() {
public void onLoad(PreloadedImage image) {
//showImageFlowPanel code solution 1
image.setWidth("75px");
showImageFlowPanel.add(image);
}
};
private IUploader.OnFinishUploaderHandler onFinishUploaderHandler = new IUploader.OnFinishUploaderHandler() {
public void onFinish(IUploader uploader) {
if (uploader.getStatus() == Status.SUCCESS) {
new PreloadedImage(uploader.fileUrl(), showImage);
UploadedInfo info = uploader.getServerInfo();
String headShotImageUrl="http://"+Window.Location.getHost()+"/" +"images/uploaded/"+info.message;
//headShotImage code solution 2
if(!"".equals(headShotImageUrl) && UriUtils.isSafeUri(headShotImageUrl)){
headShotImage.setUrl(UriUtils.fromString(headShotImageUrl));
}
}
}
};
The example uses showImageFlowPanel (solution 1) to store the image but I want to store the image inside headShotImage which take the url after user uploaded image successfully, see the headShotImage (solution 2) code above.
Ok, the headShotImage code work fine but I dont know how to remove it when users remove the image. If I use showImageFlowPanel as in the solution 1 then the program remove the image automatically for me and I do not need to do anything.
So my question is "Where to call an Action when user removes an uploaded image in GWTUpload?"
You have to use setOnCancelUploaderHandler. Take a look to this code took from the demo.
// When the user clicks a cancel button we get an event
uploader.addOnCancelUploadHandler (
new IUploader.OnCancelUploaderHandler() {
public void onCancel(IUploader uploader) {
for (String iname : uploader.getServerMessage().getUploadedFieldNames()) {
// loadedImages is an temporary table where we are adding all uploaded files
// indexed by field name
Widget w = loadedImages.get(iname);
if (w != null) {
w.removeFromParent();
loadedImages.remove(uploader.getInputName());
}
}
}
});

Listview display wrong image at wrong place when loading thumbnail image from web

I am using List view for displaying android files i.e. showing Folder and files from server.
When i start my activity, i can see the list on the screen, just as i want it.
and I am getting data from server.
I want to show structure like
when there is image file need to show image thumbnail (I have thumbnail URL which is getting from server by default imageloader displaying default image icon until thumbnail is not available).
when there is other file type like audio,video..... or file need to show that icon.
and when I am showing list it shows proper icon for related files.
But the moment i try to start scrolling the and in background my thumbnail is loading from server and when from server I am getting image from server and showing that bitmap thumbnail it will displaying thumbnail bitmap in other file type like folder or music file icon due to view reusing of listview.
this misplace is happen when getting image from server.
any one can please suggest me to how to overcome this problem.
below is my getview() method of my listview.
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder viewHolder = new ViewHolder();
if(convertView == null){
convertView = _inflate.inflate(R.layout.layout_list, null);
viewHolder.text = (TextView) convertView.findViewById(R.id.title);
viewHolder.owner = (TextView) convertView.findViewById(R.id.owner);
viewHolder.image = (ImageView) convertView.findViewById(R.id.thumb);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> item = (HashMap<String, String>) getItem(position);
viewHolder.text.setText( item.get("poiName").toString() );
viewHolder.owner.setText( item.get("owner").toString() );
ImageView imageView = viewHolder.image;
imageView.setTag(item.get("thumbs"));
//Is type of file is picture then display thumbnail by using imagloader class
if (genericDAO.sub_content_type.equalsIgnoreCase(Constants.TYPE_PICTURE))
{
String url = getTumbnalURL();
viewHolder.image.setTag(genericDAO.id);
viewHolder.image.setScaleType(ScaleType.CENTER_CROP);
mImageLoader.DisplayImage(id, url, mActivity,viewHolder.image);
}
else
{
//Display related file icon
viewHolder.image.setImageResource(FileUtil.getImageRelatedToFileType(mcontext, sub_ext));
}
return convertView;
}
although this code is insufficient. What I understood from this code is, you are using lazy loading for images, and mImageLoader must be running thread, which is setting image to viewHolder.
you can set imageInfo as tag in else part also.
....
else
{
//Display related file icon
viewHolder.image.setImageResource(FileUtil.getImageRelatedToFileType(mcontext, sub_ext));
viewHolder.image.setTag(genericDAO.id);
}
Inside ImageLoader, when new image is downloaded, just before you set new image to viewHolder please check for correct tag.

Problems with MvxSpinner in ListView

I'm having a problem where I have a listview that contains a group of spinners. If I select an option for the first spinner and then scroll down I'll see a spinner that I haven't even touched has the same value as the first spinner I just set. I'm assuming this is an issue with the Spinner view being recycled and improperly used below. Has anyone else ran into this issue with spinners? I'm thinking we need to implement a solution similar to this in MvxAdapter?
I implemented my own MyMvxAdapter and MyMvxListView to handle this. The only thing I changed in the MyMvxListView was to have it use MyMvxAdapter as its adapter instead of the normal MvxAdapter. I then changed the GetBindableView in MyMvxAdapter to look like this:
protected virtual View GetBindableView(View convertView, object dataContext, int templateId)
{
if (templateId == 0)
{
// no template seen - so use a standard string view from Android and use ToString()
return GetSimpleView(convertView, dataContext);
}
// we have a templateid so lets use bind and inflate on it :)
var viewToUse = convertView as IMvxListItemView;
if (viewToUse != null)
{
if (viewToUse.TemplateId != templateId)
{
viewToUse = null;
}
}
if (viewToUse == null)
{
viewToUse = CreateBindableView(dataContext, templateId);
}
else
{
var spinner = (MvxSpinner)convertView.FindViewById(Resource.Id.taskFieldSpinner);
if (spinner != null)
{
spinner.SetSelection(((WrappedEmployeeTaskField)dataContext).TheField.SpinnerSelection);
}
BindBindableView(dataContext, viewToUse);
}
return viewToUse as View;
}
You'll notice the only real difference is that I needed to directly access my spinner resource to properly set it if viewToUse is not null. Then the last of the "magic sauce" was to keep track of the spinner's selected value on my data model, in this case as the property "SpinnerSelection" on my model which gets filled in every time the value gets selected.

how prevent duplicate code in wicket

Sorry my english is bad
I have two class profile and EditProfile
in both class i have
protected void addContent(PageParameters pageParameters) {
final String email = pageParameters.get(ListUser.USER_EMAIL).toString();
final User loggedUser = getLoggedUser();
if (email == null) {
redirectToInterceptPage(new ErrorPage404(null));
return;
}
User userByEmail = userService.findByEmail(email);
if (userByEmail == null) {
redirectToInterceptPage(new ForbiddenPage403(null));
return;
}
final UserDetachableModel user = new UserDetachableModel(userByEmail);
// If the user is not active, there is no need to edit your profile.
if (!user.getObject().isActive()) {
redirectToInterceptPage(new ErrorPage404(null));
return;
}
// Only admins can see the profile of other users.
if (!loggedUser.getUserRole().equals(UserRole.ADMIN) && !loggedUser.getEmail().equalsIgnoreCase(email)) {
redirectToInterceptPage(new ForbiddenPage403(null));
return;
}
......PROCESS TO SEE PROFILE OR EDIT PROFILE........
}
I use a CustomMountedPage that i use to hide the serial number of wicket.
Example http://HOST/Page/subPage?ID&PARAMS to see http://HOST/Page/subPage?PARAMS and access to another profile
How prevent duplicate code!!
You can use Panels. They have their own markup file like a normal page but you can use them in any other Wicket-Page as a component.
Have a look at this page to see how to use panels correctly.

GWT CellBrowser- how to always show all values?

GWT's CellBrowser is a great way of presenting dynamic data.
However when the browser contains more rows than some (seemingly) arbitrary maximum, it offers a "Show More" label that the user can click to fetch the unseen rows.
How can I disable this behavior, and force it to always show every row?
There are several ways of getting rid of the "Show More" (which you can combine):
In your TreeViewModel, in your NodeInfo's setDisplay or in the DataProvider your give to the DefaultNodeInfo, in onRangeChange: overwrite the display's visible range to the size of your data.
Extend CellBrowser and override its createPager method to return null. It won't change the list's page size though, but you can set it to some very high value there too.
The below CellBrowser removes the "Show More" text plus loads all available elements without paging.
public class ShowAllElementsCellBrowser extends CellBrowser {
public ShowAllElementsCellBrowser(TreeViewModel viewModel, CellBrowser.Resources resources) {
super(viewModel, null, resources);
}
#Override
protected <C> Widget createPager(HasData<C> display) {
PageSizePager pager = new PageSizePager(Integer.MAX_VALUE);
// removes the text "Show More" during loading
display.setRowCount(0);
// increase the visible range so that no one ever needs to page
display.setVisibleRange(0, Integer.MAX_VALUE);
pager.setDisplay(display);
return pager;
}
}
I found a valid and simple solution in setting page size to the CellBrowser's builder.
Hope this will help.
CellBrowser.Builder<AClass> cellBuilder = new CellBrowser.Builder<AClass>(myModel, null);
cellBuilder.pageSize(Integer.MAX_VALUE);
cellBrowser = cellBuilder.build();
The easiest way to do this is by using the:
cellTree.setDefaultNodeSize(Integer.MAX_VALUE);
method on your Cell Tree. You must do this before you begin expanding the tree.
My workaround is to navigate through elements of treeview dom to get "show more" element with
public static List<Element> findElements(Element element) {
ArrayList<Element> result = new ArrayList<Element>();
findShowMore(result, element); return result; }
private static void findShowMore(ArrayList res, Element element) {
String c;
if (element == null) { return; }
if (element.getInnerText().equals("Show more")) { res.add(element);
}
for (int i = 0; i < DOM.getChildCount(element); i++) { Element
child = DOM.getChild(element, i); findShowMore(res, child); } }
and than use:
if (show) { element.getStyle().clearDisplay(); } else {
element.getStyle().setDisplay(Display.NONE); }