0

I've written an app for Android using Xamarin Studio. Occasionally, due to other code, the app will hang and become unresponsive. When the user clicks the home button, the audio continues to play instead of stopping. Is there a way for a "hung" app to know that it has been put in the background and force the audio to pause?

protected override void OnDestroy ()
{
    DependencyService.Get<IMediaController>().Stop();

    // Call base method
    base.OnDestroy ();
}

protected override void OnSleep()
{
    DependencyService.Get<IMediaController>().Pause();
}
Gandalf458
  • 2,139
  • 1
  • 21
  • 36
  • 2
    Fix your code that's hanging. If its hanging, these functions can't even be called. – Gabe Sechan Mar 31 '15 at 01:45
  • We're working daily to do that. But until then I was just hoping for something OS level that could tell the audio session to end when the app is backgrounded. My experience with setting the audio type of the app is limited to iOS. – Gandalf458 Mar 31 '15 at 17:56
  • Nope. The app can tell the OS to end the audio when its backgrounded, but to do that the app has to be functioning (it needs to have its onPause called and do it there). That's on purpose- many apps continue to play audio when backgrounded as a feature. For example, an internet radio app. The OS has no way of knowing that this isn't such an application and isn't leaving it playing on purpose. – Gabe Sechan Mar 31 '15 at 18:08

1 Answers1

0

I've determined that the way to do this is to monitor the Android running tasks. This enables me to determine if my app has been backgrounded. I have a thread which runs throughout the apps lifetime, and it is normally killed in OnSleep. If OnSleep is not called, then that thread will determine the app is non-responsive, and it will call OnSleep. This is for Xamarin. I got my ideas from this post. how to check the top activity from android app in background service

//Returns the top running task information
private static ActivityManager activityManager;
private static Android.App.ActivityManager.RunningTaskInfo runningTaskInfo;
public static ComponentName GetTopActivity()
{
    if(activityManager == null)
    {
        activityManager = (ActivityManager) Application.Context.GetSystemService(Context.ActivityService);
    }

    IList<Android.App.ActivityManager.RunningTaskInfo> runningTasks =   
        activityManager.GetRunningTasks(1);
    if(runningTasks != null && runningTasks.Count > 0)
    {
        runningTaskInfo = runningTasks[0];
        return runningTaskInfo.TopActivity;
    }
    else
    {
        return null;
    }
}

//This called from my thread every 2 seconds
public bool IsAppVisible()
{
    //have to do a complicated version of this to determine the current running tasks        //and whether our app is the most prominent.
    Android.Content.ComponentName componentName = AndroidUtils.GetTopActivity();
    bool isCurrentActivity;
    if(componentName != null)
    {
        isCurrentActivity = string.Compare(componentName.PackageName, "myPackage") == 0;
    }
    else
    {
        isCurrentActivity = false;
    }

    return isCurrentActivity;
}

if(DependencyService.Get<IDeviceUtility>().IsAppVisible() == false)
{
    //This needs to be manually called if the app becomes completely unresponive
    OnSleep();
    Debug.WriteLine("App is no longer visible");
}
Community
  • 1
  • 1
Gandalf458
  • 2,139
  • 1
  • 21
  • 36