I have a problem with my custom Dialog.
I want to show it while my application do something (in particular, creates a bitmap and does a HTTP request).
This is the portion of my code:
LoadingDialog myLoading = new LoadingDialog();
myLoading.Show()
TakePicture();
while (myPhotoFace == null) { }
Context context = Android.App.Application.Context;
if (Connectivity.isConnected(context))
{
byte[] bytePhoto;
using (var stream = new MemoryStream())
{
Constants.myGallery.Compress(Bitmap.CompressFormat.Jpeg, 40, stream);
bytePhoto = stream.ToArray();
}
byte[] byteFace;
using (var stream = new MemoryStream())
{
myPhotoFace.Compress(Bitmap.CompressFormat.Jpeg, 40, stream);
byteFace = stream.ToArray();
}
MediaEmotion myMedia = new MediaEmotion();
string token = Utils.utils.GetParametro("token");
myMedia.mediaID = 0;
myMedia.face = byteFace;
myMedia.photo = bytePhoto;
var client = new RestClient("https://myServer.net/");
var request = new RestRequest("/Controller/Method?token=" + token, Method.POST);
string json = JsonConvert.SerializeObject(myMedia);
request.AddParameter("stringaMediaEmotion", json);
IRestResponse response = client.Execute(request);
Object myObject = JsonConvert.DeserializeObject<Object>(response.Content.ToString());
[...]
After, I do something before start new activity.
As you can see, as a first operation I show my dialog (which, I verified, works correctly) but only appears as the last thing before moving on to the new activity. Also by simply trying to change the text of a textview the problem is the same.
Why? What is the problem? How can resolve this?
Try to put all the network related code inside an async task: you'll free the main thread from network operation and the popup will appear until you'll move to another activity.
You can find some good examples and documentation here https://blog.xamarin.com/getting-started-with-async-await/
Related
I want to know how I can display video from jpegs in Xamarin (all platforms).
My jpegs are being streamed from a http client stream sent by a popular video surveillance management software.
My jpegs are in the form of byte[] and I get about 10 jpegs/second. This format is imposed.
I tried rapidly changing the Source on a Image but it results in severe fliquering on Android. This seems to work on Windows phone but not so good performance.
How can I create a videoplayer for each one? Unless I am wrond, the existing components cannot do this.
Best,
Thank you Jason! Works great, very fluid rendering!!
Simply add the SkiaSharp.Views.Forms with NuGet to the project and voila!
Here is what that would look like in code (shared project):
// Content page initialization
private void InitUI() {
Title = "Xamavideo";
var button = new Button
{
Text = "Connect!"
};
Label label = new Label
{
Text = ""
};
var scroll = new ScrollView();
scroll.BackgroundColor = Color.Black;
Content = scroll;
var stack = new StackLayout
{
Padding = 40,
Spacing = 10
};
//Add a SKCanvasView item to the stack
var videoCanvas = new SKCanvasView
{
HeightRequest = 400,
WidthRequest = 600,
};
videoCanvas.PaintSurface += OnCanvasViewPaintSurface;
stack.Children.Add(videoCanvas);
}
//Create the event handler
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
// using (var stream = new SKManagedStream(fileStream))
if (lastFrame == null) return;
using (var canvas = surface.Canvas)
// use KBitmap.Decode to decode the byte[] in jpeg format
using (var bitmap = SKBitmap.Decode(lastFrame))
using (var paint = new SKPaint())
{
// clear the canvas / fill with black
canvas.DrawColor(SKColors.Black);
canvas.DrawBitmap(bitmap, SKRect.Create(640, 480), paint);
}
}
void UpdateFrame(VideoClient client){
//Use this to update the canvas:
byte[] lastFrame = client.imageBytes;
videoCanvas.InvalidateSurface();
}
I am using Itext library for android for converting html to pdf which is working fine but at certain things it is not parsing properly. I want to create a dotted line separator of red color but it is always gives me a solid line separator with dark gray color.
My html tag is
<hr noshade style="border: 0; width:100%;border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: red">
My conversion code
Document document = new Document(PageSize.A4);
//this sets the margin to the created pdf
document.setMargins(35, 35, 150, 100);
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream(fileWithinMyDir));
if (isPrescription) {
HeaderFooterPageEvent event = new HeaderFooterPageEvent();
writer.setPageEvent(event);
} else {
CertificateFooterPageEvent event = new CertificateFooterPageEvent();
writer.setPageEvent(event);
}
document.open();
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.setImageProvider(new AbstractImageProvider() {
public String getImageRootPath() {
Uri uri = Uri.parse("file:///android_asset/");
return uri.toString();
}
});
CSSResolver cssResolver =
XMLWorkerHelper.getInstance().getDefaultCssResolver(false);
// Pipelines
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
InputStream is = new ByteArrayInputStream(htmlString.getBytes());
XMLWorkerHelper.getInstance().parseXHtml(writer, document, is);
p.parse(is);
document.close();
I'm a .NET developer, so the code is in C#. But you should be able to easily translate the following.
iText is a PDF-first library, and [X]HTML parsing is quite complex so it's not full featured in that regard. Whenever parsing [X]HTML and things aren't going the way you expect for specific tags, the basic steps you should follow are:
Verify XML Worker supports the tag: Tags class.
If the tag is supported, which in this case is true, take a look at the default implementation. Here it's handled by the the HorizontalRule class. However, we see there's no support for your use case, so one way to go is use that code as a blueprint. (follows below) You can also inherit from the specific tag class and override the End() method as done here. Either way, all you're doing is implementing a custom tag processor.
If the tag is not supported, you need to roll your own custom tag processor by inheriting from AbstractTagProcessor.
Anyway, here's a simple example to get you started. First, the custom tag processor:
public class CustomHorizontalRule : AbstractTagProcessor
{
public override IList<IElement> Start(IWorkerContext ctx, Tag tag)
{
IList<IElement> result;
LineSeparator lineSeparator;
var cssUtil = CssUtils.GetInstance();
try
{
IList<IElement> list = new List<IElement>();
HtmlPipelineContext htmlPipelineContext = this.GetHtmlPipelineContext(ctx);
Paragraph paragraph = new Paragraph();
IDictionary<string, string> css = tag.CSS;
float baseValue = 12f;
if (css.ContainsKey("font-size"))
{
baseValue = cssUtil.ParsePxInCmMmPcToPt(css["font-size"]);
}
string text;
css.TryGetValue("margin-top", out text);
if (text == null) text = "0.5em";
string text2;
css.TryGetValue("margin-bottom", out text2);
if (text2 == null) text2 = "0.5em";
string border;
css.TryGetValue(CSS.Property.BORDER_BOTTOM_STYLE, out border);
lineSeparator = border != null && border == "dotted"
? new DottedLineSeparator()
: new LineSeparator();
var element = (LineSeparator)this.GetCssAppliers().Apply(
lineSeparator, tag, htmlPipelineContext
);
string color;
css.TryGetValue(CSS.Property.BORDER_BOTTOM_COLOR, out color);
if (color != null)
{
// WebColors deprecated, but docs don't state replacement
element.LineColor = WebColors.GetRGBColor(color);
}
paragraph.SpacingBefore += cssUtil.ParseValueToPt(text, baseValue);
paragraph.SpacingAfter += cssUtil.ParseValueToPt(text2, baseValue);
paragraph.Leading = 0f;
paragraph.Add(element);
list.Add(paragraph);
result = list;
}
catch (NoCustomContextException cause)
{
throw new RuntimeWorkerException(
LocaleMessages.GetInstance().GetMessage("customcontext.404"),
cause
);
}
return result;
}
}
Most of the code is taken directly from the existing source, with the exception of the checks for CSS.Property.BORDER_BOTTOM_STYLE and CSS.Property.BORDER_BOTTOM_COLOR to set border style and color if they're inlined in the <hr> style attribute.
Then you add the custom tag processor above to the XML Worker TagProcessorFactory:
using (var stream = new FileStream(OUTPUT_FILE, FileMode.Create))
{
using (var document = new Document())
{
var writer = PdfWriter.GetInstance(document, stream);
document.Open();
var tagProcessorFactory = Tags.GetHtmlTagProcessorFactory();
// custom tag processor above
tagProcessorFactory.AddProcessor(
new CustomHorizontalRule(),
new string[] { HTML.Tag.HR }
);
var htmlPipelineContext = new HtmlPipelineContext(null);
htmlPipelineContext.SetTagFactory(tagProcessorFactory);
var pdfWriterPipeline = new PdfWriterPipeline(document, writer);
var htmlPipeline = new HtmlPipeline(htmlPipelineContext, pdfWriterPipeline);
var cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(true);
var cssResolverPipeline = new CssResolverPipeline(
cssResolver, htmlPipeline
);
var worker = new XMLWorker(cssResolverPipeline, true);
var parser = new XMLParser(worker);
var xHtml = "<hr style='border:1px dotted red' />";
using (var stringReader = new StringReader(xHtml))
{
parser.Parse(stringReader);
}
}
}
One thing to note is that even though we're using the shorthand border inline style, iText's CSS parser appears to set all the styles internally. I.e., you can use any of the four longhand styles to check - I just happened to use CSS.Property.BORDER_BOTTOM_STYLE and CSS.Property.BORDER_BOTTOM_COLOR.
The resulting PDF:
You could use a div without any or with any content you want instead of an hr and give border style to that div, I am sure it will work in your case.
I am going through the Get Started tutorial for Microsoft's Face API for Android handhelds. As of right now, everything except for the recognition part works. I can browse through photos alright. However, the detect method somehow always returns null and so no red rectangle is drawn. If someone has already successfully gone through the tutorial, I would be grateful if you could help me. Here is the detect method:
public Face[] detect(InputStream image, boolean analyzesFaceLandmarks, boolean analyzesAge, boolean analyzesGender, boolean analyzesHeadPose) throws ClientException, IOException {
Map<String, Object> params = new HashMap<>();
params.put("analyzesAge", analyzesAge);
params.put("analyzesGender", analyzesGender);
params.put("analyzesFaceLandmarks", analyzesFaceLandmarks);
params.put("analyzesHeadPose", analyzesHeadPose);
String path = ServiceHost + "/detections";
String uri = WebServiceRequest.getUrl(path, params);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int bytesRead;
byte[] bytes = new byte[1024];
while ((bytesRead = image.read(bytes)) > 0) {
byteArrayOutputStream.write(bytes, 0, bytesRead);
}
byte[] data = byteArrayOutputStream.toByteArray();
params.clear();
params.put("data", data);
String json = this.restCall.request(uri, "POST", params, "application/octet-stream");
Type listType = new TypeToken<List<Face>>() {
}.getType();
List<Face> faces = this.gson.fromJson(json, listType);
return faces.toArray(new Face[faces.size()]);
}
It looks as if the code you have posted is fine. This makes me wonder if the issue might be with the InputStream you are passing in as the input parameter. It might be that having read the source into the InputStream the position of the stream is at the end and therefore when you read from it nothing is being uploaded to the api.
I was suggesting you check the amount of image data you are uploading:
byte[] data = byteArrayOutputStream.toByteArray();
int length = data.length; // <- what is this value?
It might be necessary to reset the stream position to the beginning before reading it again. Something like this may be required before reading from image
if(image.markSupported())
{
image.reset();
}
BTW, my java is very rusty so there might be better code to use but hopefully you get the gist.
My scenario is I have to make available download link for web, android mobile app and tablet app. where as android and tablet app developers accessing my dot net web API. my web application is in MVC. so what should be approach i should use for this scenario? How can I response as PDF file from my web API ? it is possible?
Edited 1:
byte[] urlContents = response1.Content.ReadAsByteArrayAsync().Result;
string s = GetString(urlContents);
iTextSharp.text.Document document = new iTextSharp.text.Document();
MemoryStream stream = new MemoryStream();
try
{
PdfWriter pdfWriter = PdfWriter.GetInstance(document, stream);
pdfWriter.CloseStream = false;
document.Open();
document.Add(new Paragraph(s));
}
return File(stream, "application/pdf", "DownloadName.pdf");.
---------------------------------------------------------------------
Edit 2
var document = new iTextSharp.text.Document(PageSize.A4);
document.SetMargins(20.0F, 20.0F, document.TopMargin + 20, document.BottomMargin);
var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);
document.Open();
StringReader strRdr = new StringReader(htmlString);
var parsedHtmlElements = HTMLWorker.ParseToList(strRdr, null);
foreach (var htmlElement in parsedHtmlElements)
document.Add(htmlElement as IElement);
writer.Flush();
output.Seek(0, SeekOrigin.Begin);
//document.Close();
return File(output, "application/pdf","somefilename");
To return a PDF from a ASP.net WebAPI project (Or any file for that matter) you can return the bytes via byte array in a HttpResponseMessage while setting the ContentDisposition header to "attachment".
For example:
//Web API Controller GET
public HttpResponseMessage Get()
{
//Do something here to generate your pdf
byte[] fileToReturn = pdf.GenerateImagePDF();
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new ByteArrayContent(fileToReturn);
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = "SomeFileName";
return response;
}
// MVC Controller Action - Reading the PDF from WebAPI and returning to browser
public ActionResult SomeAction() {
HttpResponseMessage response = httpClient.GetAsync([BuildYourURLtoWebAPIHere]).Result;
Task<Stream> streamTask = response.Content.ReadAsStreamAsync();
Stream stream = streamTask.Result; //blocks until Task is completed
byte[] bytes;
using (BinaryReader br = new BinaryReader(stream))
{
bytes = br.ReadBytes((int)stream.Length);
}
return File(bytes, "application/pdf");
}
If your question was really about generating the actual PDF, then you should search for the many free or commercial PDF libraries.
I am passing parameters and receiving a lot of values back from my webservices one of these values is a string that was suposed to be "Açougue" but im getting something different from that something like "A┌ougue". What can i do to make my app to be able to set that word right?
var request2 = new RestRequest (String.Format("?param1={0}¶m2={1}", (int)CGI_FUNC.GETSERVICOS, classGlobalVars.usuario));
asyncHandle = client.ExecuteAsync (request2, response => {
servicoLista = new List<objectServico> ();
Console.WriteLine("Something: "+response.ContentEncoding);
if (response.Content != "") {
}
});
So tried changing my response.ContentEncoding to "utf-8" or something but it didnt worked.
Thanks for all the help. ^^
try this:
var request2 = new RestRequest ();
request2.AddParameter("text/xml; charset=utf-8", String.Format("?param1={0}¶m2={1}", (int)CGI_FUNC.GETSERVICOS, classGlobalVars.usuario), ParameterType.RequestBody);
asyncHandle = client.ExecuteAsync (request2, response => {
servicoLista = new List<objectServico> ();
Console.WriteLine("Something: "+response.ContentEncoding);
if (response.Content != "") {
}
});;