Async ImageView in MonoDroid - xamarin.android

Can anybody give me an example how I would download an image asynchroniously and display it in an ImageView in MonoDroid.
Im tyring to port an project from MonoTouch to MonoDroid, but I'm having quite some problems with this part...

Maybe this is what you are looking for:
public class Activity1 : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
this.SetContentView(Resource.Layout.layout1);
WebClient web = new WebClient();
web.DownloadDataCompleted += new DownloadDataCompletedEventHandler(web_DownloadDataCompleted);
web.DownloadDataAsync(new Uri(#"http://your.image.com"));
}
void web_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
Bitmap bm = BitmapFactory.DecodeByteArray(e.Result, 0, e.Result.Length);
FindViewById<ImageView>(Resource.Layout.layout1).SetImageBitmap(bm);
}
}
I haven't tested this one, but I think it should do the job :)
/Nicklas

Related

Xamarin MvvmCross: iOS how to monitor the app has move to foreground/background

I have an MvvmCross application, and I am using the MvvmCross ViewModel Lifecycle functions to realize
certain actions when the view appears, moves to background, and moves to foreground:
public override async void ViewAppeared()
public override async void ViewAppearing()
public override void ViewDisappearing()
public override void ViewDisappeared()
public override void ViewDestroy(bool viewFinishing)
Those functions work great in my Android device.
But for iOS they do not get fired when the application moves to background or to foreground
(although, except for ViewDestroy, they fire when navigating between the screens in the app in iOS)
1)Is that the intended behavior, or I am missing something?
2)If so, what is the approach we have to follow, when there are actions that we need to do when the app moves to foreground/background (like stopping timers)?
Should we maybe have two implementations one for android, and one for ios? I also tried the ViewDidDisappear method in the MvxBaseViewController,
still it is not activated when the app moves to background. There is a way in Xamarin/MvvmCross to hook into the native ios applicationDidEnterBackground?
Edit:
I have tried Ranjit´s answer, but it seems to be a problem subscribing to the message. Here is my test code:
AppDelegate.cs:
public override void DidEnterBackground(UIApplication application)
{
base.DidEnterBackground(application);
var message = new LocationMessage(
this,
34
);
_messenger = Mvx.IoCProvider.Resolve<IMvxMessenger>();
_messenger.Publish(message);
}
Base class:
public abstract class GenericMvxViewModel : MvxViewModel
{
private IMvxMessenger _messenger;
protected GenericMvxViewModel()
{
// other stuff
_messenger = Mvx.IoCProvider.Resolve<IMvxMessenger>();
_messenger.Subscribe<LocationMessage>(OnLocationMessage);
}
protected virtual void OnLocationMessage(LocationMessage locationMessage){}
}
ViewModel:
public class MyClassViewModel : GenericMvxViewModel
{
protected override void OnLocationMessage(LocationMessage locationMessage)
{
Debug.WriteLine(locationMessage.Lat);
}
}
The message is published in the AppDelegate.cs, but the OnLocationMessage method in the viewmodel is never executed.
Also I was wondering how to unsubscribe properly the message. ViewDestroy seems the most natural place, but as mentioned before it is never called on iOS
Your code should work. I am using same kind of function in my app it was working fine
GenericMvxViewModel Code
private MvxSubscriptionToken _locationEventToken;
public override void ViewAppeared()
{
SubscribeBaseLocationEvent();
base.ViewAppeared();
}
public override void ViewDisappeared()
{
if (StaticStorage.IsApplicationInForeground)
{
UnSubscribeBaseLocationEvent();
}
base.ViewDisappeared();
}
public void SubscribeBaseLocationEvent()
{
if (_locationEventToken == null)
{
_locationEventToken = Messenger.Subscribe<LocationMessage>(OnLocationMessage);
}
}
public void UnSubscribeBaseLocationEvent()
{
if (_locationEventToken != null)
{
Messenger.Unsubscribe<LocationMessage>(_locationEventToken);
_locationEventToken = null;
}
}
AppDelegate Code
public override void DidEnterBackground(UIApplication application)
{
base.DidEnterBackground(application);
StaticStorage.IsApplicationInForeground = false;
_messenger.Publish(new LocationMessage( this, 34 ));
}
public override void WillEnterForeground(UIApplication application)
{
StaticStorage.IsApplicationInForeground = true;
}
Android
protected override void OnResume()
{
StaticStorage.IsApplicationInForeground = true;
base.OnResume();
}
protected override void OnStop()
{
StaticStorage.IsApplicationInForeground = false;
base.OnStart();
}
When application is moving from one view to other view, we need to unsubscribe the event. But not when application moves to background. So, IsApplicationInForeground flag will help to solve this issue for android. Because for android when application goes to background ViewDisappeared will be called.
In my case. I have one common activity which holds remaining all views of fragment. So, I have added this code in common activity. Not sure in your case how you are using. But implementation will be similar.

How do you send message using NFC with Xamarin.Android?

