Web service with WP7 - windows-phone-7

I did appreciate your help for my previous question , and i was wondering how to read data from an URI,using web service(let's assume it's the same data).
Here's the url link:
http://www.google.com/ig/api?weather=paris
I tryied with this code but it didn't work:
public MainPage()
{
InitializeComponent();
WebClient wc = new WebClient();
wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(download_string_complete);
wc.DownloadStringAsync(new Uri("http://www.google.com/ig/api?weather=hammamet", UriKind.Absolute));
}
public void download_string_complete(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
ListBoxItem areaItem = null;
StringReader stream = new StringReader(e.Result);
XmlReader reader = XmlReader.Create(stream);
string day = String.Empty;
string low = String.Empty;
string high = String.Empty;
string condition = String.Empty;
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name=="forecast_conditions")
{
WeatherElement welement = new WeatherElement();
switch (reader.Name)
{
case ("day_of_week"):
{
day = reader.ReadElementContentAsString();
areaItem = new ListBoxItem();
areaItem.Content = day;
friendsBox.Items.Add(day);
} break;
case ("low"):
{
low = reader.ReadElementContentAsString();
areaItem = new ListBoxItem();
areaItem.Content = low;
friendsBox.Items.Add(low);
} break;
case ("high"):
{
high = reader.ReadElementContentAsString();
areaItem = new ListBoxItem();
areaItem.Content = high;
friendsBox.Items.Add(high);
} break;
case ("condition"):
{
condition = reader.ReadElementContentAsString();
areaItem = new ListBoxItem();
areaItem.Content = condition;
friendsBox.Items.Add(condition);
} break;
}
}
}
}
}
}

void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
StringReader stream = new StringReader(e.Result);
XmlReader reader = XmlReader.Create(stream);
string Day = String.Empty;
string Low = String.Empty;
string High = String.Empty;
string ImageUri = String.Empty;
string Condition = String.Empty;
reader.MoveToContent();
while (reader.Read())
{
switch (reader.Name)
{
case ("day_of_week"):
{
listBox1.Items.Add(new ListBoxItem()
{
Content = reader.GetAttribute("data")
});
Day = Content.ToString();
} break;
case ("low"):
{
listBox1.Items.Add(new ListBoxItem()
{
Content = reader.GetAttribute("data")
});
Low = Content.ToString();
} break;
case ("high"):
{
listBox1.Items.Add(new ListBoxItem()
{
Content = reader.GetAttribute("data")
});
High = Content.ToString();
} break;
case ("icon"):
{
listBox1.Items.Add(new ListBoxItem()
{
Content = reader.GetAttribute("data")
});
Image wkpinImage = new Image();
wkpinImage.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("http://www.google.com" + Content, UriKind.Absolute));
wkpinImage.Opacity = 0.8;
wkpinImage.Stretch = System.Windows.Media.Stretch.None;
} break;
case ("condition"):
{
listBox1.Items.Add(new ListBoxItem()
{
Content = reader.GetAttribute("data")
});
Condition = Content.ToString();
} break;
case("weather"):
break;
}
}
reader.Close();
}
}

Related

Background Downloader,Download operation won't start in UWP Windows10?

I want to download files using Background Downloader.
What i have tried is?
FolderPicker folderPicker = new FolderPicker();
folderPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
folderPicker.ViewMode = PickerViewMode.Thumbnail;
folderPicker.FileTypeFilter.Add("*");
StorageFolder storgaeFolder = await folderPicker.PickSingleFolderAsync();
if (storgaeFolder != null)
{
StorageFile file = await storgaeFolder.CreateFileAsync("newnow.jpeg", CreationCollisionOption.GenerateUniqueName);
BackgroundDownloader backgroundDownloader = new BackgroundDownloader();
DownloadOperation downloadOperation = backgroundDownloader.CreateDownload(new Uri("https://www.google.com/url?sa=i&url=https%3A%2F%2Fwallpapercave.com%2Ffull-hd-wallpaper-downlord&psig=AOvVaw2_UZ_HNVNVr6fJelpyg2-S&ust=1622265707226000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCOCRzOzQ6_ACFQAAAAAdAAAAABAQ"), file);
downloadOperation.Priority = BackgroundTransferPriority.High;
Progress<DownloadOperation> progress = new Progress<DownloadOperation>(progressChanged);
CancellationTokenSource cancellationToken = new CancellationTokenSource();
try
{
await downloadOperation.StartAsync().AsTask(cancellationToken.Token, progress);
string xx = null;
}
catch (TaskCanceledException)
{
await downloadOperation.ResultFile.DeleteAsync();
downloadOperation = null;
}
}
private void progressChanged(DownloadOperation downloadOperation)
{
int progress = (int)(100 * ((double)downloadOperation.Progress.BytesReceived /(double)downloadOperation.Progress.TotalBytesToReceive));
switch (downloadOperation.Progress.Status)
{
case BackgroundTransferStatus.Running:
{
break;
}
case BackgroundTransferStatus.PausedByApplication:
{
break;
}
case BackgroundTransferStatus.PausedCostedNetwork:
{
break;
}
case BackgroundTransferStatus.PausedNoNetwork:
{
break;
}
case BackgroundTransferStatus.Error:
{
break;
}
case BackgroundTransferStatus.Completed:
{
break;
}
case BackgroundTransferStatus.Canceled:
{
break;
}
default:
{
break;
}
}
if (progress >= 100)
{
downloadOperation = null;
}
}
the execution stopped/paused at the line ---> await downloadOperation.StartAsync().The program won't run after this line and the download operation doesn't through any BackgrowndTransferStatus or Exceptions.I don't know why the code won't run after the line.

