Xamarin WebView download doesn't work for Mp4Upload - c#

I have a small Xamarin form app that I want to use to download files from mp4Upload. This is done by loading the mp4Upload url onto a WebView and then programmatically clicking the download button using WebView.EvaluateJavascriptAsync().
The problem is that it doesn't trigger a download.
public class AndroidWebView : WebViewRenderer
{
public AndroidWebView(Context ctx) : base(ctx)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Settings.UserAgentString = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/20100101 Firefox/4.0";
}
Control.Download += DownloadEvent;
}
private void DownloadEvent(object sender, Android.Webkit.DownloadEventArgs e)
{
string url = e.Url;
DownloadManager.Request request = new DownloadManager.Request(Android.Net.Uri.Parse(url));
request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted);
request.SetDestinationInExternalPublicDir(Android.OS.Environment.DirectoryDownloads, "CPPPrimer");
DownloadManager dm = (DownloadManager)Android.App.Application.Context.GetSystemService("download");
dm.Enqueue(request);
Toast.MakeText(Android.App.Application.Context, e.Url, ToastLength.Long).Show();
}
}
I've tested the above code with a github url to download a random .gitignore file which works fine.
The mp4Upload link also works in chrome if I manually click download as well as working on winforms using cefsharp using ChromiumWebBrowser.ExecuteScriptAsync() to programmatically click download.
Does anyone know how to fix this issue?