I am developing and app to demostrate how NFC works. My goal is to make and app that will work very similary to Android Beam. I am using Xamarin.Android. The goal is to type message to one device, press button and it should be send to another device with the same app where it should be shown. I have tried almost everything even the documentation but it seems like it doesnt work. Does anyone have any experience with this technology? Is this technology even available nowadays?
There is some of my code to get you an idea about what i am trying to do:
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
mNfcAdapter = NfcAdapter.GetDefaultAdapter(this);
myButton.Click += (e, o) => {
mNfcAdapter.SetNdefPushMessageCallback(this, this);
mNfcAdapter.SetOnNdefPushCompleteCallback(this, this);
};
}
public NdefMessage CreateNdefMessage(NfcEvent e)
{
DateTime time = DateTime.Now;
var text = (time.ToString("HH:mm:ss") + message2);
NdefMessage msg = new NdefMessage(
new NdefRecord[] { CreateMimeRecord (
text, Encoding.UTF8.GetBytes (text))});
return msg;
}
private NdefRecord CreateMimeRecord(string mimeType, byte[] payload)
{
byte[] mimeBytes = Encoding.UTF8.GetBytes(mimeType);
NdefRecord mimeRecord = new NdefRecord(
NdefRecord.TnfMimeMedia, mimeBytes, new byte[0], payload);
return mimeRecord;
}
public void OnNdefPushComplete(NfcEvent e)
{
Toast.MakeText(this.ApplicationContext, "Message sent", ToastLength.Long).Show();
}
protected override void OnResume()
{
base.OnResume();
if (NfcAdapter.ActionNdefDiscovered == Intent.Action)
{
ProcessIntent(Intent);
}
}
protected override void OnNewIntent(Intent intent)
{
Intent = intent;
}
void ProcessIntent(Intent intent)
{
IParcelable[] rawMsgs = intent.GetParcelableArrayExtra(
NfcAdapter.ExtraNdefMessages);
NdefMessage msg = (NdefMessage)rawMsgs[0];
var textViewMsg = FindViewById<TextView>(Resource.Id.textViewMsg);
textViewMsg.Text = Encoding.UTF8.GetString(msg.GetRecords()[0].GetPayload());
}
Thank you all :)
OnNdefPushComplete and the whole Android Beam was deprecated and removed from Android 10
https://developer.android.com/reference/android/nfc/NfcAdapter.OnNdefPushCompleteCallback
If you want to do Device to Device NFC going forward then it should be possible with one phone doing Host Card Emulation (HCE) and the other using enableReaderMode
But Google recommend using Bluetooth or Wifi Direct as a more reliable replacement for Android Beam. One of the replacement methods Google provided was Android Nearby https://developers.google.com/nearby

Need to print UWP MapControl with route results

I have a MapControl working just creating my route. Now, I just need to figure out a way to print it out. Using the UWP printing sample, I get a black box where the control should be. The map and route are being built, just not rendered correctly in the print preview. I thought I saw a MapControl.Print... but I think that was in the Bing.Maps stuff. Any pointers would be appreciated. Thanks.
Using the UWP printing sample, I get a black box where the control should be.
It seems the MapControl can not be printed.
As a workround, we can use RenderTargetBitmap to get the image from the MapControl. That we can print the image.
Using a RenderTargetBitmap, you can accomplish scenarios such as applying image effects to a visual that originally came from a XAML UI composition, generating thumbnail images of child pages for a navigation system, or enabling the user to save parts of the UI as an image source and then share that image with other apps.
Because RenderTargetBitmap is a subclass of ImageSource, it can be used as the image source for Image elements or an ImageBrush brush.
For more info,see RenderTargetBitmap.
For example:
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(MyMap);
MyImage.Source = renderTargetBitmap;
The printing code:
public sealed partial class MainPage : Page
{
private PrintManager printmgr = PrintManager.GetForCurrentView();
private PrintDocument printDoc = null;
private PrintTask task = null;
public MainPage()
{
this.InitializeComponent();
printmgr.PrintTaskRequested += Printmgr_PrintTaskRequested;
}
private void Printmgr_PrintTaskRequested(PrintManager sender, PrintTaskRequestedEventArgs args)
{
var deferral = args.Request.GetDeferral();
task = args.Request.CreatePrintTask("Print", OnPrintTaskSourceRequrested);
task.Completed += PrintTask_Completed;
deferral.Complete();
}
private void PrintTask_Completed(PrintTask sender, PrintTaskCompletedEventArgs args)
{
//the PrintTask is completed
}
private async void OnPrintTaskSourceRequrested(PrintTaskSourceRequestedArgs args)
{
var def = args.GetDeferral();
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
() =>
{
args.SetSource(printDoc?.DocumentSource);
});
def.Complete();
}
private async void appbar_Printer_Click(object sender, RoutedEventArgs e)
{
if (printDoc != null)
{
printDoc.GetPreviewPage -= OnGetPreviewPage;
printDoc.Paginate -= PrintDic_Paginate;
printDoc.AddPages -= PrintDic_AddPages;
}
this.printDoc = new PrintDocument();
printDoc.GetPreviewPage += OnGetPreviewPage;
printDoc.Paginate += PrintDic_Paginate;
printDoc.AddPages += PrintDic_AddPages;
bool showPrint = await PrintManager.ShowPrintUIAsync();
}
private void PrintDic_AddPages(object sender, AddPagesEventArgs e)
{
printDoc.AddPage(this);
printDoc.AddPagesComplete();
}
private void PrintDic_Paginate(object sender, PaginateEventArgs e)
{
PrintTaskOptions opt = task.Options;
printDoc.SetPreviewPageCount(1, PreviewPageCountType.Final);
}
private void OnGetPreviewPage(object sender, GetPreviewPageEventArgs e)
{
printDoc.SetPreviewPage(e.PageNumber, this);
}
}