Is How do I solve the error Event registration is overwriting existing delegate for MKMapView?

When I try to run my Xamarin.forms maps application I get the following error: Event registration is overwriting existing delegate. Either just use events or your own delegate: MyApp.iOS.CustomRenderer.MapDelegate MapKit.MKMapView+_MKMapViewDelegate
I attached my CustomMapRender file to this question
... C#
using ICCHMapClusterControllerDelegate = MapClustering.ICCHMapClusterControllerDelegate;
using ICCHMapClusterer = MapClustering.ICCHMapClusterer;
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace MyApp.iOS.CustomRenderer
{
public class CustomMapRenderer : MapRenderer, ICCHMapClusterControllerDelegate//IMKMapViewDelegate
{
MKMapView mapView;
CustomMap customMap;
CCHMapClusterController mapClusterController;
ICCHMapClusterer mapClusterer;
List<MKPointAnnotation> annotations;
CLLocationManager LocationManager;
protected override void Dispose(bool disposing)
{
mapView.ShowsUserLocation = false;
base.Dispose(disposing);
}
protected override void OnElementChanged(ElementChangedEventArgs<View> e)
{
base.OnElementChanged(e);
if (e.OldElement == null)
{
mapView = Control as MKMapView;
customMap = e.NewElement as CustomMap;
customMap.LocationsLoaded += customMap_LocationsLoaded;
customMap.CenterToMyLocationButtonClicked += CenterToMyLocation;
customMap.OpenCallout += OpenCallout;
LocationManager = new CLLocationManager();
LocationManager.AuthorizationChanged += (object locationmanager, CLAuthorizationChangedEventArgs eventargs) =>
{
if (eventargs.Status == CLAuthorizationStatus.AuthorizedWhenInUse)
{
mapView.ShowsUserLocation = true;
}
else
{
mapView.ShowsUserLocation = false;
}
};
if (CLLocationManager.Status == CLAuthorizationStatus.AuthorizedWhenInUse || CLLocationManager.Status == CLAuthorizationStatus.AuthorizedAlways
|| CLLocationManager.Status == CLAuthorizationStatus.Authorized)
{
mapView.ShowsUserLocation = true;
}
WMSTileOverlay WMSOverlay = new WMSTileOverlay(NetworkConstants.WmsOvermaasLayerUrl, "3")
{
CanReplaceMapContent = false
};
WMSProvincieTileOverlay ProvinceOverLay = new WMSProvincieTileOverlay
{
CanReplaceMapContent = false
};
WMSTileOverlay WPMOverlay2 = new WMSTileOverlay(NetworkConstants.WmsWpmLayerUrl, "2")
{
CanReplaceMapContent = false
};
WMSTileOverlay WPMOverlay3 = new WMSTileOverlay(NetworkConstants.WmsWpmLayerUrl, "3")
{
CanReplaceMapContent = false
};
WMSTileOverlay WPMOverlay4 = new WMSTileOverlay(NetworkConstants.WmsWpmLayerUrl, "4")
{
CanReplaceMapContent = false
};
mapView.AddOverlay(WMSOverlay, MKOverlayLevel.AboveLabels);
mapView.AddOverlay(ProvinceOverLay, MKOverlayLevel.AboveLabels);
mapView.AddOverlay(WPMOverlay2, MKOverlayLevel.AboveLabels);
mapView.AddOverlay(WPMOverlay3, MKOverlayLevel.AboveLabels);
mapView.AddOverlay(WPMOverlay4, MKOverlayLevel.AboveLabels);
Debug.WriteLine("TESTING");
mapClusterController = new CCHMapClusterController(mapView);
mapClusterController.Delegate = new CCHMapClusterControllerDelegate();
mapClusterController.WeakDelegate = this;
// /new CCHMapDelegate();//new CCHMapDelegate();
//new CCHMapClusterControllerDelegate(); //new CCHMapDelegate ();
}
}
private void customMap_LocationsLoaded(object sender, List<Location> locations)
{
RemoveAnnotations();
if (locations == null || locations.Count == 0)
{
return;
}
annotations = new List<MKPointAnnotation>();
foreach (Location location in locations)
{
MKPointAnnotation anno = new MKPointAnnotation();
CLLocationCoordinate2D coord = new CLLocationCoordinate2D(location.Latitude, location.Longitude);
anno.Coordinate = coord;
anno.Title = location.WaterName;
anno.Subtitle = location.City + " " + location.ExternalReference;
annotations.Add(anno);
}
mapClusterController.AddAnnotations(annotations.ToArray(), null);
mapView.Delegate = new MapDelegate(locations, customMap);
mapClusterController.ReuseExistingClusterAnnotations = false;
}
private void RemoveAnnotations()
{
if (annotations != null && annotations.Count != 0)
{
mapClusterController.RemoveAnnotations(annotations.ToArray(), () =>
{
});
}
}
private void CenterToMyLocation(object sender, string e)
{
if (CLLocationManager.Status == CLAuthorizationStatus.AuthorizedWhenInUse || CLLocationManager.Status == CLAuthorizationStatus.AuthorizedAlways
|| CLLocationManager.Status == CLAuthorizationStatus.Authorized)
{
MKCoordinateRegion mapRegion;
mapRegion.Center.Latitude = mapView.UserLocation.Coordinate.Latitude;
mapRegion.Center.Longitude = mapView.UserLocation.Coordinate.Longitude;
mapRegion.Span.LatitudeDelta = 0.2;
mapRegion.Span.LongitudeDelta = 0.2;
mapView.SetRegion(mapRegion, true);
}
if (CLLocationManager.Status == CLAuthorizationStatus.Denied)
{
//check if ios 7/8 this is ios 8
UIAlertController alertController = UIAlertController.Create(title: "Locatie", message: "Om uw locatie te kunnen gebruiken in de app hebben we uw toestemming nodig. " +
"dit kunt u in het instellingen menu geven.", preferredStyle: UIAlertControllerStyle.Alert);
alertController.AddAction(UIAlertAction.Create(title: "Annuleren", style: UIAlertActionStyle.Cancel, handler: null));
alertController.AddAction(UIAlertAction.Create(title: "Instellingen", style: UIAlertActionStyle.Default, handler =>
{
NSUrl settingsurl = new NSUrl(UIApplication.OpenSettingsUrlString);
mapView.ShowsUserLocation = true;
UIApplication.SharedApplication.OpenUrl(settingsurl);
}));
UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(alertController, true, null);
//Old Obsolete
//UIAlertView alert = new UIAlertView("Locatie", "Om uw locatie te kunnen gebruiken in de app hebben we uw toestemming nodig. " +
// "dit kunt u in het instellingen menu geven.", null, "Annuleren", "Instellingen");
//alert.Clicked += (object alertsender, UIButtonEventArgs eventargs) => {
// if (eventargs.ButtonIndex != 0)
// {
// NSUrl settingsurl = new NSUrl(UIApplication.OpenSettingsUrlString);
// mapView.ShowsUserLocation = true;
// UIApplication.SharedApplication.OpenUrl(settingsurl);
// }
//};
//alert.Show();
}
if (CLLocationManager.Status == CLAuthorizationStatus.NotDetermined)
{
LocationManager.RequestWhenInUseAuthorization();
}
}
private void OpenCallout(object sender, Location e)
{
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
Thread.Sleep(1000); // delay execution for 1 s
Device.BeginInvokeOnMainThread(() =>
{
var anno = this.annotations.Where(a => a.Coordinate.Latitude == e.Latitude && a.Coordinate.Longitude == e.Longitude).FirstOrDefault();
if (anno != null)
{
this.mapClusterController.SelectAnnotation(anno, e.Latitude, e.Longitude);
}
});
});
}
[Export("mapClusterController:titleForMapClusterAnnotation:")]
public string TitleForMapClusterAnnotation(CCHMapClusterController mapClusterController, CCHMapClusterAnnotation mapClusterAnnotation)
{
var annotationsCount = mapClusterAnnotation.Annotations.Count;
if (annotationsCount != 1) return "";
MKPointAnnotation annot = (MKPointAnnotation)mapClusterAnnotation.Annotations.First();
return annot.Title;
}
[Export("mapClusterController:subtitleForMapClusterAnnotation:")]
public string SubtitleForMapClusterAnnotation(CCHMapClusterController mapClusterController, CCHMapClusterAnnotation mapClusterAnnotation)
{
if (mapClusterAnnotation.Annotations.Count != 1) return "";
MKPointAnnotation annot = (MKPointAnnotation)mapClusterAnnotation.Annotations.First();
return annot.Subtitle;
}
[Export("mapClusterController:willReuseMapClusterAnnotation:")]
public void WillReuseMapClusterAnnotation(CCHMapClusterController mapClusterController, CCHMapClusterAnnotation mapClusterAnnotation)
{
}
}
internal class MapDelegate : MKMapViewDelegate
{
public MapDelegate(List<Location> locations, CustomMap CustomMap)
: base()
{
Locations = locations;
customMap = CustomMap;
conv = new LevelStatusToColorValueConverter();
defaultColor = Color.FromHex(ColorConstants.WaterLevelBadgeGreen).ToUIColor();
}
static NSObject Invoker = new NSObject();
List<Location> Locations;
string clusterPinId = "cluster";
string nonClusterPinId = "nonCluster";
CustomMap customMap;
LevelStatusToColorValueConverter conv;
UIColor defaultColor;
public override void RegionChanged(MKMapView mapView, bool animated)
{
if (mapView.UserLocationVisible)
{
customMap.ChangeStatusOfLocationImageOnMap(true);
}
else
{
customMap.ChangeStatusOfLocationImageOnMap(false);
}
}
public override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation anno)
{
var annotation = ObjCRuntime.Runtime.GetNSObject(anno.Handle) as CCHMapClusterAnnotation; // this is required to get the underlying annotation object
string useId = nonClusterPinId;
if (anno is MKUserLocation)
return null;
if (annotation == null)
{
return null;
}
string imageName = "";
string imageURL = string.Empty;
string value = string.Empty;
UIColor color = defaultColor;
if (annotation.IsCluster)
{
useId = clusterPinId;
if (Locations != null)
{
List<Location> locations = new List<Location>();
foreach (MKPointAnnotation clusterAnno in annotation.Annotations)
{
string title = clusterAnno.Subtitle;
var location = Locations.Where(l => (l.City + " " + l.ExternalReference) == title).ToList();
if (location != null && location.Count != 0)
{
locations.Add(location.First());
}
}
if (locations.Any())
{
imageName = MapUtil.GetCorrectImageNameForLocations(locations);
}
}
}
else
{
if (Locations != null)
{
string title = annotation.Subtitle;
var location = Locations.Where(l => (l.City + " " + l.ExternalReference) == title).ToList();
if (location != null && location.Count != 0)
{
var currentLocation = location.First();
value = currentLocation.CurrentValueAsString;
var xColor = (Color)conv.Convert(currentLocation.WaterlevelStatus, null, null, null);
color = xColor.ToUIColor();
imageName = MapUtil.GetCorrectImageNameForLocation(currentLocation);
if (currentLocation.HasImage)
{
imageURL = currentLocation.SmallImageURL();
}
else
{
imageURL = NetworkConstants.NoImageSmall;
}
}
}
}
MKAnnotationView pinView = (MKAnnotationView)mapView.DequeueReusableAnnotation(useId);
if (pinView == null)
pinView = new MKAnnotationView(annotation, useId);
if (!annotation.IsCluster)
{
pinView.CanShowCallout = true;
double testWidth = value.Length < 11 ? 65 : 90;
var button = new UIButton(new CGRect(testWidth, 5, 10, 20));
button.SetImage(UIImage.FromBundle("disclosure"), UIControlState.Normal);
JSBadgeView badge = new JSBadgeView(button, JSBadgeView.Alignment.CenterLeft)
{
BadgeBackgroundColor = color,
BadgeStrokeColor = UIColor.Red,
BadgeTextColor = Color.FromHex(ColorConstants.DarkGreyDetailText).ToUIColor(),
BadgeTextFont = UIFont.FromName("AvenirNext-Regular", 11),
BadgeAlignment = JSBadgeView.Alignment.CenterLeft,
BadgeText = value
};
UIView view = new UIView(new CGRect(0, 0, testWidth + 10, 30));
view.ClipsToBounds = false;
view.AddSubview(button);
pinView.RightCalloutAccessoryView = view;
if (string.IsNullOrEmpty(imageURL))
{
var imageView = new UIImageView(new CGRect(0, 0, 42, 42));
imageView.Image = UIImage.FromBundle("notavailable");
imageView.ContentMode = UIViewContentMode.ScaleAspectFit;
pinView.LeftCalloutAccessoryView = imageView;
}
else
{
FromUrl(imageURL, pinView);
}
}
pinView.Image = UIImage.FromBundle((string.IsNullOrEmpty(imageName)) ? "flowgreenpin" : imageName);
if (annotation.IsCluster)
{
pinView.CanShowCallout = false;
JSBadgeView badge = new JSBadgeView(pinView, JSBadgeView.Alignment.TopCenter)
{
BadgeBackgroundColor = UIColor.FromRGB(0.451f, 0.847f, 0.988f),
BadgeStrokeColor = UIColor.Red,
BadgeTextColor = UIColor.White,
BadgeTextFont = UIFont.FromName("AvenirNext-Regular", 11),
BadgeAlignment = JSBadgeView.Alignment.TopCenter,
BadgeText = annotation.Annotations.Count.ToString()
};
}
return pinView;
}
public static void InvokedOnMainThread(Action Action)
{
if (NSThread.Current.IsMainThread)
Action();
else
Invoker.BeginInvokeOnMainThread(() => Action());
}
static async Task FromUrl(string uri, MKAnnotationView pinView)
{
using (var httpClient = new HttpClient())
{
Task<byte[]> contentsTask = httpClient.GetByteArrayAsync(uri);
// await! control returns to the caller and the task continues to run on another thread
var contents = await contentsTask;
// load from bytes
var image = UIImage.LoadFromData(NSData.FromArray(contents));
var imageView = new UIImageView(new CGRect(0, 0, 42, 42));
imageView.Image = image;
imageView.ContentMode = UIViewContentMode.ScaleAspectFit;
InvokedOnMainThread(delegate
{
pinView.LeftCalloutAccessoryView = imageView;
});
}
}
public override void DidSelectAnnotationView(MKMapView mapView, MKAnnotationView view)
{
var annotation = ObjCRuntime.Runtime.GetNSObject(view.Annotation.Handle) as CCHMapClusterAnnotation;
if (annotation != null)
{
if (!annotation.IsCluster)
{
UITapGestureRecognizer tap = new UITapGestureRecognizer(OnTap);
view.AddGestureRecognizer(tap);
return;
}
MKMapRect mapRect = annotation.MapRect;
UIEdgeInsets edgeInsets = new UIEdgeInsets(20, 20, 20, 20);
mapView.SetVisibleMapRect(mapRect, edgeInsets, true);
}
mapView.DeselectAnnotation(view.Annotation, true);
}
public override void DidDeselectAnnotationView(MKMapView mapView, MKAnnotationView view)
{
view.GestureRecognizers = null;
}
public override void CalloutAccessoryControlTapped(MKMapView mapView, MKAnnotationView view, UIControl control)
{
if (view != null)
{
var clusterPin = ObjCRuntime.Runtime.GetNSObject(view.Annotation.Handle) as CCHMapClusterAnnotation;
var location = Locations.Where(l => (l.City + " " + l.ExternalReference) == clusterPin.Subtitle).ToList();
if (location != null && location.Count != 0)
{
customMap.ClickedCallout(location.First());
}
}
}
private void OnTap(UIGestureRecognizer gesture)
{
var pinView = gesture.View as MKAnnotationView;
if (pinView != null)
{
var clusterPin = ObjCRuntime.Runtime.GetNSObject(pinView.Annotation.Handle) as CCHMapClusterAnnotation;
var location = Locations.Where(l => (l.City + " " + l.ExternalReference) == clusterPin.Subtitle).ToList();
if (location != null && location.Count != 0)
{
customMap.ClickedCallout(location.First());
}
}
}
public override MKOverlayRenderer OverlayRenderer(MKMapView mapView, IMKOverlay overlay)
{
var osmOverlay = overlay as WMSTileOverlay;
if (osmOverlay != null)
{
return new MKTileOverlayRenderer(new WMSTileOverlay(osmOverlay.BaseUrl, osmOverlay.Layer) { CanReplaceMapContent = false });
}
return new MKTileOverlayRenderer(new WMSProvincieTileOverlay() { CanReplaceMapContent = false });
}
}
internal class CCHMapDelegate : UIViewController, ICCHMapClusterControllerDelegate//CCHMapClusterControllerDelegate
{
[Export("mapClusterController:titleForMapClusterAnnotation:")]
public string TitleForMapClusterAnnotation(CCHMapClusterController mapClusterController, CCHMapClusterAnnotation mapClusterAnnotation)
{
var annotationsCount = mapClusterAnnotation.Annotations.Count;
if (annotationsCount != 1) return "";
MKPointAnnotation annot = (MKPointAnnotation)mapClusterAnnotation.Annotations.First();
return annot.Title;
}
//public override string MapClusterTitleForAnnotation (CCHMapClusterController mapClusterController, CCHMapClusterAnnotation mapClusterAnnotation)
//{
// if (mapClusterAnnotation.Annotations.Count == 1) {
// MKPointAnnotation annot = (MKPointAnnotation)mapClusterAnnotation.Annotations.First ();
// return annot.Title;
// }
// return "";
//}
[Export("mapClusterController:subtitleForMapClusterAnnotation:")]
public string SubtitleForMapClusterAnnotation(CCHMapClusterController mapClusterController, CCHMapClusterAnnotation mapClusterAnnotation)
{
if (mapClusterAnnotation.Annotations.Count != 1) return "";
MKPointAnnotation annot = (MKPointAnnotation)mapClusterAnnotation.Annotations.First();
return annot.Subtitle;
}
//public override string MapClusterSubtitleForAnnotation (CCHMapClusterController mapClusterController, CCHMapClusterAnnotation mapClusterAnnotation)
//{
// if (mapClusterAnnotation.Annotations.Count == 1) {
// MKPointAnnotation annot = (MKPointAnnotation)mapClusterAnnotation.Annotations.First ();
// return annot.Subtitle;
// }
// return "";
//}
[Export("mapClusterController:willReuseMapClusterAnnotation:")]
public void WillReuseMapClusterAnnotation(CCHMapClusterController mapClusterController, CCHMapClusterAnnotation mapClusterAnnotation)
{
}
//public override void MapClusterWillReuseAnnotation (CCHMapClusterController mapClusterController, CCHMapClusterAnnotation mapClusterAnnotation)
//{
//}
}
}
...