It's not as simple as it looks, especially for downloads that open in a _blank target. This is the code I used in one of my projects:
Setup your webview to support downloads:
using Xamarin.Forms;
using Android.Webkit;
using Android.Content;
using System.Threading.Tasks;
using Xamarin.Forms.Platform.Android;
// In your android webview renderer
protected override void OnElementChanged(ElementChangedEventArgs<XamWebView> e)
{
base.OnElementChanged(e);
if (this.Control != null)
{
var xamWebView = (AppWebView)e.NewElement;
this.AllowFileDownloads(this.Control, xamWebView);
}
}
private void AllowFileDownloads(DroidWebView webView, AppWebView customWebView)
{
webView.Settings.SetSupportMultipleWindows(false);
var downloadListener = new WebViewDownloadListener(this.Context);
webView.SetDownloadListener(downloadListener);
}
Use this as your webview download listener
using System;
using Android.App;
using Android.Widget;
using Android.Webkit;
using Android.Content;
using Xamarin.Essentials;
public class WebViewDownloadListener : Java.Lang.Object, IDownloadListener
{
private Context AppContext { get; }
public event Action<string> OnDownloadStarted;
private DownloadManager DownloadManager => DownloadManager.FromContext(this.AppContext);
public WebViewDownloadListener(Context appContext)
{
this.AppContext = appContext;
this.AppContext.RegisterReceiver(new OnDownloadCompleteOpenFileInDefaultApp(), new IntentFilter(DownloadManager.ActionDownloadCom
}
public void OnDownloadStart(string url, string userAgent, string contentDisposition, string mimetype, long contentLength)
{
this.OnDownloadStarted?.Invoke(url);
var downloadRequest = BuildDownloadRequest(url, userAgent, contentDisposition, mimetype);
AppErrorHandler.ExecuteSafely(async () =>
{
if (ShouldAskPermissionToSaveFile)
{
var permission = await Permissions.RequestAsync<Permissions.StorageWrite>();
if (permission == PermissionStatus.Granted)
this.EnqueueDownloadRequest(downloadRequest);
}
else
this.EnqueueDownloadRequest(downloadRequest);
});
}
private static bool ShouldAskPermissionToSaveFile => Android.OS.Build.VERSION.SdkInt <= Android.OS.BuildVersionCodes.P;
private void EnqueueDownloadRequest(DownloadManager.Request downloadRequest)
{
this.DownloadManager.Enqueue(downloadRequest);
Toast.MakeText(this.AppContext, "Downloading File", ToastLength.Long).Show();
}
private static DownloadManager.Request BuildDownloadRequest(string url, string userAgent, string contentDisposition, string mimetype)
{
var request = new DownloadManager.Request(Android.Net.Uri.Parse(url));
request.SetMimeType(mimetype);
request.SetDescription("Downloading file...");
request.AddRequestHeader("User-Agent", userAgent);
request.AddRequestHeader("cookie", CookieManager.Instance.GetCookie(url));
request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted);
request.SetDestinationInExternalPublicDir(
Android.OS.Environment.DirectoryDownloads,
URLUtil.GuessFileName(url, contentDisposition, mimetype)
);
return request;
}
}
And finally, this as your download broadcast receiver
using Java.IO;
using Android.App;
using Android.Widget;
using Android.Content;
using Android.Database;
using AndroidX.Core.Content;
public class OnDownloadCompleteOpenFileInDefaultApp : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (DownloadManager.ActionDownloadComplete.Equals(intent.Action))
{
ICursor cursor = GetDbCursorForDownloadedFile(context, intent);
if (cursor.MoveToFirst())
{
var (downloadStatus, downloadUri, mimeType) = ExtractDataFromCursor(cursor);
if (downloadStatus == (int)DownloadStatus.Successful && downloadUri != null)
{
var fileUri = GetFileUri(context, downloadUri);
var openFileIntent = CreateOpenFileIntent(mimeType, fileUri);
LaunchOpenFileIntent(context, openFileIntent);
}
}
cursor.Close();
}
}
private static ICursor GetDbCursorForDownloadedFile(Context context, Intent intent)
{
var downloadManager = DownloadManager.FromContext(context);
var downloadId = intent.GetLongExtra(DownloadManager.ExtraDownloadId, 0);
var query = new DownloadManager.Query();
query.SetFilterById(downloadId);
var cursor = downloadManager.InvokeQuery(query);
return cursor;
}
private static (int status, string downloadUri, string mimeType) ExtractDataFromCursor(ICursor cursor) =
(
cursor.GetInt(cursor.GetColumnIndex(DownloadManager.ColumnStatus)),
cursor.GetString(cursor.GetColumnIndex(DownloadManager.ColumnLocalUri)),
cursor.GetString(cursor.GetColumnIndex(DownloadManager.ColumnMediaType))
);
private static Android.Net.Uri GetFileUri(Context context, string downloadUri)
{
var fileUri = Android.Net.Uri.Parse(downloadUri);
if (ContentResolver.SchemeFile.Equals(fileUri.Scheme))
{
// FileUri - Convert it to contentUri.
File file = new File(fileUri.Path);
fileUri = FileProvider.GetUriForFile(context, $"{context.PackageName}.fileprovider", file);
}
return fileUri;
}
private static Intent CreateOpenFileIntent(string mimeType, Android.Net.Uri fileUri)
{
Intent openAttachmentIntent = new Intent(Intent.ActionView);
openAttachmentIntent.SetDataAndType(fileUri, mimeType);
openAttachmentIntent.SetFlags(ActivityFlags.GrantReadUriPermission);
return openAttachmentIntent;
}
private static void LaunchOpenFileIntent(Context context, Intent openAttachmentIntent)
{
try
{
context.StartActivity(openAttachmentIntent);
}
catch (ActivityNotFoundException)
{
Toast.MakeText(context, "Could not open file.", ToastLength.Long).Show();
}
}
}

Related

How to stream web cam per ASP.Net Core WebApi

