android.view.WindowManager$BadTokenException: Tidak dapat menambahkan jendela android.view.ViewRootImpl$W@c745883 - izin ditolak

Inilah jejak tumpukan saya:

01-30 15:11:41.037 13010-13010/project.app E/AndroidRuntime: FATAL EXCEPTION: main
 Process: project.app, PID: 13010
 android.view.WindowManager$BadTokenException:
   Unable to add window android.view.ViewRootImpl$W@c745883 -- permission denied for window type 2003
   at android.view.ViewRootImpl.setView(ViewRootImpl.java:789)
   at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
   at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
   at android.app.Dialog.show(Dialog.java:330)
   at com.facebook.react.devsupport.DevSupportManagerImpl$4.run(DevSupportManagerImpl.java:344)
   at android.os.Handler.handleCallback(Handler.java:790)
   at android.os.Handler.dispatchMessage(Handler.java:99)
   at android.os.Looper.loop(Looper.java:164)
   at android.app.ActivityThread.main(ActivityThread.java:6494)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Saya menemukan jawaban tentang TYPE_SYSTEM_ERROR tidak digunakan lagi di Android Oreo (8) jadi saya menerapkan metode berikut yang juga saya temukan:

public void fixAndroid() {
    WindowManager.LayoutParams params;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      params = new WindowManager.LayoutParams(
              WindowManager.LayoutParams.MATCH_PARENT,
              WindowManager.LayoutParams.MATCH_PARENT,
              WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
              WindowManager.LayoutParams.FLAG_FULLSCREEN,
              PixelFormat.TRANSLUCENT);
    } else {
      params = new WindowManager.LayoutParams(
              WindowManager.LayoutParams.MATCH_PARENT,
              WindowManager.LayoutParams.MATCH_PARENT,
              WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
              WindowManager.LayoutParams.FLAG_FULLSCREEN,
              PixelFormat.TRANSLUCENT);
    }
  }

Di dalam metode onCreate() saya, saya memiliki:

  @Override
  public void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Checking permissions on init
    fixAndroid();
  }

Saya masih mendapatkan kesalahan.

Saya menggunakan Expo SDK 21, React Native 0.48. Aplikasi telah terlepas dari ExpoKit.

Setelah setiap perubahan saya membersihkan proyek saya dan kemudian menjalankannya di Emulator melalui Android Studio.

Edit: Saya menjalankan ini pada emulator Nexus 5X, berjalan pada API 27.


person Dan    schedule 30.01.2018    source sumber
comment
Saya pikir ini ada hubungannya denganWindowManager.LayoutParams. Menarik untuk melihat apa yang terjadi dengan: WindowManager.LayoutParams.TYPE_TOAST atau WindowManager.LayoutParams.TYPE_APPLICATION_PANEL dan juga WindowManager.LayoutParams.TYPE_SYSTEM_ALERT dengan: <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> di manifes   -  person Jon Goodwin    schedule 02.02.2018
comment
Hai Jon, izinnya ada di dalam AndroidManifest.xml - Saya akan mencoba saran Anda. Terima kasih.   -  person Dan    schedule 02.02.2018
comment
Hai Dan, saya siap membantu Anda, kebetulan saya mencoba frenagle beberapa poin lagi dari Men-debug WebView di aplikasi React Native mungkin layak untuk dicoba untuk tujuan debugging. Atau Anda dapat memberi saya 500 poin yang ditawarkan!   -  person Jon Goodwin    schedule 03.02.2018
comment
Saya pikir Anda bisa menggunakan dialog penggantian Aktivitas Ttranslucent untuk banyak ponsel Android yang menolak izin tentang TYPE_SYSTEM_ALERT   -  person Cyrus    schedule 09.02.2018


Jawaban (3)


Saya melihat kesalahan ini beberapa waktu lalu, ketika saya memperbarui aplikasi asli & bereaksi ke SDK 26. Masalahnya adalah fungsi react-native yang membuat dialog merah untuk pengembangan. Fungsi tersebut menggunakan TYPE_SYSTEM_ALERT sebagai tipenya, jadi Anda tidak dapat menggunakan level SDK yang lebih besar dari 25 di aplikasi hibrid Anda dengan versi react-native tersebut, kecuali Anda menambal fungsi tersebut sehingga tidak lagi menggunakan TYPE_SYSTEM_ALERT.

ini adalah kode reaksi-asli di 0,48:

private void showNewError(
      final String message,
      final StackFrame[] stack,
      final int errorCookie,
      final ErrorType errorType) {
    UiThreadUtil.runOnUiThread(
        new Runnable() {
          @Override
          public void run() {
            if (mRedBoxDialog == null) {
              mRedBoxDialog = new RedBoxDialog(mApplicationContext, DevSupportManagerImpl.this, mRedBoxHandler);
              mRedBoxDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
            }
            if (mRedBoxDialog.isShowing()) {
              // Sometimes errors cause multiple errors to be thrown in JS in quick succession. Only
              // show the first and most actionable one.
              return;
            }
            mRedBoxDialog.setExceptionDetails(message, stack);
            updateLastErrorInfo(message, stack, errorCookie, errorType);
            // Only report native errors here. JS errors are reported
            // inside {@link #updateJSError} after source mapping.
            if (mRedBoxHandler != null && errorType == ErrorType.NATIVE) {
              mRedBoxHandler.handleRedbox(message, stack, RedBoxHandler.ErrorType.NATIVE);
              mRedBoxDialog.resetReporting(true);
            } else {
              mRedBoxDialog.resetReporting(false);
            }
            mRedBoxDialog.show();
          }
        });
  } 

Anda perlu mengubah panggilan mRedBoxDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); ke jenis lain. Namun, ini tidak memberi Anda jaminan apa pun bahwa Anda akan dapat menjalankan aplikasi Anda dengan SDK 26, ketika saya mencoba mengkompilasi reaksi dengan SDK 26, bagian lain dari proyek "bereaksi" meledak, jadi ini sepertinya tidak akan berhasil dalam waktu singkat jangka waktu (Anda mungkin perlu mulai memperbaiki masalah lain). Jadi pilihan Anda adalah:

-Downgrade aplikasi ke level 25;

-Tingkatkan ke reaksi 0,52, jika fungsi tersebut tidak ada lagi, dan coba lagi (perpustakaan reaksi mungkin tidak berfungsi setelah ini)

-Patch fungsi di cabang react-native 0.48 dan coba versi yang dipatch. Beberapa masalah lain yang terkait dengan SDK mungkin muncul (react saat ini masih dikompilasi dengan SDK 22)

Selamat membuat kode!

person Fco P.    schedule 07.02.2018

TYPE_SYSTEM_ALERT

Konstanta ini tidak digunakan lagi di API level 26 untuk aplikasi non-sistem. Gunakan TYPE_APPLICATION_OVERLAY sebagai gantinya.

person Elad    schedule 11.06.2018

Verifikasi Izin SYSTEM_ALERT_WINDOW Atau coba berikan Izin Overlay Secara Manual.

Seperti yang dikatakan @Fco P. Anda dapat mencoba mengubahnya

mRedBoxDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

**## Jika Anda menggunakan perangkat Lenovo. Silakan coba dengan yang lain. Izin khusus ini terkadang menimbulkan masalah pada perangkat Lenovo.****

person Dipendra Sharma    schedule 08.02.2018