Open EvilKingStone opened 4 years ago
You probably have to subscribe on NFC events elsewhere than OnAppearing
.
A quick fix for the sample will be like this:
bool _eventsAlreadySubscribed = false;
void SubscribeEvents()
{
if (_eventsAlreadySubscribed)
return;
_eventsAlreadySubscribed = true;
CrossNFC.Current.OnMessageReceived += Current_OnMessageReceived;
[...]
}
It doesn't matter where the subscription is done.
Change in the shared project app.xaml.cs Main page to the navigation page
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
Add button to the MainPage. Bind to ListenCommand
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="Catyari.Xam.Nfc.Mobile.MainPage">
<StackLayout>
<!-- Place new controls here -->
<Label Text="Welcome to Xamarin.Forms!"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Button Text="Listen" Command="{Binding ListenCommand}"/>
</StackLayout>
public partial class MainPage : ContentPage
{
public MainPage()
{
this.ListenCommand = new Command(() =>
{
CrossNFC.Current.StartListening();
CrossNFC.Current.OnMessageReceived += this.OnNfcMessage;
});
this.BindingContext = this;
InitializeComponent();
}
private void OnNfcMessage(ITagInfo tagInfo)
{
}
public ICommand ListenCommand { get; }
protected override void OnAppearing()
{
base.OnAppearing(); // set breakpoint here
}
}
5. Run app
6. Set breakpoint in OnAppearing method.
7. Click Listen button.
8. Place card on phone NFC sensor.
Current result: app stops on the breakpoint in OnAppearing method
I did some googling about that. The reason is that the MainActivity is paused before new intent processing.
The only one way I found to avoid it is to push page in modal navigation stack. This case OnAppearing is not called.
I'm also encountering this issue. OnDisappearing() is called before the event is handled and OnAppearing() is called after the event is handled. @dm-CaT did you find any other way around it?
@dm-CaT, @timothy-gibson
- Create blank Xamarin Forms Project.
- Init CrossNFC in Android project, set required permissions.
- Change in the shared project app.xaml.cs Main page to the navigation page
- Add button to the MainPage. Bind to ListenCommand
- Run app
- Set breakpoint in OnAppearing method.
- Click Listen button.
- Place card on phone NFC sensor.
Current result: app stops on the breakpoint in OnAppearing method
I followed these reproduction steps but I didn't reproduce the final result, app didn't stop. This is my test project: TestIssue27.zip
But I maybe misunderstood the issue... If so, please provide a reproduction sample and some clear explanations.
@franckbour, I took your test project and the issue is reproduced. Here is video with your project: youtube
The problem is when you read a NFC card the page in non-modal navigation stack disappears and appears (OnDisapearing and OnAppearing are called). OnAppearing method is used primarily to load some data. And loading occurs every time when a NFC is read.
@timothy-gibson,
@dm-CaT did you find any other way around it?
No, I didn't. To way around I took a look into Xamarin Forms source code. I was looking for a place where OnDisappearing/OnAppearing are called as the result of the MainActivity deactivation and activation back. But I didn't find such code because XF source code is too entangled. I think if we'll find this piece of code we'll be able avoid somehow OnAppearing/OnDesappearing calls.
@dm-CaT and @timothy-gibson I made it work in my ViewModel perfectly in a stable app. All i did was ensure that I assigned the event handlers only once, and then in the destructor of the viewmodel, and every navigation away from the page, i unassigned the event handlers
Hi @saamerm I am stuck with this issue. Can you explain how do you workaround it? I didn't understand your last message. Thanks.
@pazunino if you see @dm-CaT ‘s comment, you cannot reliably use the OnAppearing and OnDisappearing from Android. So instead try to use a view model and use the constructor and destructor of the view model instead
Is any progress with this issue? I think that this issue limited the usage of NFC in Xamarin.Forms. I tested with AppShell and the same problem occurred.
I use another workaround for my MAUI application. In the OnAppearing() and OnDisappearing() functions, I directly return when the application is not navigating between pages (called when NFC is used). In AppShell.xaml.cs, I set a static bool to true in the function OnNavigating(ShellNavigatingEventArgs args). After in All OnAppearing(), I test this bool to directly return or to set it to false and execute all lines in OnAppearing(). In All OnDisappearing() I test this bool to directly return or execute all lines. So with a card on phone NFC, the 2 functions OnAppearing() and OnDisappearing() are called but there is a return.
This is the MAUI sample code tested in Android: Plugin.NFCWorkaround.zip
I use navigation in my xamarin.forms app and "OnAppearing" calling again when tag is detected by device. And I get 'Tag is missing' when try to write tag. Everything will be ok in singlepage application.
To reproduce error you can change App.xaml.cs in your sample: MainPage = new NavigationPage(new MainPage()); and try to write tag