I try to create an endpoint which delivers a live stream of my webcam. I´m using AForge to access the camera, but I can´t manage to create and return a stream that actually renders in a video tag in the html client.
Additionally: The MemoryStream I'm using growes every second. And that is definitly not what I want.
What I tried so far:
Cam.cs:
public class Cam
{
MemoryStream stream = new MemoryStream();
public Cam()
{
FilterInfoCollection videoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
VideoCaptureDevice finalVideo = new VideoCaptureDevice(videoCaptureDevices[0].MonikerString);
finalVideo.NewFrame += this._streamNewFrame;
finalVideo.Start();
}
private void _streamNewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
{
System.Drawing.Image imgforms = (Bitmap)eventArgs.Frame.Clone();
imgforms.Save(this.stream, ImageFormat.Bmp);
this.stream.Seek(0, SeekOrigin.Begin);
}
public Stream GetStream()
{
MemoryStream stream = new MemoryStream();
this.stream.CopyTo(stream);
return stream;
}
}
CamController.cs:
[ApiController]
[Route("[controller]")]
public class CamController : ControllerBase
{
private readonly Cam cam;
public CamController(Cam cam)
{
this.cam = cam;
}
[HttpGet]
public IActionResult Get()
{
var contentType = "multipart/x-mixed-replace;boundary=myboundary";
Stream stream = this.cam.GetStream();
var result = new FileStreamResult(stream, contentType)
{
EnableRangeProcessing = true,
};
return result;
}
}
Update 1:
I made progress. I managed to create a valid MJPEP stream (it is pretty easy if know how it has to look like). Look at that:
CamController.cs:
using Microsoft.AspNetCore.Mvc;
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace demo.Controllers
{
[ApiController]
[Route("[controller]")]
public class CamController : ControllerBase
{
private readonly Cam cam;
public CamController(Cam cam)
{
this.cam = cam;
}
[HttpGet]
[Route("cam/video")]
public async Task Get()
{
Response.ContentType = "video/webm";
// How to go on here?
}
[HttpGet]
[Route("cam/mjepg")]
public async Task Get2()
{
Response.StatusCode = 206;
Response.ContentType = "multipart/x-mixed-replace; boundary=frame";
Response.Headers.Add("Connection", "Keep-Alive");
StreamingSession session = this.cam.StreamOn(data =>
{
if (Request.HttpContext.RequestAborted.IsCancellationRequested)
{
throw new Exception();
}
Response.Body.Write(this.CreateHeader(data.Length));
Response.Body.Write(data);
Response.Body.Write(this.CreateFooter());
Response.Body.Flush();
});
await Response.StartAsync();
await session.WaitAsync();
}
/// <summary>
/// Create an appropriate header.
/// </summary>
/// <param name="length"></param>
/// <returns></returns>
private byte[] CreateHeader(int length)
{
string header =
"--frame" + "\r\n" +
"Content-Type:image/jpeg\r\n" +
"Content-Length:" + length + "\r\n\r\n";
return Encoding.ASCII.GetBytes(header);
}
private byte[] CreateFooter()
{
return Encoding.ASCII.GetBytes("\r\n");
}
}
}
Cam.cs:
using AForge.Video.DirectShow;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace demo
{
public class Cam
{
object locker = new object();
bool signaledToStop = false;
List<StreamingSession> sessions = new List<StreamingSession>();
VideoCaptureDevice finalVideo;
public Cam()
{
FilterInfoCollection videoCaptureDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
finalVideo = new VideoCaptureDevice(videoCaptureDevices[0].MonikerString);
finalVideo.VideoResolution = finalVideo.VideoCapabilities
.OrderByDescending(x => x.MaximumFrameRate)
.ThenByDescending(x=>x.FrameSize.Width)
.FirstOrDefault();
finalVideo.NewFrame += this._streamNewFrame;
}
private void _streamNewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
{
System.Drawing.Image imgforms = (Bitmap)eventArgs.Frame.Clone();
byte[] data = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
imgforms.Save(stream, ImageFormat.Jpeg);
data = stream.ToArray();
}
lock (this.locker)
{
foreach (var session in sessions.ToList())
{
session.ProvideData(data);
}
}
}
public StreamingSession StreamOn(Action<byte[]> callback)
{
StreamingSession session = new StreamingSession(callback);
lock (this.locker)
{
this.sessions.Add(session);
if (this.signaledToStop)
{
this.finalVideo.WaitForStop();
}
if (!this.finalVideo.IsRunning)
{
this.finalVideo.Start();
this.signaledToStop = false;
}
}
session.OnSessionEnded += Session_OnSessionEnded;
return session;
}
private void Session_OnSessionEnded(object sender, EventArgs e)
{
lock(this.locker)
{
this.sessions.Remove(sender as StreamingSession);
if (!this.sessions.Any())
{
this.finalVideo.SignalToStop();
this.signaledToStop = true;
}
}
}
}
public class StreamingSession
{
public StreamingSession(Action<byte[]> Callback)
{
this.Callback = Callback;
}
private Action<byte[]> Callback;
private TaskCompletionSource Completion = new TaskCompletionSource();
public event EventHandler OnSessionEnded;
public Task WaitAsync(int? timeout = null)
{
if (timeout.HasValue)
{
return Task.WhenAny(Task.Delay(timeout.Value), this.Completion.Task);
}
return this.Completion.Task;
}
public void ProvideData(byte[] data)
{
try
{
this.Callback(data);
}
catch(Exception)
{
this.EndSession();
}
}
public void EndSession()
{
this.Completion.SetResult();
if (this.OnSessionEnded != null)
{
this.OnSessionEnded(this, null);
}
}
}
}
But there is a problem left: The "video" (more like moving images) only renders in an img tag. But it shall render in a video tag. I read that video tag doesn´t support mjpeg - but how can I encode the stream in a format the video tag understands?
I uploaded the complete code here: https://github.com/ChristophWieske/asp-net-core-live-stream-source
You may want to consider WebRTC.
WebRTC is a relatively new browser based technology that allows a server to send streams to a JavaScript client.
See the WebRTC Samples for client side code: https://github.com/webrtc/samples
Server side code is a bit more complex. Here's an overly complicated example that uses "Mixed Reality." It's a bit overboard, but should point you in the right direction.
https://microsoft.github.io/MixedReality-WebRTC/manual/cs/helloworld-cs-connection-core3.html

