From ee105a1610212cd2e9d55004fb3c4241ddcc4f0b Mon Sep 17 00:00:00 2001 From: Kilian Lackhove Date: Sun, 19 Apr 2026 12:16:14 +0200 Subject: [PATCH] Fix file import/export on debug builds Debug builds added .debug to the actual applicationId, but the settings XML used a flavor-level applicationId resource without that suffix, causing an "Unable to find explicit activity class" exception. Solved by generating the applicationId resource from each resolved variant and keeping debug and nightly branding limited to the launcher label. Also added an Android test that verifies the settings targets resolve on-device. --- build.gradle | 12 +++-- .../ImportExportSettingsIntentTest.java | 51 +++++++++++++++++++ src/debug/res/values/strings.xml | 2 +- src/main/AndroidManifest.xml | 2 +- src/main/res/values/do_not_translate.xml | 1 + src/nightly/res/values/strings.xml | 2 +- 6 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 src/androidTest/java/de/dennisguse/opentracks/settings/ImportExportSettingsIntentTest.java diff --git a/build.gradle b/build.gradle index d1f65c55b..ab370c0e2 100644 --- a/build.gradle +++ b/build.gradle @@ -107,7 +107,6 @@ android { nightly { dimension 'version' applicationId 'de.dennisguse.opentracks.nightly' - resValue 'string', 'applicationId', 'de.dennisguse.opentracks.nightly' versionCode getVersionCodeNightly() versionName getVersionName() @@ -119,7 +118,6 @@ android { // Non-reproducible: https://f-droid.org/de/packages/de.dennisguse.opentracks/ dimension 'version' applicationId 'de.dennisguse.opentracks' - resValue 'string', 'applicationId', 'de.dennisguse.opentracks' versionNameSuffix 'irreproducible' } reproducible { @@ -128,7 +126,6 @@ android { // PlayStore: https://play.google.com/store/apps/details?id=de.dennisguse.opentracks.playstore dimension 'version' applicationId 'de.dennisguse.opentracks.playstore' - resValue 'string', 'applicationId', 'de.dennisguse.opentracks.playstore' base.archivesName = "de.dennisguse.opentracks.playstore_${getVersionName()}_${android.defaultConfig.versionCode}" @@ -169,3 +166,12 @@ dependencies { androidTestUtil 'androidx.test:orchestrator:1.6.1' } + +androidComponents { + onVariants(selector().all()) { variant -> + variant.resValues.put( + new com.android.build.api.variant.impl.ResValueKeyImpl("string", "applicationId"), + new com.android.build.api.variant.ResValue(variant.applicationId.get(), null) + ) + } +} diff --git a/src/androidTest/java/de/dennisguse/opentracks/settings/ImportExportSettingsIntentTest.java b/src/androidTest/java/de/dennisguse/opentracks/settings/ImportExportSettingsIntentTest.java new file mode 100644 index 000000000..f05b83f25 --- /dev/null +++ b/src/androidTest/java/de/dennisguse/opentracks/settings/ImportExportSettingsIntentTest.java @@ -0,0 +1,51 @@ +package de.dennisguse.opentracks.settings; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; + +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import de.dennisguse.opentracks.BuildConfig; +import de.dennisguse.opentracks.R; + +@RunWith(AndroidJUnit4.class) +public class ImportExportSettingsIntentTest { + + private final Context context = ApplicationProvider.getApplicationContext(); + + @Test + public void applicationIdResource_matchesInstalledPackage() { + assertEquals(BuildConfig.APPLICATION_ID, context.getString(R.string.applicationId)); + assertEquals(context.getPackageName(), context.getString(R.string.applicationId)); + } + + @Test + public void importExportPreferenceTargets_areResolvableInCurrentPackage() throws PackageManager.NameNotFoundException { + assertResolvable("de.dennisguse.opentracks.io.file.importer.DirectoryChooserActivity$ImportDirectoryChooserActivity"); + assertResolvable("de.dennisguse.opentracks.io.file.importer.DirectoryChooserActivity$ExportDirectoryChooserActivity"); + assertResolvable("de.dennisguse.opentracks.io.file.importer.DirectoryChooserActivity$ExportDirectoryChooserOneFileActivity"); + assertResolvable("de.dennisguse.opentracks.io.file.importer.DirectoryChooserActivity$DefaultTrackExportDirectoryChooserActivity"); + } + + private void assertResolvable(String activityClassName) throws PackageManager.NameNotFoundException { + String applicationId = context.getString(R.string.applicationId); + ComponentName componentName = new ComponentName(applicationId, activityClassName); + + ActivityInfo activityInfo = context.getPackageManager().getActivityInfo(componentName, 0); + assertEquals(applicationId, activityInfo.packageName); + + ResolveInfo resolveInfo = context.getPackageManager().resolveActivity(new Intent().setComponent(componentName), 0); + assertNotNull(resolveInfo); + } +} diff --git a/src/debug/res/values/strings.xml b/src/debug/res/values/strings.xml index 350355fb2..994e901db 100644 --- a/src/debug/res/values/strings.xml +++ b/src/debug/res/values/strings.xml @@ -14,5 +14,5 @@ See the License for the specific language governing permissions and limitations under the License. --> - OpenTracks (Debug) + OpenTracks (Debug) diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 6c8d740ff..c231beac1 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -78,7 +78,7 @@ limitations under the License. android:hardwareAccelerated="true" android:hasFragileUserData="false" android:icon="@drawable/ic_launcher" - android:label="@string/app_name" + android:label="@string/launcher_name" android:supportsRtl="true" android:theme="@style/DayNightDynamicTheme"> diff --git a/src/main/res/values/do_not_translate.xml b/src/main/res/values/do_not_translate.xml index 0bc8fc9ad..a8bd70cdf 100644 --- a/src/main/res/values/do_not_translate.xml +++ b/src/main/res/values/do_not_translate.xml @@ -16,6 +16,7 @@ limitations under the License. https://codeberg.org/OpenTracksApp/OpenTracks OpenTracks + OpenTracks EGM2008 WGS84 diff --git a/src/nightly/res/values/strings.xml b/src/nightly/res/values/strings.xml index 16089f443..291ee71e9 100644 --- a/src/nightly/res/values/strings.xml +++ b/src/nightly/res/values/strings.xml @@ -1,4 +1,4 @@ - OpenTracks (Nightly) + OpenTracks (Nightly)