Why Toast is not compatible with Android 28+?

Viewed 47

why does standard form Toast (also in current google android online docs) give "false caller" error for an app in Android compileSdkVersion/targetSdkVersion 28. Using getApplicationContext() does not matter.

public class MainActivity extends Activity implements SensorEventListener {

...

  OnClickListener captureListener = new OnClickListener() {
    @Override
    public void onClick(View v) {
      Toast.makeText(MainActivity.this, "pop-up text", Toast.LENGTH_LONG).show();
    }
  };

}

error line, on real android-11 device:

V/Toast: Toast SHOW: android.widget.Toast@86d08e5 view = android.widget.LinearLayout{540bfba V.E...... ......I. 0,0-0,0} pkg: com.example.app TextToast? false caller: com.example.app.MainActivity$1.onClick:211 ...

build.gradle dependencies:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'commons-io:commons-io:2.4'
    implementation "androidx.appcompat:appcompat:1.3.1"
    implementation "androidx.appcompat:appcompat-resources:1.3.1"
}
1 Answers

Changes to the Toast.makeText() code were made starting with Android 11+ with the introduction of the Compatibility CHANGE_TEXT_TOASTS_IN_THE_SYSTEM check.


    /**
     * Make a standard toast to display using the specified looper.
     * If looper is null, Looper.myLooper() is used.
     *
     * @hide
     */
    public static Toast makeText(@NonNull Context context, @Nullable Looper looper,
            @NonNull CharSequence text, @Duration int duration) {
        if (Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM)) {
            Toast result = new Toast(context, looper);
            result.mText = text;
            result.mDuration = duration;
            return result;
        } else {
            Toast result = new Toast(context, looper);
            View v = ToastPresenter.getTextToastView(context, text);
            result.mNextView = v;
            result.mDuration = duration;

            return result;
        }
    }

CHANGE_TEXT_TOASTS_IN_THE_SYSTEM Change ID: 147798919

Default state: Enabled for apps that target Android 11 (API level 30) or higher.

Text toasts are now rendered by the SystemUI instead of in-app. This prevents apps from circumventing restrictions on posting custom toasts in the background.

https://developer.android.com/about/versions/11/reference/compat-framework-changes#change_text_toasts_in_the_system

What is SystemUI?

https://android.googlesource.com/platform/frameworks/base/+/master/packages/SystemUI/README.md

As Myrick Chow explained, you must now instantiate a Toast (first method) rather than using the static Toast object (second method), as shown below.

// Method 1: Public constructor
val simpleToast = Toast(this)

// Method 2: Static constructor
val textToast = Toast.makeText(this, "Simple toast message", Toast.LENGTH_SHORT)

https://itnext.io/android-11-toast-updates-7f1cd2245bc4

Related