Xamarin Loop (Thread) in Foreground Service not continue when device is unplugged

Hi i've a problem getting location each 1-5 minutes with a Foreground Service, when I unplug the device and turn off the screen, the thread stops but the service notification is visible all time,
how can i prevent this?
i was reading about to use AlarmManager (is a real solution), how can i do it ? or should only foreground service do it by self
this is my code:
using Android.App;
using Android.Content;
using Android.Locations;
using Android.OS;
using Android.Text.Format;
using Invima.VehiculosApp.ViewModels;
using Java.Util;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xamarin.Essentials;
using Xamarin.Forms;
namespace Invima.VehiculosApp
{
[Service(Label = "LocationUpdatesService", Enabled = true, Exported = true)]
[IntentFilter(new string[] { "com.Antss.InvimaVehiculos.Service" })]
public class LocationService : Service
{
IBinder Binder;
public override IBinder OnBind(Intent intent)
{
return Binder;
}
public const int ServiceRunningNotifID = 9000;
Ruta ruta;
Thread hiloUbicacion;
private System.Timers.Timer timer;
public override void OnCreate()
{
Notification notif = DependencyService.Get<INotification>().ReturnNotif();
StartForeground(ServiceRunningNotifID, notif);
_ = TomarUbicaciones();
base.OnCreate();
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
string rutaStr = intent.GetStringExtra("ruta");
this.ruta = JsonConvert.DeserializeObject<Ruta>(rutaStr);
var autoEvent = new AutoResetEvent(false);
// i tried this but ... the same problem
timer = new System.Timers.Timer(30000);
timer.Elapsed += async (object sender, System.Timers.ElapsedEventArgs e) =>
{
using (HttpClient cl = new HttpClient())
{
await cl.GetAsync("https://webhook.site/a718fef4-769b-4871-87a8-ec1ccd83fc50");
}
};
timer.Start();
return StartCommandResult.Sticky;
}
public int TomarUbicaciones()
{
hiloUbicacion = new Thread(TomarUbicacionAsync);
hiloUbicacion.Start();
return 1;
}
int contador = 0;
public async void TomarUbicacionAsync()
{
while (true)
{
try
{
var request = new GeolocationRequest(GeolocationAccuracy.Medium);
var location = await Geolocation.GetLocationAsync(request);
if (location != null && ruta != null)
{
Console.WriteLine($"Latitude: {location.Latitude}, Longitude: {location.Longitude}, Altitude: {location.Altitude}");
App.BD.RutaUbicacion.Add(new RutaUbicacion
{
Fecha = DateTime.Now,
IdRuta = ruta.IdRuta,
Latitud = (decimal)location.Latitude,
Longitud = (decimal)location.Longitude,
Altitud = (decimal)location.Altitude
});
App.BD.SaveChanges();
App.Sincronizar();
}
Device.BeginInvokeOnMainThread(() =>
{
DependencyService.Get<IMessage>().ShortAlert("Done!");
});
}
catch (Exception ex)
{
}
Thread.Sleep(60000); // each minute
}
}
public override void OnDestroy()
{
try
{
hiloUbicacion.Abort();
}
catch { }
base.OnDestroy();
}
public override bool StopService(Intent name)
{
try
{
hiloUbicacion.Abort();
}
catch { }
return base.StopService(name);
}
}
}

