Calling Android Toast Notifications from Unity C# Scripts

Overview

This article demonstrates how to invoke native Android functionality directly from Unity by leveraging the AndroidJavaClass and AndroidJavaObject APIs. Specifically, we'll implement a wrapper that allows displaying Toast notifications—a common Android UI component for showing brief messsages to users.

Implementation Details

Core Concepts

When working with Android Java classes in Unity, you need to understand two fundamental types:

  • AndroidJavaClass: Represents a Java class (static context). Use this to access static methods and static fields.
  • AndroidJavaObject: Represents an instantiated Java object (instance context). Use this to call instance methods on objects.

A critical consideration is that C# string and Java String are not the same type. When passing strings to Android methods, you must wrap them in a Java String object:

AndroidJavaObject javaString = new AndroidJavaObject("java.lang.String", "Your text here");

Toast Helper Implementation

Create a static helper class that encapsulates the Android Toast functionality:

using UnityEngine;

public static class AndroidBridge
{
#if UNITY_ANDROID
    /// <summary>
    /// Displays a Toast message on Android devices.
    /// </summary>
    /// <param name="message">Text to display in the toast.</param>
    /// <param name="context">Optional Android context. Uses current activity if null.</param>
    public static void DisplayToast(this string message, AndroidJavaObject context = null)
    {
        Debug.Log($"[Toast] {message}");
        
        if (context == null)
        {
            using var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            context = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        }

        using var toastClass = new AndroidJavaClass("android.widget.Toast");
        using var appContext = context.Call<AndroidJavaObject>("getApplicationContext");
        
        context.Call("runOnUiThread", new AndroidJavaRunnable(() =>
        {
            using var textObj = new AndroidJavaObject("java.lang.String", message);
            using var toast = toastClass.CallStatic<AndroidJavaObject>(
                "makeText", appContext, textObj, 
                toastClass.GetStatic<int>("LENGTH_SHORT")
            );
            toast.Call("show");
        }));
    }

    /// <summary>
    /// Alternative method using explicit class invocation.
    /// </summary>
    public static void ShowToast(string message, AndroidJavaObject context = null)
    {
#if UNITY_ANDROID
        if (context == null)
        {
            using var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            context = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        }

        using var toastClass = new AndroidJavaClass("android.widget.Toast");
        using var appContext = context.Call<AndroidJavaObject>("getApplicationContext");
        
        context.Call("runOnUiThread", new AndroidJavaRunnable(() =>
        {
            using var textObj = new AndroidJavaObject("java.lang.String", message);
            using var toast = toastClass.CallStatic<AndroidJavaObject>(
                "makeText", appContext, textObj,
                toastClass.GetStatic<int>("LENGTH_SHORT")
            );
            toast.Call("show");
        }));
#endif
    }

    /// <summary>
    /// Converts a C# string to a Java String object.
    /// </summary>
    public static AndroidJavaObject ToJavaString(this string csharpString)
    {
        return new AndroidJavaObject("java.lang.String", csharpString);
    }
#endif
}

Usage Examples

Extension Method Approach

The string extension method provides the cleanest syntax:

"Operation completed successfully".DisplayToast();
"Download finished".DisplayToast(activityObject);

Static Class Method Approach

Alternative, call the static method directly:

AndroidBridge.ShowToast("Processing data...", activityObject);
AndroidBridge.ShowToast("Download complete");

Complete Example Script

using UnityEngine;

public class ToastDemo : MonoBehaviour
{
    private AndroidJavaObject currentActivity;

    private void Start()
    {
        InitializeAndroidContext();
        DemonstrateToastFunctionality();
    }

    private void InitializeAndroidContext()
    {
        using var playerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        currentActivity = playerClass.GetStatic<AndroidJavaObject>("currentActivity");
    }

    private void DemonstrateToastFunctionality()
    {
        // Extension method with explicit context
        "Loading resources...".DisplayToast(currentActivity);
        
        // Static method approach
        AndroidBridge.ShowToast("Initializing components", currentActivity);
        
        // Using default activity (auto-acquired)
        "Background process complete".DisplayToast();
        AndroidBridge.ShowToast("All systems operational");
    }
}

Key Implementation Notes

  1. Thread Safety: Android UI operations must run on the main UI thread. The runOnUiThread wrapper ensures the Toast display occurs on the correct thread, preventing potential crashes.

  2. Resource Management: Wrap AndroidJavaObject instances in using statements to ensure proper disposal and prevent memory leaks in long-running applications.

  3. Platform Guards: Always wrap Android-specific code in #if UNITY_ANDROID preprocessor directives to prevent compilation errors on other platforms.

  4. String Conversion: Remember that Java requires java.lang.String objects rather than C# strings when passing text to native Android methods.

Setup Steps

  1. Create a new Unity project
  2. Add the AndroidBridge class to your project
  3. Attach a demo script to any GameObject in your scene
  4. Build and run on an Android device

The Toast notification will appear overlaid on the Unity game view, displaying the message for approximately 2 seconds (standard Android Toast duration).

Tags: unity Android Toast Platform Integration C#

Posted on Thu, 23 Jul 2026 16:34:22 +0000 by freelancedeve