How can I get FilePicker working properly on certain BlackBerry handsets?

I'm implementing a Filepicker in my app to allow users to choose photos from their phones. The code I'm using is as follows:
Calling the Filepicker:
try
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
FilePicker fp = FilePicker.getInstance();
fileListener = new FilePickListener();
fp.setListener(fileListener);
fp.show();
}
});
}
catch (Exception e)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Please check your data card..");
}
});
}
And the method to get the filename in my FilePickListener:
public void selectionDone(String str)
{
this.currFileName = str;
int index = str.lastIndexOf('/');
Dialog.alert("Filename: "+str.substring(index+1).trim());
}
This works perfectly in most handsets that I've tried it on (which have been a mix of handsets with some running OS5 and some running OS6). But on some, like the 8900 (running OS v5.0.0.411) it doesn't work properly. The Filepicker gets called and appears, but when any file gets selected, the selectionDone method doesn't get called. I've tested it on two separate 8900s and both have the same problem.
Does anyone have an idea why it works on certain handsets and not other?
You are a victim of a known RIM issue: FilePicker throws ControlledAccessException.
The issue is marked as "Fixed". However there is no info in which OS version they fixed it. (Is it so difficult to tell such a useful info?)
But from the comments to the issue:
We experience the very same issue with OS 5.0.0.321 on a Bold 9700. However, the issue does NOT appear on OS 5.0.0.464
so my guess would be they fixed it in OS 5.0.0.464. But that's not the end - in OS 6 FilePicker appears broken in early versions of OS 6 again. The conclusion - just don't use it. Use a custom file browser screen to pick a file. There is a sample in SDK 4.7.0 named FileExplorerDemo, check it for implementation details.
This is a known issue. FilePicker does not open on some devices and return an error, like the 8900 device. You can catch this error on some devices by adding the catch (Error e) { }
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
FilePicker fp = FilePicker.getInstance();
fileListener = new FilePickListener();
fp.setListener(fileListener);
fp.show();
}
});
}
catch (Exception e)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("Please check your data card..");
}
});
}
catch (Error e)
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
Dialog.alert("This device does not support File Picker");
}
});
}

Nice code template for windows service

Any links to a good template for a windows service? (looking for C# code)
Something that has the basic functionality that I could extend.
It is a little clear what you are looking for. The Windows Service project type in Visual Studio creates a project with the templates you need to get going with a basic windows service.
You can also look at this article from C# Online. It goes over a few ideas and has a few parts to the article. (Note; the page seems to loads a little slow so be patient)
I use VS2005 and I like to start with the basic template.
Modify the Service class to this
using System;
using System.ServiceProcess;
using System.Timers;
namespace WindowsService1
{
public partial class Service1 : ServiceBase
{
//better is to read from settings or config file
private readonly Double _interval = (new TimeSpan(1, 0, 0, 0)).TotalMilliseconds;
private Timer m_Timer;
public Service1()
{
InitializeComponent();
Init();
}
private void Init()
{
m_Timer = new Timer();
m_Timer.BeginInit();
m_Timer.AutoReset = false;
m_Timer.Enabled = true;
m_Timer.Interval = 1000.0;
m_Timer.Elapsed += m_Timer_Elapsed;
m_Timer.EndInit();
}
private void m_Timer_Elapsed(object sender, ElapsedEventArgs e)
{
//TODO WORK WORK WORK
RestartTimer();
}
private void RestartTimer()
{
m_Timer.Interval = _interval;
m_Timer.Start();
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
Start();
}
protected override void OnStop()
{
Stop();
base.OnStop();
}
public void Start()
{
m_Timer.Start();
}
public new void Stop()
{
m_Timer.Stop();
}
}
}
Install using InstallUtil.exe, after you have added an installer : http://msdn.microsoft.com/en-us/library/ddhy0byf(VS.80).aspx
Keep the Init function small and fast, otherwise your service will not start with an error that the service did not respond in a timely fashion
Hope this helps

Resources