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.
Related
we have implement file chooser for web view. it works successfully when attachment is selected, but fails when cancelled without file specification. The file chooser just stops to react on click
any help is appreciated. Thanks
we use chrome client. it works fine if in all cases, file selection is listed. but even from the first file selection is cancelled, no longer file chooser will work. It is Xamarin.Android app based fully on webview
Our code is:
protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
if (requestCode == FILECHOOSER_RESULTCODE)
{
if (null == _mUploadMessage)
return;
// Check that the response is a good one
if (resultCode == Result.Ok)
{
Android.Net.Uri[] results = null;
if (intent == null)
{
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null)
{
results = new Android.Net.Uri[] { Android.Net.Uri.Parse(mCameraPhotoPath) };
}
}
else
{
if (intent.DataString != null)
{
results = new Android.Net.Uri[] { Android.Net.Uri.Parse(intent.DataString) };
}
}
_mUploadMessage.OnReceiveValue(results);
_mUploadMessage = null;
}
}
}
Chrome client:
var chrome = new FileChooserWebChromeClient((uploadMsg) =>
{
_mUploadMessage = uploadMsg;
mCameraPhotoPath = null;
Intent takePictureIntent = new Intent(Android.Provider.MediaStore.ActionImageCapture);
//Create the File where the photo should go
File photoFile = null;
try
{
string folder = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
photoFile = new File(folder, "image" + DateTime.Now.Millisecond + ".png");
takePictureIntent.PutExtra("PhotoPath", mCameraPhotoPath);
}
catch (IOException ex)
{
// Error occurred while creating the File
System.Console.WriteLine("" + ex.ToString());
}
// Continue only if the File was successfully created
if (photoFile != null)
{
mCameraPhotoPath = "file:" + photoFile.AbsolutePath;
takePictureIntent.PutExtra(Android.Provider.MediaStore.ExtraOutput,
Android.Net.Uri.FromFile(photoFile));
}
else
{
takePictureIntent = null;
}
Intent contentSelectionIntent = new Intent(Intent.ActionGetContent);
contentSelectionIntent.AddCategory(Intent.CategoryOpenable);
contentSelectionIntent.SetType("image/*");
Intent[] intentArray;
if (takePictureIntent != null)
{
intentArray = new Intent[] { takePictureIntent };
}
else
{
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ActionChooser);
chooserIntent.PutExtra(Intent.ExtraIntent, contentSelectionIntent);
chooserIntent.PutExtra(Intent.ExtraTitle, this.GetStringFromResource(Resource.String.chose_photo));
chooserIntent.PutExtra(Intent.ExtraInitialIntents, intentArray);
base.StartActivityForResult(chooserIntent, HarmonyAndroid.AndroidMainActivity.FILECHOOSER_RESULTCODE);
});
return chrome;
Part 2
class FileChooserWebChromeClient : WebChromeClient
{
Action<IValueCallback> callback;
public FileChooserWebChromeClient(Action<IValueCallback> callback)
{
this.callback = callback;
}
public override bool OnShowFileChooser(WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
{
callback(filePathCallback);
return true;
}
public override void OnCloseWindow(WebView window)
{
base.OnCloseWindow(window);
}
}
Part 3
webView.ImprovePerformance();
webView.SetWebViewClient(new HomeWebViewClient(customWebViewClientListener, clientId));
webView.SetWebChromeClient(chrome);
webView.Settings.JavaScriptEnabled = true;
webView.Settings.DomStorageEnabled = true;
webView.SetDownloadListener(new CustomDownloadListener(activity, customDownloadListener));
webView.AddJavascriptInterface(new JavaScriptToCSharpCommunication(activity, javaScriptToCSharpCommunicationListener), Constants.JS_CSHARP_COMMUNICATOR_NAME);
Try to give a null object to the uri callback, when the resultCode is not RESULT_OK.
add in your OnActivityResult method:
if (resultCode != Result.Ok)
{
_mUploadMessage.OnReceiveValue(null);
_mUploadMessage = null;
return;
}
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.
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;
}
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();
}
}
Is there a way to conditionally load different user control as edit form based on some user action (Edit vs. Create)?
This is how I ended up doing it
protected void Page_Init(object sender, EventArgs e)
{
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.EditFormType = GridEditFormType.WebUserControl;
ctlBenefitLimitsGrid.ItemDataBound += BenefitLimitsGrid_ItemDataBound;
ctlBenefitLimitsGrid.ItemCommand += BenefitLimitsGrid_ItemCommand;
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.EditFormType = GridEditFormType.WebUserControl;
}
void BenefitLimitsGrid_ItemCommand(object source, GridCommandEventArgs e)
{
switch (e.CommandName)
{
case "Edit":
e.Item.OwnerTableView.IsItemInserted = false;
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.UserControlName =
#"UserControls/BenefitLimitEdit.ascx";
break;
case "Add":
{
InsertAddControl(e);
break;
}
case "Delete":
var benefitLimitId = Convert.ToInt32(e.CommandArgument);
Presenter.Delete(benefitLimitId);
Presenter.LoadView();
break;
case "Save":
IEditView item;
if (e.Item.GetType() == typeof(GridEditFormInsertItem))
{
item =
(IEditView)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
}
else
{
item = ((GridDataItem)e.Item).EditFormItem.FindControl(GridEditFormItem.EditFormUserControlID) as IEditView;
}
if (item != null && item.HasErrors)
{
e.Canceled = true;
return;
}
e.Item.Edit = false;
ctlBenefitLimitsGrid.MasterTableView.ClearEditItems();
Presenter.LoadView();
break;
case "SaveAndNew":
{
var benefitLimitCreate = (IBenefitLimitCreate)e.Item.FindControl(GridEditFormItem.EditFormUserControlID);
if (benefitLimitCreate.HasErrors)
{
e.Canceled = true;
return;
}
Presenter.LoadView();
InsertAddControl(e);
break;
}
}
}
private void InsertAddControl(GridCommandEventArgs e)
{
ctlBenefitLimitsGrid.MasterTableView.ClearEditItems();
ctlBenefitLimitsGrid.MasterTableView.EditFormSettings.UserControlName = #"UserControls/BenefitLimitCreate.ascx";
e.Item.OwnerTableView.InsertItem();
var insertedItem = e.Item.OwnerTableView.GetInsertItem();
var ctlBenefitLimitCreate = (BenefitLimitCreate)insertedItem.FindControl(GridEditFormItem.EditFormUserControlID);
ctlBenefitLimitCreate.Presenter.LoadView();
}
I think that there was an article in the Telerik online documentation (under Insert/Update/Delete -> HowTo chapter) which does exactly what you are after.
Dick