I added this code to my books app to recognize foldable devices (deleted unrelevant code).
On OnePlus and Oppo devices (not foldable) the app crashes.
It happens only in Android OS bigger than 13.
Code:
private WindowInfoTrackerCallbackAdapter windowInfoTracker;
private final Consumer<WindowLayoutInfo> layoutStateChangeCallback = new LayoutStateChangeCallback();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_epub_reader);
windowInfoTracker = new WindowInfoTrackerCallbackAdapter(WindowInfoTracker.getOrCreate(this));
}
@Override
protected void onStart() {
super.onStart();
if (Utilities.isFoldableDevice(this)) {
Timber.tag(TAG).d("onStart: isFoldableDevice");
windowInfoTracker.addWindowLayoutInfoListener(this, Runnable::run, layoutStateChangeCallback);
}
}
@Override
protected void onStop() {
super.onStop();
if (Utilities.isFoldableDevice(this)) {
windowInfoTracker.removeWindowLayoutInfoListener(layoutStateChangeCallback);
}
}
class LayoutStateChangeCallback implements Consumer<WindowLayoutInfo> {
@Override
public void accept(WindowLayoutInfo newLayoutInfo) {
EpubReaderActivity.this.runOnUiThread(() -> {
try {
boolean isDeviceFlatFoldable = !newLayoutInfo.getDisplayFeatures().isEmpty();
Timber.tag(TAG).d("accept: isDeviceFlatFoldable = %s", isDeviceFlatFoldable);
if (preferencesManager.getIsDeviceFlatFoldable() != isDeviceFlatFoldable) {
preferencesManager.setIsDeviceFlatFoldable(isDeviceFlatFoldable);
EventBus.getDefault().post(new EpubColumnsChangeEvent());
}
} catch (Exception e) {
Timber.e(e);
}
});
}
}
public static boolean isFoldableDevice(Context context) {
// at least Android 11 (Version code 30) is required
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_SENSOR_HINGE_ANGLE);
}
return false;
}
build.gradle
implementation 'androidx.window:window-java:1.3.0'
Crash log:
Fatal Exception: java.lang.AbstractMethodError: abstract method "void androidx.window.sidecar.SidecarInterface$SidecarCallback.onDeviceStateChanged(androidx.window.sidecar.SidecarDeviceState)"
at androidx.window.sidecar.StubSidecar.updateDeviceState(StubSidecar.java:64)
at androidx.window.sidecar.SampleSidecarImpl.onDisplayFeaturesChanged(SampleSidecarImpl.java:78)
at androidx.window.sidecar.SampleSidecarImpl.-$$Nest$monDisplayFeaturesChanged()
at androidx.window.sidecar.SampleSidecarImpl$NotifyOnConfigurationChanged.onDisplayFeaturesChangedForActivity(SampleSidecarImpl.java:194)
at androidx.window.sidecar.SampleSidecarImpl$NotifyOnConfigurationChanged.onActivityCreated(SampleSidecarImpl.java:182)
at android.app.Application.dispatchActivityCreated(Application.java:388)
at android.app.Activity.dispatchActivityCreated(Activity.java:1430)
at android.app.Activity.onCreate(Activity.java:1758)
at androidx.core.app.ComponentActivity.onCreate(ComponentActivity.java:88)
at androidx.activity.ComponentActivity.onCreate(ComponentActivity.java:363)
at androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:273)
at androidx.appcompat.app.AppCompatActivity.onCreate(AppCompatActivity.java:65347)
at com.yit.evrit.viewer.BaseActivity.onCreate(BaseActivity.kt:37)
at com.yit.evrit.viewer.BaseActivity.onCreate(BaseActivity.kt:216)
at com.yit.evrit.reader.BaseReaderActivity.onCreate(BaseReaderActivity.java:78)
at com.yit.evrit.reader.BaseReaderActivity.onCreate(BaseReaderActivity.java:259)
at com.yit.evrit.reader.epub.ui.main_screen.EpubReaderActivity.onCreate(EpubReaderActivity.java:461)
at com.yit.evrit.reader.epub.ui.main_screen.EpubReaderActivity.onCreate(EpubReaderActivity.java:1665)
at android.app.Activity.performCreate(Activity.java:8757)
at android.app.Activity.performCreate(Activity.java:8729)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1475)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:4005)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4181)
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:6349)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:6219)
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:76)
at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:144)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:101)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2643)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:257)
at android.os.Looper.loop(Looper.java:368)
at android.app.ActivityThread.main(ActivityThread.java:8839)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:572)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1049)
There still seems to be a proguard rule issue with androidx.window:window:1.1.0, 1.2.0 and 1.3.0. https://issuetracker.google.com/issues/165268619.
For now I found a temp solution by using the following proguard rules from https://issuetracker.google.com/issues/189001730#comment16.
-keep class androidx.window.extensions.** { *; }
-dontwarn androidx.window.extensions.**
# Keep the whole library for now since there is a crash with a missing method.
# TODO(b/165268619) Make a narrow rule
-keep class androidx.window.** { *; }
# We also neep to keep sidecar.** for the same reason.
-keep class androidx.window.sidecar.** { *; }
-dontwarn androidx.window.sidecar.**