How to download files in webview..?

My app would open browser to download files,but I want it to download in webview(Don't open browser to download).
I'm not good at app,plz give me complete codes as you can.
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Webkit;
using System.Net;
namespace REC
{
[Activity(Label = "ABC", MainLauncher = true, Icon = "#drawable/rec512", ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.ScreenSize)]
public class MainActivity : Activity
{
private WebView mWebView;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
RequestWindowFeature(WindowFeatures.NoTitle);
SetContentView(Resource.Layout.Main);
mWebView = FindViewById<WebView>(Resource.Id.webview);
mWebView.Settings.SetRenderPriority(WebSettings.RenderPriority.High);
mWebView.Settings.JavaScriptEnabled = true;
mWebView.SetWebChromeClient(new WebChromeClient());
mWebView.LoadUrl("http://www.mywebsite");
mWebView.SetDownloadListener(new MyDownloadListerner(this));
mWebView.SetWebViewClient(new WebViewClient());
}
class MonkeyWebChromeClient : WebChromeClient
{
public override bool OnJsAlert(WebView view, string url, string message, JsResult result)
{
return base.OnJsAlert(view, url, message, result);
}
public override Boolean OnJsConfirm(WebView view, String url, String message, JsResult result)
{
return base.OnJsConfirm(view, url, message, result);
}
public override Boolean OnJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
{
return base.OnJsPrompt(view, url, message, defaultValue, result);
}
}
public override bool OnKeyDown(Keycode keyCode, KeyEvent e)
{
if (keyCode == Keycode.Back && mWebView.CanGoBack())
{
mWebView.GoBack();
return true;
}
return base.OnKeyDown(keyCode, e);
}
}
public class WebClient : WebViewClient
{
public override bool ShouldOverrideUrlLoading(WebView view, string url)
{
//return base.ShouldOverrideUrlLoading(view, url);
view.LoadUrl(url);
return true;
}
internal object GetWebRequest(Uri address)
{
throw new NotImplementedException();
}
}
class MyDownloadListerner : Java.Lang.Object, IDownloadListener
{
Context cont;
public MyDownloadListerner(Context context)
{
cont = context;
}
public void OnDownloadStart(string url, string userAgent, string contentDisposition, string mimetype, long contentLength)
{
Android.Net.Uri uri = Android.Net.Uri.Parse(url);
Intent intent = new Intent(Intent.ActionView, uri);
cont.StartActivity(intent);
}
}
}
A necessary message
A necessary message
A necessary message
A necessary message

Xamarin iOS Perform Segue with Scandit

