0

I am using the Messaging Center to send and receive messages/data throughout the app. The app handles custom file extensions and loads them into the app and work on those files.

There are two ways to import files into the app:

1- Pushing the Browse button in the app and choosing the file (This is working fine).

2- Pressing directly on the file, since the file extension is associated with the app, the application opens up and imports the selected file. This is where the problems start.

If the application has not opened before and is not in the background (that means there are no subscribers yet), the application starts and does nothing, as expected. The app sending the selected files to the subscriber but there is no subscriber available yet because the form did not complete opening (pages and view models executed after MainActivity or AppDelagate).

If the app is in the background, clicking the file opens the app and works as expected.

I am aware of the problem but I do not know how to get around it. Any suggestions?

This is MainActivity.cs in Android:

 protected override async void OnNewIntent(Intent intent)
        {
            if (intent?.Data == null)
                return;

            // Open a stream from the URI 
            var lasStream = ContentResolver.OpenInputStream(intent.Data);

            // Save it over 
            var memStream = new MemoryStream();
            await lasStream.CopyToAsync(memStream);
            var byteArray = memStream.ToArray();

            MessagingCenter.Send(byteArray, "ByteArrayReceived");
        }

This method is called in one of the ViewModels in the app:

private async Task ByteArrayReceived(byte[] byteArray)
    {
        // Handle incoming file as a byte array
    }

UPDATE:

I think the question was not that clear. I will try to explain a little bit more.

What I want to do is that when user selects an external file (this could be a txt file or something else), this app should fire up and load the contents of selected file into the app.

Incoming File is being detected in MainActivity.cs which is executed first when the app is opening, and that means there cannot be any subscribers available yet, because app did not finish loading and the subscriber method has not been called yet. The subscriber method is in MainPageView.cs

I know that subscriber method should be called before sending messages but how do I do it in MainActivity.cs or AppDelagate.cs?

UPDATE 2:

MainPageView is called after MainActivity.cs is executed.

This is MainActivity.cs

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.Window.RequestFeature(WindowFeatures.ActionBar);
        base.SetTheme(Resource.Style.MainTheme);

        if (Intent.Action == Intent.ActionSend || Intent.Action == Intent.ActionView)
            HandleIntent(Intent);

        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);

        LoadApplication(new App());
    }

This is App.cs

   public App()
    {
        InitializeComponent();

        MainPage = new NavigationPage(new MainPageView());
    }
Omer
  • 23
  • 10

1 Answers1

0

One solution I find is that you can send the message after X seconds by using Device.StartTimer:

protected override async void OnNewIntent(Intent intent)
{
    if (intent?.Data == null)
        return;

    // Open a stream from the URI 
    var lasStream = ContentResolver.OpenInputStream(intent.Data);

    // Save it over 
    var memStream = new MemoryStream();
    await lasStream.CopyToAsync(memStream);
    var byteArray = memStream.ToArray();

    // run task after 2 second
    Device.StartTimer(TimeSpan.FromSeconds(2), () =>
    {
        MessagingCenter.Send(byteArray, "ByteArrayReceived");

        // No longer need to recur. Stops firing task
        return false;
    });
}
nevermore
  • 15,432
  • 1
  • 12
  • 30
  • Unfortunately, it did not work. Still not trigger the "ByteArrayReceived" method. – Omer Jul 01 '20 at 08:46
  • When does you call MainPageView under this scenario? – nevermore Jul 01 '20 at 08:50
  • I updated my question one more time, can you look at it? – Omer Jul 02 '20 at 10:07
  • Can you please add a breakpoint in `MessagingCenter.Send(byteArray, "ByteArrayReceived");` and `MainPageView` to see which one triggered first? You can also increase the delay time to make it work. – nevermore Jul 03 '20 at 01:26