Action.Picker returns invalid/wrong Uri (How to get path or byte[] from multiple picked gallery img)

I have an forms app where i need to pick "1 to many" images from the phone storage.
For this i use the dependency injection system.
My problem is the somewhere i get an Android.netUri that resolves to a file that do not exist... and to a file name that i have never seen before.
The kicker is that if i pick pictures that was takes within the last couple of hours this code works...
Im am at the end of my hoap, i really hope someone can point me to something that i'm doing wrong.
i start the Picker activity with:
[assembly: Dependency(typeof(ImagePickerService))]
namespace MyApp.Droid
{
public class ImagePickerService : Java.Lang.Object, IImagePickerService
{
public async Task OpenGallery()
{
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Storage);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Storage))
{
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Need Storage permission to access to your photos.", ToastLength.Long).Show();
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(new[] { Permission.Storage });
status = results[Permission.Storage];
}
if (status == PermissionStatus.Granted)
{
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Pick max 20 images", ToastLength.Long).Show();
var imageIntent = new Intent(Intent.ActionPick);
imageIntent.SetType("image/*");
imageIntent.PutExtra(Intent.ExtraAllowMultiple, true);
imageIntent.SetAction(Intent.ActionPick);
CrossCurrentActivity.Current.Activity.StartActivityForResult(Intent.CreateChooser(imageIntent, "Pick pictures"), 100);
}
else if (status != PermissionStatus.Unknown)
{
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Permission Denied. Can not continue, try again.", ToastLength.Long).Show();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Toast.MakeText(CrossCurrentActivity.Current.Activity, "Error. Can not continue, try again.", ToastLength.Long).Show();
}
}
}
then in my MainActivity.cs i have the OnActivityResult
I have tried to use the ContentResolver.OpenInputStream to get the image bytes with no luck, so this is commented out atm.
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == OPENGALLERYCODE && resultCode == Result.Ok)
{
List<string> images = new List<string>();
if (data != null)
{
ClipData clipData = data.ClipData;
if (clipData != null)
{
for (int i = 0; i < clipData.ItemCount; i++)
{
ClipData.Item item = clipData.GetItemAt(i);
/*
var stream = ContentResolver.OpenInputStream(item.Uri); //This throws "FileNotFound"
byte[] byteArray;
using (var memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
byteArray = memoryStream.ToArray();
stream.Close();
stream = null;
}
stream = ContentResolver.OpenInputStream(item.Uri);
var exif = new ExifInterface(stream);
stream.Close();
*/
Android.Net.Uri uri = item.Uri;
var path = GetActualPathFromFile(uri);
if (path != null)
{
var tmpImgPath = RotateToOriginalDimention(path);
images.Add(tmpImgPath);
}
}
}
else
{
Android.Net.Uri uri = data.Data;
var path = GetActualPathFromFile(uri);
if (path != null)
{
var tmpImgPath = RotateToOriginalDimention(path);
images.Add(tmpImgPath);
}
}
MessagingCenter.Send<App, List<string>>((App)Xamarin.Forms.Application.Current, "ImagesSelected", images);
}
}
}
And the GetActualPathFromFile (also in my MainActivity.cs)
The hole func is below but i hit this part of the code and get at "FileNotFound"
(...)
else if ("content".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
var retval2 = getDataColumn(this, uri, null, null);
if (File.Exists(retval2)) //<----------------------- This returns "false"
{
return retval2;
}
else
{
throw new Exception("file not found " + retval2);
}
}
(...)
The Hole GetActualPathFromFile
private string GetActualPathFromFile(Android.Net.Uri uri)
{
bool isKitKat = Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Kitkat;
if (isKitKat && DocumentsContract.IsDocumentUri(this, uri))
{
// ExternalStorageProvider
if (isExternalStorageDocument(uri))
{
string docId = DocumentsContract.GetDocumentId(uri);
char[] chars = { ':' };
string[] split = docId.Split(chars);
string type = split[0];
if ("primary".Equals(type, StringComparison.OrdinalIgnoreCase))
{
var retval = Android.OS.Environment.ExternalStorageDirectory + "/" + split[1];
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri))
{
string id = DocumentsContract.GetDocumentId(uri);
Android.Net.Uri contentUri = ContentUris.WithAppendedId(
Android.Net.Uri.Parse("content://downloads/public_downloads"), long.Parse(id));
//System.Diagnostics.Debug.WriteLine(contentUri.ToString());
var retval = getDataColumn(this, contentUri, null, null);
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
// MediaProvider
else if (isMediaDocument(uri))
{
String docId = DocumentsContract.GetDocumentId(uri);
char[] chars = { ':' };
String[] split = docId.Split(chars);
String type = split[0];
Android.Net.Uri contentUri = null;
if ("image".Equals(type))
{
contentUri = MediaStore.Images.Media.ExternalContentUri;
}
else if ("video".Equals(type))
{
contentUri = MediaStore.Video.Media.ExternalContentUri;
}
else if ("audio".Equals(type))
{
contentUri = MediaStore.Audio.Media.ExternalContentUri;
}
String selection = "_id=?";
String[] selectionArgs = new String[]
{
split[1]
};
var retval = getDataColumn(this, contentUri, selection, selectionArgs);
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
}
// MediaStore (and general)
else if ("content".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
// Return the remote address
if (isGooglePhotosUri(uri))
{
var retval = uri.LastPathSegment;
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
var retval2 = getDataColumn(this, uri, null, null);
if (File.Exists(retval2))
{
return retval2;
}
else
{
throw new Exception("file not found " + retval2);
}
}
// File
else if ("file".Equals(uri.Scheme, StringComparison.OrdinalIgnoreCase))
{
var retval = uri.Path;
if (File.Exists(retval))
{
return retval;
}
else
{
throw new Exception("file not found " + retval);
}
}
throw new Exception("file not found ");
}
public static String getDataColumn(Context context, Android.Net.Uri uri, String selection, String[] selectionArgs)
{
ICursor cursor = null;
String column = "_data";
String[] projection =
{
column
};
try
{
cursor = context.ContentResolver.Query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.MoveToFirst())
{
int index = cursor.GetColumnIndexOrThrow(column);
return cursor.GetString(index);
}
}
finally
{
if (cursor != null)
cursor.Close();
}
return null;
}
//Whether the Uri authority is ExternalStorageProvider.
public static bool isExternalStorageDocument(Android.Net.Uri uri)
{
return "com.android.externalstorage.documents".Equals(uri.Authority);
}
//Whether the Uri authority is DownloadsProvider.
public static bool isDownloadsDocument(Android.Net.Uri uri)
{
return "com.android.providers.downloads.documents".Equals(uri.Authority);
}
//Whether the Uri authority is MediaProvider.
public static bool isMediaDocument(Android.Net.Uri uri)
{
return "com.android.providers.media.documents".Equals(uri.Authority);
}
//Whether the Uri authority is Google Photos.
public static bool isGooglePhotosUri(Android.Net.Uri uri)
{
return "com.google.android.apps.photos.content".Equals(uri.Authority);
}
Found out that the real problem was that Google Photos App was not updating and was still showing images that were deleted.
After 2x reboot of the phone, Google Photos app finally updated.
So this looks more like a cache problem with Google Foto than a xamarin problem.

Save files in asp.net folder with reference in the database from a desktop client

ASP.NET WEB API: Hi, I would like to know to save files in asp.net web api folder with the link reference in database from desktop client. I searched it online and got some implementation still it's not workin.
Below are what I got so far. I hope someone can help me out with that.
Your contribution will really help.
My api controller code
[HttpPost]
public HttpResponseMessage PostFile()
{
HttpResponseMessage result = null;
var httpRequest = HttpContext.Current.Request;
if (httpRequest.Files.Count > 0)
{
var docfiles = new List<string>();
foreach (string file in httpRequest.Files)
{
var postedFile = httpRequest.Files[file];
if (postedFile != null)
{
var filePath = HttpContext.Current.Server.MapPath("~/files" + postedFile.FileName);
postedFile.SaveAs(filePath);
docfiles.Add(filePath);
}
}
result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
}
else
{
result = Request.CreateResponse(HttpStatusCode.BadRequest);
}
return result;
}
My client side code
OpenFileDialog fd = new OpenFileDialog();
private void btnUpload_Click(object sender, EventArgs e)
{
bool uploadStatus = false;
fd.Filter = "Image Files(*.jpg; *.jpeg; *.gif; *.bmp;)|*.jpg; *jpeg; *.gif; *.bmp;";
fd.Title = "Choose image";
if (fd.ShowDialog() == DialogResult.OK)
{
picUpload.Image = new Bitmap(fd.FileName);
foreach(String localfile in fd.FileNames)
{
var url = "url";
var filepath = #"\";
Random ran = new Random();
var uploadFileName = "img" + ran.Next(999).ToString();
uploadStatus = UploadConfig(url, filepath, localfile, uploadFileName);
}
}
if (uploadStatus)
{
MessageBox.Show("Successful");
}
else
{
MessageBox.Show("Failed");
}
}
bool UploadConfig(string url, string filePath, string localFileName, string UploadFileName)
{
bool isFileUploaded = false;
try
{
using (HttpClient client = new HttpClient())
{
var fs = File.Open(localFileName, FileMode.Open);
var fi = new FileInfo(localFileName);
UploadDetails uploadDetails = null;
bool fileUpload = false;
MultipartFormDataContent content = new MultipartFormDataContent();
content.Headers.Add("filePath",filePath);
content.Add(new StreamContent(fs), "\"files\"",
string.Format("\"{0}\"", UploadFileName + fi.Extension));
Task taskUpload = client.PostAsync(url, content).ContinueWith(task =>
{
if(task.Status == TaskStatus.RanToCompletion)
{
var res = task.Result;
if (res.IsSuccessStatusCode)
{
uploadDetails = res.Content.ReadAsAsync<UploadDetails>().Result;
if (uploadDetails != null)
{
fileUpload = true;
}
}
}
fs.Dispose();
});
taskUpload.Wait();
if (fileUpload)
{
isFileUploaded = true;
client.Dispose();
}
}
}
catch (Exception e)
{
isFileUploaded = false;
}
return isFileUploaded;
}

How to show image on imageview using webservices and json

I am using web service for showing image in imageview. But web service image show in SYSTEM.BYTE[] Format. So how to Convert or display the image in imageview in xamarin android application??
Webservice.asmx:
[WebMethod(MessageName = "BindHospName", Description = "Bind Hospital Name Control")]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
[System.Xml.Serialization.XmlInclude(typeof(GetHospName))]
public string BindHosp(decimal SpecID)
{
JavaScriptSerializer objJss = new JavaScriptSerializer();
List<GetHospName> HospName = new List<GetHospName>();
try
{
ConnectionString();
cmd = new SqlCommand("select b.HID,b.HospName,b.Logo from HospitalRegBasic b inner join HospitalRegClinical c on b.HID=c.HID " +
"where b.EmailActivationCode <> '' and b.EmailActivationStatus = 1 and b.Status = 1 and c.SPEC_ID = #SpecID ", conn);
cmd.Parameters.AddWithValue("#SpecID", SpecID);
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
var getHosp = new GetHospName
{
HospID = dr["HID"].ToString(),
HospName = dr["HospName"].ToString(),
HospLogo = dr["Logo"].ToString()
};
HospName.Add(getHosp);
}
}
dr.Close();
cmd.Dispose();
conn.Close();
}
catch (Exception)
{
throw;
}
return objJss.Serialize(HospName);
}
Class.cs:
namespace HSAPP
{
class ContListViewHospNameClass : BaseAdapter<GetHospNames>
{
List<GetHospNames> objList;
Activity objActivity;
public ContListViewHospNameClass (Activity objMyAct, List<GetHospNames> objMyList) : base()
{
this.objActivity = objMyAct;
this.objList = objMyList;
}
public override GetHospNames this[int position]
{
get
{
return objList[position];
}
}
public override int Count
{
get
{
return objList.Count;
}
}
public override long GetItemId(int position)
{
return position;
}
public static Bitmap bytesToBitmap(byte[] imageBytes)
{
Bitmap bitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
return bitmap;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = objList[position];
if (convertView == null)
{
convertView = objActivity.LayoutInflater.Inflate(Resource.Layout.ContListViewHospName, null);
}
convertView.FindViewById<TextView>(Resource.Id.tvHospID).Text = item.HospID;
convertView.FindViewById<TextView>(Resource.Id.tvHospName).Text = item.HospName;
byte[] img =item.HospLogo;
Bitmap bitmap = BitmapFactory.DecodeByteArray(img, 0, img.Length);
convertView.FindViewById<ImageView>(Resource.Id.imgLogo).SetImageBitmap(bitmap);
return convertView;
}
}
}
This is JSON Code:
private void BindControl_BindHospCompleted(object sender, BindControl.BindHospCompletedEventArgs e)
{
jsonValue = e.Result.ToString();
if (jsonValue == null)
{
Toast.MakeText(this, "No Data For Bind", ToastLength.Long).Show();
return;
}
try
{
JArrayValue = JArray.Parse(jsonValue);
list = new List<GetHospNames>();
int count = 0;
while (count < JArrayValue.Count)
{
GetHospNames getHospName = new GetHospNames(JArrayValue[count]["HospID"].ToString(), JArrayValue[count]["HospName"].ToString(),JArrayValue[count]["Logo"]);
list.Add(getHospName);
count++;
}
listView.Adapter = new ContListViewHospNameClass(this, list);
}
catch (Exception ex)
{
Toast.MakeText(this, ex.ToString(), ToastLength.Long).Show();
}
}
public static void SetImageFromByteArray (byte[] iArray, UIImageView imageView)
{
if (iArray != null && iArray.Length > 0) {
Bitmap bitmap = BitmapFactory.DecodeByteArray (iArray, 0, iArray.Length);
imageView.SetImageBitmap (bitmap);
}
}
That's it. If this is not working, your byte array may not be a valid image.
public static bool IsValidImage(byte[] bytes)
{
try {
using(MemoryStream ms = new MemoryStream(bytes))
Image.FromStream(ms);
}
catch (ArgumentException) {
return false;
}
return true;
}

Resources