java.lang.IllegalAccessException: Tried to access visual service WindowManager from a non-visual Context
Hi,
I'm using segment version 4.8.2 and got a crash on Android 11 (the issue does not appear on Android 10).
E/ContextImpl: Tried to access visual service WindowManager from a non-visual Context:***.Application@4bba99f Visual services, such as WindowManager, WallpaperService or LayoutInflater should be accessed from Activity or other visual Context. Use an Activity or a Context created with Context#createWindowContext(int, Bundle), which are adjusted to the configuration and visual bounds of an area on screen.
java.lang.IllegalAccessException: Tried to access visual service WindowManager from a non-visual Context:***@4bba99f
at android.app.ContextImpl.getSystemService(ContextImpl.java:1916)
at android.content.ContextWrapper.getSystemService(ContextWrapper.java:803)
at com.segment.analytics.internal.Utils.getSystemService(Utils.java:167)
at com.segment.analytics.AnalyticsContext.putScreen(AnalyticsContext.java:322)
at com.segment.analytics.AnalyticsContext.create(AnalyticsContext.java:140)
at com.segment.analytics.Analytics$Builder.build(Analytics.java:1383)
...
As Segment documentation recommend https://segment.com/docs/connections/sources/catalog/libraries/mobile/android/#step-2-initialize-the-client, the SDK should be initialized in the Application, but on Android 11 it expects a visual context (like an Activity context).
Do you think the Segment initialization should be moved to an Activity. Do we lose any features by doing that?
The issue is right here: https://github.com/segmentio/analytics-android/blob/28e82449f1cdc6fb49cab20179265f77690c81b8/analytics/src/main/java/com/segment/analytics/AnalyticsContext.java#L328
I think this can be fixed by using the new APIs for getting the DisplayMetrics instead of using WindowManager.
DisplayMetrics displayMetrics = new DisplayMetrics();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
context.getDisplay().getRealMetrics(displayMetrics);
} else {
WindowManager manager = getSystemService(context, Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
display.getMetrics(displayMetrics);
}
But this is only going to be possible if the project is upgraded to target SDK 30
Any update on this particular issue? This will be a hindrance for me going forward since it is prohibiting me from bumping up versions.
It's been about 9 months since my last comment. Could we please have an update on when/if this might be fixed in the near future?
Hi @TylerMcCraw! Apologies for the extremely late reply, the issue seemed to have slipped through the cracks.
I see your proposed solution, and seems like a good implementation. Would it be possible for you to make a PR with those proposed changes and potentially tests to solidify this new behaviour?
Is there any update on this issue? It is still open with the latest version.
hey @alihussain8999 I have created an internal ticket to track this issue. will get it fixed soon. fyi, if you just started to use the SDK, it's highly recommended to use our new analytics-kotlin instead of this one. it's going to be deprecated soon. even if you already use this SDK, it won't be too hard to upgrade to the new one. analytics-kotlin does not have this issue and is way more performant (see benchmarks here)
this issue is fixed on 4.11.2