Skip to content

Commit de3f71a

Browse files
committed
Work around a toolbar display issue with SDK 35+
Update Gradle version.
1 parent 8ef7ce1 commit de3f71a

File tree

14 files changed

+158
-17
lines changed

14 files changed

+158
-17
lines changed

.idea/compiler.xml

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MediaPhone/build.gradle

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
apply plugin: 'com.android.application'
22

33
android {
4-
namespace 'ac.robinson.mediaphone'
5-
testNamespace namespace + '.test'
6-
compileSdk 35
4+
namespace = 'ac.robinson.mediaphone'
5+
testNamespace = namespace + '.test'
6+
compileSdk = 35
77

8-
def getVersionCode = { -> return 61 }
8+
def getVersionCode = { -> return 62 }
99

1010
defaultConfig {
1111
manifestPlaceholders.providerId = 'mediaphone'
@@ -17,11 +17,15 @@ android {
1717
targetSdkVersion 35
1818
minSdkVersion 14
1919
versionCode getVersionCode()
20-
versionName '1.7.8'
20+
versionName '1.7.9'
2121
// versionNameSuffix = '-beta-1'
2222
resourceConfigurations += ['en', 'es', 'fr', 'nl', 'pt', 'pl', 'ru']
2323
}
2424

25+
compileOptions {
26+
sourceCompatibility JavaVersion.VERSION_21
27+
}
28+
2529
buildTypes {
2630
configureEach {
2731
buildConfigField 'java.util.Date', 'BUILD_TIME', 'new java.util.Date(' + Calendar.getInstance()
@@ -34,19 +38,19 @@ android {
3438
minifyEnabled true
3539
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-mediaphone.txt'
3640

37-
shrinkResources true
41+
shrinkResources = true
3842
}
3943

4044
// used solely for automatic screenshot generation - requires selecting in build variants pane to run via Android Studio
41-
testBuildType 'screenshots'
45+
testBuildType = 'screenshots'
4246
screenshots {
4347
initWith debug
4448
matchingFallbacks = ['debug']
4549
}
4650
}
4751
buildFeatures {
4852
// https://developer.android.com/r/tools/upgrade-assistant/build-config-default
49-
buildConfig true
53+
buildConfig = true
5054
}
5155

5256
// automatically regenerate fastlane metadata for new releases
@@ -82,8 +86,9 @@ dependencies {
8286
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
8387
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.3.0'
8488
}
89+
8590
java {
8691
toolchain {
87-
languageVersion = JavaLanguageVersion.of(17)
92+
languageVersion = JavaLanguageVersion.of(21)
8893
}
8994
}

MediaPhone/src/main/java/ac/robinson/mediaphone/MediaPhoneActivity.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@
122122
import androidx.core.app.NotificationManagerCompat;
123123
import androidx.core.content.ContextCompat;
124124
import androidx.core.content.FileProvider;
125+
import androidx.core.content.res.ResourcesCompat;
126+
import androidx.core.graphics.Insets;
127+
import androidx.core.view.ViewCompat;
128+
import androidx.core.view.WindowInsetsCompat;
125129
import androidx.exifinterface.media.ExifInterface;
126130

127131
public abstract class MediaPhoneActivity extends AppCompatActivity {
@@ -161,6 +165,7 @@ public abstract class MediaPhoneActivity extends AppCompatActivity {
161165
protected void onCreate(Bundle savedInstanceState) {
162166
super.onCreate(savedInstanceState);
163167
Window window = getWindow();
168+
164169
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
165170
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
166171
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
@@ -171,6 +176,21 @@ protected void onCreate(Bundle savedInstanceState) {
171176
setTaskDescription(taskDescription);
172177
}
173178

179+
// workaround for Android 15+ edge-to-edge mode because we still use an Action Bar and there doesn't seem
180+
// to be a documented way to deal with this automatically without going through the Toolbar upgrade route
181+
// see: https://stackoverflow.com/a/79338465
182+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
183+
ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(), (v, insets) -> {
184+
Insets bars = insets.getInsets(WindowInsetsCompat.Type.systemBars()
185+
| WindowInsetsCompat.Type.displayCutout() | WindowInsetsCompat.Type.ime());
186+
// setting a background colour changes the whole app's background colour; instead, use a drawable
187+
// v.setBackgroundColor(getResources().getColor(R.color.primary_dark, getTheme()));
188+
v.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.toolbar_background, getTheme()));
189+
v.setPadding(bars.left, bars.top, bars.right, bars.bottom);
190+
return WindowInsetsCompat.CONSUMED;
191+
});
192+
}
193+
174194
UIUtilities.setPixelDithering(window);
175195
checkDirectoriesExist();
176196

MediaPhone/src/main/java/ac/robinson/mediaphone/activity/CameraActivity.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@
8383
import androidx.appcompat.app.ActionBar;
8484
import androidx.appcompat.app.AlertDialog;
8585
import androidx.core.content.res.ResourcesCompat;
86+
import androidx.core.graphics.Insets;
87+
import androidx.core.view.ViewCompat;
88+
import androidx.core.view.WindowInsetsCompat;
8689

8790
public class CameraActivity extends MediaPhoneActivity {
8891

@@ -156,6 +159,30 @@ protected void onCreate(Bundle savedInstanceState) {
156159
findViewById(R.id.controls_pre21_wrapper).setFitsSystemWindows(true);
157160
}
158161

162+
// workaround for Android 15+ edge-to-edge mode because we still use an Action Bar and there doesn't seem
163+
// to be a documented way to deal with this automatically without going through the Toolbar upgrade route
164+
// see: https://stackoverflow.com/a/79338465
165+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
166+
ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(), (v, insets) -> {
167+
Insets bars = insets.getInsets(WindowInsetsCompat.Type.systemBars()
168+
| WindowInsetsCompat.Type.displayCutout() | WindowInsetsCompat.Type.ime());
169+
ActionBar supportActionBar = getSupportActionBar();
170+
boolean visibleActionBar = true;
171+
if (supportActionBar != null) {
172+
visibleActionBar = supportActionBar.isShowing();
173+
}
174+
if (!visibleActionBar) {
175+
// similar to the playback view, here we really do want a colour rather than drawable
176+
// (but we don't set top padding to zero because we aren't in true fullscreen mode
177+
v.setBackgroundColor(getResources().getColor(R.color.playback_background, getTheme()));
178+
} else {
179+
v.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.toolbar_background_playback, getTheme()));
180+
}
181+
v.setPadding(bars.left, bars.top, bars.right, bars.bottom);
182+
return WindowInsetsCompat.CONSUMED;
183+
});
184+
}
185+
159186
// note - we use this only to set the window dimensions accurately for padding (above); setFullScreen and
160187
// setNonFullScreen are still better elsewhere as they don't hide the navigation bar (TODO: refactor/combine)
161188
systemUiHider = new SystemUiHider(CameraActivity.this, findViewById(R.id.camera_view_root),

MediaPhone/src/main/java/ac/robinson/mediaphone/activity/PlaybackActivity.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,12 @@
8787
import androidx.appcompat.app.ActionBar;
8888
import androidx.appcompat.app.AlertDialog;
8989
import androidx.core.content.ContextCompat;
90+
import androidx.core.content.res.ResourcesCompat;
9091
import androidx.core.graphics.BlendModeColorFilterCompat;
9192
import androidx.core.graphics.BlendModeCompat;
93+
import androidx.core.graphics.Insets;
94+
import androidx.core.view.ViewCompat;
95+
import androidx.core.view.WindowInsetsCompat;
9296

9397
public class PlaybackActivity extends MediaPhoneActivity {
9498

@@ -169,6 +173,28 @@ protected void onCreate(Bundle savedInstanceState) {
169173
actionBar.setDisplayHomeAsUpEnabled(true);
170174
}
171175

176+
// workaround for Android 15+ edge-to-edge mode because we still use an Action Bar and there doesn't seem
177+
// to be a documented way to deal with this automatically without going through the Toolbar upgrade route
178+
// see: https://stackoverflow.com/a/79338465
179+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
180+
ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(), (v, insets) -> {
181+
Insets bars = insets.getInsets(WindowInsetsCompat.Type.systemBars()
182+
| WindowInsetsCompat.Type.displayCutout() | WindowInsetsCompat.Type.ime());
183+
int topPadding = bars.top;
184+
if (bars.bottom == 0) { // bottom of 0 = full-screen mode
185+
// unlike other places where we handle insets and use a hacky drawable, here we really do want a
186+
// colour (in full-screen mode) because the playback screen is meant to be as immersive as possible
187+
topPadding = 0;
188+
v.setBackgroundColor(getResources().getColor(R.color.playback_background, getTheme()));
189+
} else {
190+
// non-fullscreen mode
191+
v.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.toolbar_background_playback, getTheme()));
192+
}
193+
v.setPadding(bars.left, topPadding, bars.right, bars.bottom);
194+
return WindowInsetsCompat.CONSUMED;
195+
});
196+
}
197+
172198
setupUI(); // initialise the interface and fullscreen controls/timeouts
173199
refreshPlayback(); // initialise (and start) playback
174200
}

MediaPhone/src/main/java/ac/robinson/mediaphone/activity/PreferencesActivity.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@
7878
import androidx.appcompat.app.AppCompatDelegate;
7979
import androidx.core.app.ActivityCompat;
8080
import androidx.core.content.ContextCompat;
81+
import androidx.core.content.res.ResourcesCompat;
82+
import androidx.core.graphics.Insets;
83+
import androidx.core.view.ViewCompat;
84+
import androidx.core.view.WindowInsetsCompat;
8185

8286
/**
8387
* A {@link PreferenceActivity} for editing application settings.
@@ -104,6 +108,21 @@ protected void onCreate(Bundle savedInstanceState) {
104108
actionBar.setDisplayHomeAsUpEnabled(true);
105109
}
106110

111+
// workaround for Android 15+ edge-to-edge mode because we still use an Action Bar and there doesn't seem
112+
// to be a documented way to deal with this automatically without going through the Toolbar upgrade route
113+
// see: https://stackoverflow.com/a/79338465
114+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
115+
ViewCompat.setOnApplyWindowInsetsListener(getWindow().getDecorView(), (v, insets) -> {
116+
Insets bars = insets.getInsets(WindowInsetsCompat.Type.systemBars()
117+
| WindowInsetsCompat.Type.displayCutout());
118+
// setting a background colour changes the whole app's background colour; instead, use a drawable
119+
// v.setBackgroundColor(getResources().getColor(R.color.primary_dark, getTheme()));
120+
v.setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.toolbar_background, getTheme()));
121+
v.setPadding(bars.left, bars.top, bars.right, bars.bottom);
122+
return WindowInsetsCompat.CONSUMED;
123+
});
124+
}
125+
107126
setupPreferences();
108127
}
109128

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools">
4+
<!-- TODO: this is a hacky workaround for SDK 35+ due to our use of Action Bars rather than
5+
Toolbars. With the requirement to support edge-to-edge displays, we need to handle insets,
6+
(see MediaPhoneActivity.java), but when this is done, the status bar background ends up
7+
transparent and unusable. Setting a background colour there changes the colour of the
8+
whole application; instead we use a drawable to restore the previous behaviour. -->
9+
<item>
10+
<shape>
11+
<solid android:color="@color/primary_dark" />
12+
</shape>
13+
</item>
14+
<item
15+
android:top="?android:attr/actionBarSize"
16+
tools:targetApi="35"><!-- note: we assume that the status bar's height will never be more than the action bar's height -->
17+
<shape>
18+
<solid android:color="?android:colorBackground" />
19+
</shape>
20+
</item>
21+
</layer-list>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools">
4+
<!-- TODO: this is a hacky workaround for SDK 35+ due to our use of Action Bars rather than
5+
Toolbars. With the requirement to support edge-to-edge displays, we need to handle insets,
6+
(see MediaPhoneActivity.java), but when this is done, the status bar background ends up
7+
transparent and unusable. Setting a background colour there changes the colour of the
8+
whole application; instead we use a drawable to restore the previous behaviour. -->
9+
<item>
10+
<shape>
11+
<solid android:color="@color/primary_dark" />
12+
</shape>
13+
</item>
14+
<item
15+
android:top="?android:attr/actionBarSize"
16+
tools:targetApi="35"><!-- note: we assume that the status bar's height will never be more than the action bar's height -->
17+
<shape>
18+
<solid android:color="@color/playback_background" />
19+
</shape>
20+
</item>
21+
</layer-list>

0 commit comments

Comments
 (0)