I am using a barcode scanner to grab a barcode and then I want to segue to my next screen right after that barcode is grabbed and I use that to find some specific data. The scanning works fine, and when the barcode is scanned The method DidScanBarcode is hit and runs through, is in this method that I try and perform my segue but the app either freezes or crashes without ever performing the segue and the method PrepareForSegue is never hit after the PerformSegue is run. Any thoughts?
using Foundation;
using System;
using System.CodeDom.Compiler;
using UIKit;
using RedLasterPrototype;
using System.Threading.Tasks;
using CoreGraphics;
using ZXing.Mobile;
using ScanditSDK;
namespace Prototype
{
partial class ScanViewController : UIViewController
{
public static ProductElement ScannedProduct { get; set; }
ScanditDelegate scanditDelegate;
public static string appKey = "xxxxx";
public ScanViewController(IntPtr handle) : base (handle)
{
}
public async override void ViewDidLoad()
{
var picker = new ScanditSDK.SIBarcodePicker (appKey);
scanditDelegate = new ScanditDelegate ();
picker.OverlayController.Delegate = scanditDelegate;
PresentViewController (picker, true, null);
picker.StartScanning ();
}
public static ProductElement GetScannedData(string upc)
{
var _service = new RestService ();
var data = _service.GetDataFromUpc (upc);
if (data != null)
{
return data;
}
return null;
}
public override void PrepareForSegue (UIStoryboardSegue segue, NSObject sender)
{
base.PrepareForSegue (segue, sender);
if (segue.Identifier == "SegueToProductPage")
{
var destination = (ScannedProductViewController)segue.DestinationViewController;
destination.product = ScannedProduct;
}
}
public class ScanditDelegate : SIOverlayControllerDelegate
{
public override void DidScanBarcode (SIOverlayController overlayController, NSDictionary barcode) {
// perform actions after a barcode was scanned
Console.WriteLine ("barcode scanned: {0}, '{1}'", barcode["symbology"], barcode["barcode"]);
var code = barcode ["barcode"].ToString();
if(code != null)
{
ScannedProduct = GetScannedData (code);
var x = new ScanViewController (this.Handle);
x.PerformSegue ("SegueToProductPage", this);
}
}
public override void DidCancel (SIOverlayController overlayController, NSDictionary status) {
// perform actions after cancel was pressed
}
public override void DidManualSearch (SIOverlayController overlayController, string text) {
// perform actions after search was used
}
}
}
}

HTTPS call via HttpClient Getting 404 - NOT FOUND

