简体   繁体   中英

Using NFC with Mvx WP8 Application

I am attempting to use NFC in an Windows Phone 8 application, which uses the MvvmCross framework. Now normally you subscribe to receive NFC events on WP8 by adding an Extension to the WMAppManifest.xml like so:

<Extensions>
    <Protocol Name="my-resource" NavUriFragment="encodedLaunchUri=%s" TaskId="_default" />
</Extensions>

This will launch the _default task, if it finds a uri starting with my-resource:// , which on a fresh project is the MainPage.xaml . In this case I have set it to Views\\ScanView.axml , which is a MvxPhonePage .

Then to get the data in the _default task, you would override OnNavigatedTo and grab the e.Uri , which is the data from the NFC tag. Ie: /Protocol?encodedLaunchUri=my-resource://ni?EkkeEkkeEkkeEkkePtangyaZiiinngggggggNi .

Now it seems that the MvxPhonePage overrides OnNavigatedTo on its own and uses it for some save states. So my question is. How do I get original Uri instead of the saved state?

Can I just work around it by using the MainPage.axml and then when I am done loading the NFC stuff navigate to Views\\ScanView.axml ?

I solved the problem by creating a custom AppStart which is briefly described in this Slide Deck , which Stuart Lodge told me to look at.

So in my ScanViewModel I added an Init(string url) method, which handles navigation with extra parameters, in this case my wanted Url, and then I can handle it as I want there.

In App.xaml.cs where you normally call the Start() method of the AppStart I added some conditions:

var start = Mvx.Resolve<IMvxAppStart>();
var url = navigatingCancelEventArgs.Uri.ToString();
if(url.StartsWith(@"/Protocol?encodedLaunchUri=my-resource")
    start.Start(url.SubString("/Protocol?encodedLaunchUri=".Length));
else
    start.Start();

Then I had to create my own AppStart :

public class MyCustomAppStart : MvxNavigatingObject, IMvxAppStart
{
    public void Start(object hint = null)
    {
        if(hint is string)
            ShowViewModel<ScanViewModel>(new {url = (string)hint});
        else
            ShowViewModel<ScanViewModel>();
    }
}

Which I instantiate in the MvxApplcation Initialize method:

RegisterAppStart(new MyCustomAppStart());

Then I get the desired Url in Init in the ViewModel:

public void Init(string url)
{
    //Whatever I want, whatever I need
}

Another alternative is to define a custom UriMapper to catch and validate the external launch URI, and then return the URI of the actual page you want to launch. That way you keep the external launch logic away from your page navigation logic.

See UriMapperBase docs for the basics. You'll need to add the UriMapper to your PhoneApplicationFrame at the correct point.

In App.xaml.cs:

// Do not add any additional code to this method
// ;)
private void InitializePhoneApplication()
{
    if (phoneApplicationInitialized)
        return;

    // Create the frame but don't set it as RootVisual yet; this allows the splash
    // screen to remain active until the application is ready to render.
    RootFrame = new PhoneApplicationFrame();

    // TODO: Add custom UriMapper here
    RootFrame.UriMapper = new MyCustomUriMapper();

    RootFrame.Navigated += CompleteInitializePhoneApplication;

    // ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM