How can I return an app to the foreground, considering the new security changes in API 29?

645 views Asked by At

I have an app that makes an http request via the localhost to a separate, third-party app which I do not control, and waits for a response from that call before continuing. The workflow goes like this:

  • User is inside my app
  • User presses a button, which launches and calls out to the third-party application
  • User interacts with the third-party application
  • When the third-party application finishes its work, my app picks up the completed http response, and pulls itself back to the forefront via MoveTaskToFront for the user to continue working.

This functions properly in Android 9 and below, but the last step does not work in Android 10, I believe due to the new restrictions on launching activities from the background.

I have no control over the third-party app, so I cannot modify it to close itself when finished working, or request that the calling app be returned to the foreground when appropriate. Does anyone know of a workaround for this?

Edit: as requested, I've added the code snippet with the call out. This is a Xamarin project, so it's written in C#, but this particular code section is Android-platform-specific, so I am able to make Android system calls.

First I have to bring up the third-party app:

Intent intent = CrossCurrentActivity.Current.AppContext.PackageManager.GetLaunchIntentForPackage("com.bbpos.android.tsys");
            if (intent != null)
            {
                // We found the activity now start the activity
                intent.AddFlags(ActivityFlags.ClearTask);
                CrossCurrentActivity.Current.AppContext.StartActivity(intent);
            }

Then I call into it via the localhost, process the response, and want to switch back to my app.

using (var client = new HttpClient())
            {
                // by calling .Result we're forcing synchronicity
                var response = client.GetAsync("http://127.0.0.1:8080/v2/pos?TransportKey=" + pTransportKey + "&Format=JSON").Result;
                if (response.IsSuccessStatusCode)
                {
                    var responseContent = response.Content;

                    // as above, forcing synchronicity
                    string responseString = responseContent.ReadAsStringAsync().Result;

                    var result = JsonConvert.DeserializeObject<GeniusTransactionResponse>(responseString);

                    var manager = (ActivityManager)Application.Context.GetSystemService(Context.ActivityService);
                    var test = manager.AppTasks.First().TaskInfo.Id;
                    manager.AppTasks.First().MoveToFront();
                    //manager.MoveTaskToFront(CrossCurrentActivity.Current.Activity.TaskId, 0);

                    return result;
                }
                else
                {
                    return null;
                }
            }
1

There are 1 answers

0
Dan Amato On BEST ANSWER

Quick update in case anyone else has this same issue: I was able to work around this by adding an Accessibility Service to the project. Simply having an Accessibility Service registered and enabled by the user allows MoveTaskToFront to function as it did in APIs <29; the actual service doesn't need to do anything.