I've been going crazy over this particular problem. What I am trying to do is make an HTTPS Call to the server after a user clicks the sign up button. The server must add the new user to the database and send me back a user key. I've tested the httpClient class with a local LAMP server without HTTPS. Works fine. When I try to connect to the productions server with SSL I GET A 404 - NOT FOUND. I have double checked that the URL, CONTENT and Authorization is formatted well. As a matter of facted I codded it in a console application and it connects to the production server every time. It just does not work with the windows phone emulator or my windows phone. Been monitoring everything with fiddler. I've also used the WebClient class to no avail. PLEASE HELP!
Code below!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JailBird_ProtoType.Models
{
// CLASS USED TO FORMAT OBJECT TO JSON STRING
public class TestUser
{
public string Name { set; get; }
public string Email { get; set; }
public string Password { set; get; }
public List<string> Roles = new List<string>();
}
}
using Microsoft.Phone.Net.NetworkInformation;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace JailBird_ProtoType.Services
{
public class UploadJsonService
{
private BackgroundWorker bw = new BackgroundWorker();
public BackgroundWorker GetBackGroundWorker { get { return bw; } }
private HttpClient client = new HttpClient();
private HttpClient GetClient { get { return client; } }
private HttpResponseMessage response;
public HttpResponseMessage GetResponseMessage { get { return response; } }
// SET THE UPLOAD URL
private string uploadURL;
public string SetUploadURL { set { uploadURL = value; } }
// SET THE STRING DATA UPLOAD VALUE
private string jsonValue ="";
public string SetJsonValue { set { jsonValue = value; } }
private HttpContent httpContent;
public HttpContent GetHttpContent { get { return httpContent; } set { httpContent = value; } }
// SET THE METHOD TYPE UPLOAD VALUE
private string Method = "POST";
public string SetMethod { set { Method = value; } }
// CONSRUCTOR
public UploadJsonService()
{
SetUpClass();
}
public UploadJsonService(string url, string data)
{
SetUploadURL = url;
SetJsonValue = data;
SetUpClass();
}
public UploadJsonService(string url, string method, string data)
{
SetUploadURL = url;
SetJsonValue = data;
SetMethod = method;
SetUpClass();
}
private void SetUpClass()
{
bw.DoWork += new DoWorkEventHandler(DoWork);
httpContent = new StringContent(jsonValue);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
}
public void StartUpload()
{
try
{
bw.RunWorkerAsync(); // RUN BACKGROUND WORKER
}
catch (Exception) { }
}
public void CancelUpload()
{
// CANCEL ALL WORKER TASKS
try
{
client.Dispose();
httpContent = null;
bw.CancelAsync();
}
catch (Exception) { }
}
public void SetHeader(string header, string value)
{
client.DefaultRequestHeaders.Add(header, value);
}
private async void DoWork(object sender, DoWorkEventArgs e)
{
if (isConnectionReady())
{
try
{
if (Method.ToLower() == "post")
{
response = await client.PostAsync(new Uri(uploadURL, UriKind.Absolute), httpContent);
}
else if (Method.ToLower() == "push")
{
response = await client.PutAsync(new Uri(uploadURL, UriKind.Absolute), httpContent);
}
// DO SOMETHING WITH THE RESPONSE HERE
}
catch (Exception)
{
//UPDATE THE UI THREAD HERE
Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
{
MessageBox.Show("Upload did not complete successfully. Check your connection settings.", "Something Went Wrong", MessageBoxButton.OK);
}));
}
}
else
{
//UPDATE THE UI THREAD HERE
Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
{
MessageBox.Show("Check your phone's connection settings", "No Network Connection", MessageBoxButton.OK);
}));
}
}
// METHOD USED TO CHECK FOR NETWORK CONNECTION
private bool isConnectionReady()
{
bool internet = false;
//Check if network is available
if (DeviceNetworkInformation.IsNetworkAvailable)
{
internet = true;
}
return internet;
}
}
}
// THIS METHOD IS ACTIVATED IN THE SIGNUP BUTTON EVENT HANDLER
public void SendToServer()
{
// string user = JsonConvert.SerializeObject(App.ViewModel.Users[0]); // Get User Information
TestUser me = new TestUser() { Name="testName2", Password="password",Email="mail#mail.com"};
me.Roles.Add("User");
string meString = JsonConvert.SerializeObject(me);
if (App.Settings.Contains("FirstSignUp"))
{
service = new UploadJsonService(ConnectToServer.USER_UPLOAD_URL,"PUT",meString);
}
else
{
service = new UploadJsonService(ConnectToServer.USER_UPLOAD_URL,"POST",meString);
}
service.SetHeader("Authorization", "Basic " + ConnectToServer.Get64BitEncoding(ConnectToServer.SERVER_ADMIN));
service.GetBackGroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerServiceCompleted);
service.StartUpload();
}
private void RunWorkerServiceCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// DO WORK AFTER THE BACKGROUND WORKER COMPLETES
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JailBird_ProtoType.Services
{
// THIS CLASS HOLDS ALL SERVER INFORMATION
// FOR QUICK ACCESS AND CHANGE
public static class ConnectToServer
{
public static string SERVER_ADMIN = "admin:password";
// UPLOAD USER TO DB
public static string USER_UPLOAD_URL = "https://xx.xxx.xx.xxx:443/api/users";
public static string Get64BitEncoding(string key) {
byte[] convert = System.Text.Encoding.UTF8.GetBytes(key);
return System.Convert.ToBase64String(convert);
}
}
}
omitted real server address for security reasons.
Sorry my code is not structured Right. Been changing it around to get this to work.

Categories

Resources