Android Float Widget - Unable to add window

Android Float Widget - Unable to add window
2021-01-01T17:05:32+01:00
2021-01-05T18:35:22+01:00
2022-10-15T21:16:37+02:00
DarkRaptor
Sziasztok!

Van egy Float Widget-em, amit egy AsyncTask letöltés végén jelenítek meg WindowManager-el. Ez 6-os Android-on még gond nélkül ment, de felette már 9-es és 10-es Android-on tesztelve ezt a hibaüzenetet kapom:

android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?

Tehát adott egy ilyen kód:

public class DownloadManager extends AsyncTask<String, String, String> { ... @Override protected void onPostExecute(String file_url) { ... if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.M) { FloatStatusWidgetService.prepareFloatWidgetWithPopup(ContextManager.getContext()); } else { FloatStatusWidgetService.prepareFloatWidgetWithWindow(ContextManager.getContext()); } FloatStatusWidgetService.show(wasError);
Ahol pedig...

public static void prepareFloatWidgetWithPopup(Context context) { LayoutInflater inflater = setFloatWidgetView(context); int width = LinearLayout.LayoutParams.WRAP_CONTENT; int height = LinearLayout.LayoutParams.WRAP_CONTENT; boolean focusable = true; // lets taps outside the popup also dismiss it PopupWindow popupWindow = new PopupWindow(mFloatingWidget, width, height, focusable); View widgetPositionLayout = inflater.inflate(R.layout.activity_main, null); popupWindow.showAtLocation(widgetPositionLayout, Gravity.END | Gravity.CENTER_VERTICAL, 0, 0); } public static void prepareFloatWidgetWithWindow(Context context) { setFloatWidgetView(context); WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_TOAST, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); params.gravity = Gravity.END | Gravity.CENTER_VERTICAL; params.x = 0; params.y = 0; WindowManager mWindowManager = (WindowManager) context.getSystemService(WINDOW_SERVICE); mWindowManager.addView(mFloatingWidget, params); } public static void show(Boolean wasError) { if(mFloatingWidget != null) { RelativeLayout mRelativeLayout = mFloatingWidget.findViewById(R.id.status_widget_root); ImageView widgetImage = mRelativeLayout.findViewById(R.id.widget_image); int imageResource; if (wasError) { imageResource = R.drawable.inferno_error; } else { imageResource = R.drawable.inferno_complete; } widgetImage.setImageResource(imageResource); mRelativeLayout.setVisibility(View.VISIBLE); startFadeAnimation(mRelativeLayout, "fadeIn"); initFloatStatusWidgetTouchListener(); } }
Régen nem használtam elágazást, mindenütt a prepareFloatWidgetWithWindow-t használtam, de mivel erre a sorra:

mWindowManager.addView(mFloatingWidget, params);
a fenti hibaüzenetet kapom, ezért elágaztattam úgy, hogy 6-os Android felett már a PopupWindow (prepareFloatWidgetWithPopup) verziót használom. A gond az, hogy a PopupWindow verzió csak és kizárólag az Applikáción belül jeleníti meg a Float Widget-et, kívül, mondjuk ha a kezdő képernyőn állok, azaz az alkalmazáson kívül, akkor nem. Tudtok esetleg erre egy megoldást? rengeteget kutattam ebben, de nem bírtam a WindowManager verzióban a fenti hibaüzenetet kikerülni. Ezeket mind végigpróbáltam:

Unable to add window -- token null is not valid; is your activity running?

PopupWindow $BadTokenException: Unable to add window — token null is not valid - SemicolonWorld

Köszönöm!
Mutasd a teljes hozzászólást!
Látom nem válaszolt senki (pedig bíztam benne), úgyhogy utána néztem a dolognak (pedig semmi humorom nem volt hozzá), és olvastam, hogy a fenti kód az Android Oreoval elavult. Olyan nagyon azért mégsem, mert egy sort kellett átjavítani a kódban:

WindowManager.LayoutParams.TYPE_PHONE, sort
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, -ra.
Itt a kód amit összetákoltam, ha ez sem működik, akkor írj privátban, és valahova felteszem a forráskódot.

public class MainActivity extends AppCompatActivity { private WindowManager wm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (!Settings.canDrawOverlays(getApplicationContext())) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivity(intent); } wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); addImageView(8); } private void addImageView(Integer i) { final WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); params.gravity = Gravity.TOP | Gravity.START; params.x=i; params.y=i; LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); View popupView = inflater.inflate(R.layout.rere, null); //RelativeLayout wm.addView(popupView, params); TextView titi= popupView.findViewById(R.id.zizi); titi.setText("szöveg átír"); } }

rere.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="left" android:id="@+id/o2element1" android:padding="0dp" android:background="#FFFF00" xmlns:android="http://schemas.android.com/apk/res/android" > <TextView android:layout_width="wrap_content" android:layout_height="30dp" android:text="próba 1" android:id="@+id/zizi" /> <TextView android:layout_width="wrap_content" android:layout_height="30dp" android:text="próba 2" android:id="@+id/zizi2" /> </LinearLayout>
Manifest

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Egy sárga ablak-szeletet keress a bal felső sarokban
Mutasd a teljes hozzászólást!

  • <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    Két év alatt a fenti dolog annyiban változott, hogy most már engedély kell hozzá, illetve elég hamar megbánós dolog lett az Android részéről, úgyhogy ilyent már csak akkor lehet csinálni, ha a felhasználó külön beállítja a telefonján a programodnak hogy lehet mindig felül, a sima telepítés kevés hozzá. Ez nemrég volt itt téma, 
    Android - Alkalmazás kis méretben való megjelenítése probléma
    az én (utolsó) hozzászólásom nézd
    Mutasd a teljes hozzászólást!
  • Szia!

    Köszönöm a válaszod, de sajnos nem ez a gond. Elnézést, a Manifest-et beszúrhattam volna...

    <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.inferno.daily_wallpaper_manager"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.SET_WALLPAPER"/> <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <application android:name=".ApplicationInit" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/appName" android:supportsRtl="true" android:theme="@style/AppTheme" android:persistent="true"> <activity android:name=".MainActivity" android:largeHeap="true" android:configChanges="orientation|screenSize" tools:targetApi="honeycomb"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SettingsActivity" android:largeHeap="true" android:configChanges="orientation|screenSize" tools:targetApi="honeycomb" /> <activity android:name=".AboutActivity" android:largeHeap="true" android:configChanges="orientation|screenSize" tools:targetApi="honeycomb" /> <service android:name=".Service.AutoStartupService" android:enabled="true" /> <service android:name=".Service.FloatStatusWidgetService" android:enabled="true" /> <!-- Receive app start on device boot --> <receiver android:name=".BroadcastReceiver.DeviceBootCompleteReceiver" android:enabled="true" android:exported="true" android:permission="android.permission.RECEIVE_BOOT_COMPLETED"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> </receiver> </application>
    Illetve:

    hamar megbánós dolog lett az Android részéről, úgyhogy ilyent már csak akkor lehet csinálni, ha a felhasználó külön beállítja a telefonján a programodnak hogy lehet mindig felül, a sima telepítés kevés hozzá

    Sejtem mire gondolsz, ezt is bekérem tőle...

    if (!Settings.canDrawOverlays(ContextManager.getContext())) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivityForResult(intent, GlobalVariables.appPermissionRequest); }
    Minden tesztelésnél beállítottam ezt az engedélyt, így nem ez a gond. Van esetleg más ötletetek?

    Egyébként igen ez nekem is megfordult a fejemben, hogy nem véletlenül szigorították ezt meg ennyire. Ugyanakkor viszont azt nem értem, hogy a WIFI automatikus ki/be kapcsolását miért szedték ki 10-ben... a mobilnet kapcsolgatásának kiszedését még megértettem 5-ös android-tól (nyilván az pénzbe kerül), de hogy a WIFI kinek fájt...

    Köszönöm!
    Mutasd a teljes hozzászólást!
  • Látom nem válaszolt senki (pedig bíztam benne), úgyhogy utána néztem a dolognak (pedig semmi humorom nem volt hozzá), és olvastam, hogy a fenti kód az Android Oreoval elavult. Olyan nagyon azért mégsem, mert egy sort kellett átjavítani a kódban:

    WindowManager.LayoutParams.TYPE_PHONE, sort
    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, -ra.
    Itt a kód amit összetákoltam, ha ez sem működik, akkor írj privátban, és valahova felteszem a forráskódot.

    public class MainActivity extends AppCompatActivity { private WindowManager wm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (!Settings.canDrawOverlays(getApplicationContext())) { Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())); startActivity(intent); } wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); addImageView(8); } private void addImageView(Integer i) { final WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); params.gravity = Gravity.TOP | Gravity.START; params.x=i; params.y=i; LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); View popupView = inflater.inflate(R.layout.rere, null); //RelativeLayout wm.addView(popupView, params); TextView titi= popupView.findViewById(R.id.zizi); titi.setText("szöveg átír"); } }

    rere.xml

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="left" android:id="@+id/o2element1" android:padding="0dp" android:background="#FFFF00" xmlns:android="http://schemas.android.com/apk/res/android" > <TextView android:layout_width="wrap_content" android:layout_height="30dp" android:text="próba 1" android:id="@+id/zizi" /> <TextView android:layout_width="wrap_content" android:layout_height="30dp" android:text="próba 2" android:id="@+id/zizi2" /> </LinearLayout>
    Manifest

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    Egy sárga ablak-szeletet keress a bal felső sarokban
    Mutasd a teljes hozzászólást!
  • Isten vagy köszönöm! :) a TYPE_APPLICATION_OVERLAY volt a megoldás, csak azt kellett átírni.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd