Search code examples
androidandroid-intentandroid-activitybroadcastreceiver

Android: How to hide or close topmost activity?


In my app, I need to start the built-in camera application using the action INTENT_ACTION_STILL_IMAGE_CAMERA. The reason of this action is that in this case, I can use the Pro camera mode, like manual ISO, exposure time, etc., while using the action ACTION_IMAGE_CAPTURE this is not possible (at least for the builtin camera app for my Samsung Galaxy S20+ device)

Using the broadcast receiver intent filter ACTION_NEW_PICTURE I am also able to catch the URI of the photo taken.

What I need is to hide the built-in camera Activity from the broadcast receiver's OnReceive method, once the photo was taken. What I tried so far is that I called my Activity from OnReceive by specifying the intent action flags FLAG_ACTIVITY_REORDER_TO_FRONT and FLAG_ACTIVITY_SINGLE_TOP this way (a C# language snippet, but almost identical to Java):

public override void OnReceive(Context context, Intent intent) {
    Toast.MakeText(context, $"Data1: {intent.DataString}", ToastLength.Short).Show();

    var path = Path.Combine(context.CacheDir.AbsolutePath, $"Photo_{DateTime.Now.ToString("yyyyMMMdd_HHmmss")}.jpg");
    try {
        // copy the photo to app cache dir
        using (var outs = File.Create(path)) {
            using (var ins = context.ContentResolver.OpenInputStream(intent.Data)) {
                ins.Seek(0, SeekOrigin.Begin);
                ins.CopyTo(outs);
            }
        }
        
        var a = Xamarin.Essentials.Platform.CurrentActivity;
        var tvInfo = a.FindViewById<AppCompatTextView>(Resource.Id.tvInfo);
        tvInfo.Append("Picture was taken and saved to:");
        tvInfo.Append($"{path}{SysEnv.NewLine}{SysEnv.NewLine}");

        // hide the builtin camera's Activity by brining my Activity to top
        var i = new Intent(context, typeof(MainActivity)).SetFlags(ActivityFlags.ReorderToFront | ActivityFlags.SingleTop);
        a.StartActivity(i);
    }
    catch (Exception ex) {
        Toast.MakeText(context, $"Error: {ex.Message}", ToastLength.Short).Show();
    }
}

Here is how I start the camera:

var btnTake = FindViewById<AppCompatButton>(Resource.Id.btnTake);
btnTake.Click += (s, e) => {
    var i = new Intent(MediaStore.IntentActionStillImageCamera);
    var r = i.ResolveActivity(this.PackageManager);
    if (r != null) {
        StartActivity(i);
    }
};

The problem with the above is that it works only on the first attempt, which means I click on my app's button, the built-in camera starts. When I take a picture, the picture is saved and copied to my app's cache dir, the built-in camera's Activity disappears and my Activity appears. But on the second attempt, my activity does not appear and the bulti-in camera's Activity stays on top. Any idea, how to hide or close the built-in camera's Activity?


Solution

  • Thanks to @DavidWasser finally it works!!!

    Solution is to add a new dummy activity calling Finish() from its OnCreate() and finally call following from broadcast receiver's OnReceive():

    var i = new Intent(context, typeof(Dummy));
    context.StartActivity(i);