Search code examples
c#androidxamarinxamarin.formsxamarin.android

How can I pop a navigation page when a value changes in a static class?


So I have a bit of a weird problem. I've implemented a camera preview class (largely following this code here: https://learn.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/customrenderers-view/) but have added a button at the bottom to take a picture. This involves the use of both some xamarin forms code and some xamarin android code.

However, the CapturePage is only put on the stack when the user announces that they want to take a photo, and after the photo has been taken, I want to pop the Capture page to go back to the main screen. Currently, I have a static boolean value in the overall project that is changed from false to true when a capture has occurred. Is there some way to get my code in Main.xaml.cs to wait on this value changing, then pop whatever is on top of the navigation stack? Is this a use for a property changed? See code below:

The code in Project.Droid that handles the capturing and saving of the image:

void OnCapButtonClicked(object sender, EventArgs e)
{
    // capButton.capture is an instance of Android.Hardware.Camera
    capButton.capture.TakePicture(null, null, this);
    // stop the preview when the capture happens
    CameraInfoContainer.isPreviewing = false;
}

public void OnPictureTaken(byte[] data, Camera camera)
{
    var filepath = string.Empty;
    var clientInstanceId = Guid.NewGuid().ToString();
    var saveLoc = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures);
    filepath = System.IO.Path.Combine(saveLoc.AbsolutePath, clientInstanceId + ".jpg");
    try
    {
        System.IO.File.WriteAllBytes(filepath, data);
        //mediascan adds the saved image into the gallery  
        var mediaScanIntent = new Intent(Intent.ActionMediaScannerScanFile);
        mediaScanIntent.SetData(Android.Net.Uri.FromFile(new File(filepath)));
        Forms.Context.SendBroadcast(mediaScanIntent);
    }
    catch (Exception e)
    {
        System.Console.WriteLine(e.ToString());
    }
    // CameraInfoContainer is a static class in Project NOT in Project.Droid
    CameraInfoContainer.savedCapture = filepath;
    CameraInfoContainer.capType = CaptureType.Photo;
    CameraInfoContainer.captureComplete = true; // here is where I set the value (in Project)
}

Now the code in Project that pushes the capture page on the stack and that I want to trigger when the capture has happened:

// this method puts the capture page on the stack and starts the whole process
private async Task ExecuteNewCapture()
{
    var cp = new CapturePage();
    var np = new NavigationPage(cp);
    await Navigation.PushModalAsync(np, true);
}
 // this is the method that I want to trigger when a photo is taken (in Project/Main.xaml.cs)
private async Task Complete(string fileLoc)
{
    await Navigation.PopModalAsync();
}

Solution

  • Answer is in a comment from Junior Jiang. Ended up using Xamarin.Forms.MessagingCenter to get done what I needed.