diff --git a/build.gradle b/build.gradle index 20c4bb70..a89f84a5 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,7 @@ android { targetSdkVersion 34 versionCode 39 versionName "2.23.0" + applicationId "de.storchp.opentracks.osmplugin" testInstrumentationRunnerArguments runnerBuilder: 'de.mannodermaus.junit5.AndroidJUnit5Builder' testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index de8bbfae..e10743f2 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -29,6 +29,8 @@ android:name=".SettingsActivity" android:label="@string/title_activity_settings" android:theme="@style/AppTheme.NoActionBar" /> + + settingsActivityResultLauncher = registerForActivityResult( @@ -68,16 +58,6 @@ public boolean onOptionsItemSelected(MenuItem item) { showCompassSmoothingDialog(); } else if (itemId == R.id.stroke_width) { showStrokeWidthDialog(); - } else if (itemId == R.id.map_selection) { - startActivity(new Intent(this, MapSelectionActivity.class)); - } else if (itemId == R.id.theme_selection) { - startActivity(new Intent(this, ThemeSelectionActivity.class)); - } else if (itemId == R.id.map_folder) { - openDirectory(mapDirectoryLauncher); - } else if (itemId == R.id.theme_folder) { - openDirectory(themeDirectoryLauncher); - } else if (itemId == R.id.download_map) { - startActivity(new Intent(this, DownloadMapSelectionActivity.class)); } else if (itemId == R.id.overdraw_factor) { showOverdrawFactorDialog(); } else if (itemId == R.id.tilecache_capacity_factor) { @@ -317,61 +297,6 @@ public void onStopTrackingTouch(SeekBar seekBar) { }); } - protected final ActivityResultLauncher mapDirectoryLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), - result -> { - if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { - changeMapDirectory(result.getData().getData(), result.getData()); - } - }); - - protected final ActivityResultLauncher themeDirectoryLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), - result -> { - if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { - changeThemeDirectory(result.getData().getData(), result.getData()); - } - }); - - protected void openDirectory(ActivityResultLauncher launcher) { - try { - launcher.launch(createOpenDocumentIntent()); - } catch (ActivityNotFoundException exception) { - Toast.makeText(BaseActivity.this, R.string.no_file_manager_found, Toast.LENGTH_LONG).show(); - } - } - - @NonNull - private Intent createOpenDocumentIntent() { - var intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); - intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); - return intent; - } - - private void releaseOldPermissions() { - getContentResolver().getPersistedUriPermissions().stream() - .map(UriPermission::getUri) - .filter(uri -> !uri.equals(PreferencesUtils.getMapDirectoryUri()) - && !uri.equals(PreferencesUtils.getMapThemeDirectoryUri())) - .forEach(uri -> getContentResolver().releasePersistableUriPermission(uri, 0)); - } - - protected void changeThemeDirectory(Uri uri, Intent resultData) { - takePersistableUriPermission(uri, resultData); - PreferencesUtils.setMapThemeDirectoryUri(uri); - releaseOldPermissions(); - } - - protected void changeMapDirectory(Uri uri, Intent resultData) { - takePersistableUriPermission(uri, resultData); - PreferencesUtils.setMapDirectoryUri(uri); - releaseOldPermissions(); - } - - private void takePersistableUriPermission(Uri uri, Intent intent) { - int takeFlags = intent.getFlags(); - takeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - getContentResolver().takePersistableUriPermission(uri, takeFlags); - } - protected void keepScreenOn(boolean keepScreenOn) { if (keepScreenOn) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); diff --git a/src/main/java/de/storchp/opentracks/osmplugin/DirectoryChooserActivity.java b/src/main/java/de/storchp/opentracks/osmplugin/DirectoryChooserActivity.java new file mode 100644 index 00000000..b889ffa2 --- /dev/null +++ b/src/main/java/de/storchp/opentracks/osmplugin/DirectoryChooserActivity.java @@ -0,0 +1,78 @@ +package de.storchp.opentracks.osmplugin; + +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.content.UriPermission; +import android.net.Uri; +import android.os.Bundle; +import android.widget.Toast; + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; + +import de.storchp.opentracks.osmplugin.utils.PreferencesUtils; + +public abstract class DirectoryChooserActivity extends AppCompatActivity { + + protected final ActivityResultLauncher directoryIntentLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) { + onActivityResultCustom(result.getData()); + } + finish(); + }); + + abstract void onActivityResultCustom(@NonNull Intent resultData); + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + var intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); + intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); + + try { + directoryIntentLauncher.launch(intent); + } catch (final ActivityNotFoundException exception) { + Toast.makeText(this, R.string.no_file_manager_found, Toast.LENGTH_LONG).show(); + } + } + + protected void takePersistableUriPermission(Uri uri, Intent intent) { + int takeFlags = intent.getFlags(); + takeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + getContentResolver().takePersistableUriPermission(uri, takeFlags); + } + + protected void releaseOldPermissions() { + getContentResolver().getPersistedUriPermissions().stream() + .map(UriPermission::getUri) + .filter(uri -> !uri.equals(PreferencesUtils.getMapDirectoryUri()) + && !uri.equals(PreferencesUtils.getMapThemeDirectoryUri())) + .forEach(uri -> getContentResolver().releasePersistableUriPermission(uri, 0)); + } + + public static class MapDirectoryChooserActivity extends DirectoryChooserActivity { + + @Override + void onActivityResultCustom(@NonNull final Intent resultData) { + takePersistableUriPermission(resultData.getData(), resultData); + PreferencesUtils.setMapDirectoryUri(resultData.getData()); + releaseOldPermissions(); + } + } + + public static class ThemeDirectoryChooserActivity extends DirectoryChooserActivity { + + @Override + void onActivityResultCustom(@NonNull final Intent resultData) { + takePersistableUriPermission(resultData.getData(), resultData); + PreferencesUtils.setMapThemeDirectoryUri(resultData.getData()); + releaseOldPermissions(); + } + } + +} diff --git a/src/main/java/de/storchp/opentracks/osmplugin/DownloadActivity.java b/src/main/java/de/storchp/opentracks/osmplugin/DownloadActivity.java index 21b4591a..22f0a6fa 100644 --- a/src/main/java/de/storchp/opentracks/osmplugin/DownloadActivity.java +++ b/src/main/java/de/storchp/opentracks/osmplugin/DownloadActivity.java @@ -112,13 +112,13 @@ private boolean isDownloadInProgress() { public void startDownload() { var directoryUri = downloadType.getDirectoryUri(); if (directoryUri == null) { - openDirectory(downloadType.getLauncher(DownloadActivity.this)); + // TODO: openDirectory(downloadType.getLauncher(DownloadActivity.this)); return; } var directoryFile = FileUtil.getDocumentFileFromTreeUri(this, directoryUri); if (directoryFile == null || !directoryFile.canWrite()) { - openDirectory(downloadType.getLauncher(DownloadActivity.this)); + // TODO: openDirectory(downloadType.getLauncher(DownloadActivity.this)); return; } @@ -170,6 +170,7 @@ private void downloadEnded(boolean success, boolean canceled) { } } + /* TODO @Override protected void changeMapDirectory(Uri uri, Intent resultData) { super.changeMapDirectory(uri, resultData); @@ -182,6 +183,8 @@ protected void changeThemeDirectory(Uri uri, Intent resultData) { startDownload(); } + */ + private static class DownloadTask extends Thread { private final WeakReference ref; private final Uri downloadUri; @@ -331,7 +334,7 @@ public Uri getDirectoryUri() { @Override public ActivityResultLauncher getLauncher(BaseActivity activity) { - return activity.mapDirectoryLauncher; + return null; // TODO: activity.mapDirectoryLauncher; } }, MAP_ZIP(R.string.overwrite_map_question, R.string.download_success, R.string.download_failed, true) { @@ -341,7 +344,7 @@ public Uri getDirectoryUri() { } @Override public ActivityResultLauncher getLauncher(BaseActivity activity) { - return activity.mapDirectoryLauncher; + return null; // TODO: activity.mapDirectoryLauncher; } }, THEME(R.string.overwrite_theme_question, R.string.download_theme_success, R.string.download_theme_failed, false) { @@ -351,7 +354,7 @@ public Uri getDirectoryUri() { } @Override public ActivityResultLauncher getLauncher(BaseActivity activity) { - return activity.themeDirectoryLauncher; + return null; // TODO: activity.themeDirectoryLauncher; } }; @@ -385,6 +388,7 @@ public boolean isExtractMapFromZIP() { return extractMapFromZIP; } + // TODO: check if this is still needed after refactoring public abstract ActivityResultLauncher getLauncher(BaseActivity activity); } diff --git a/src/main/java/de/storchp/opentracks/osmplugin/SettingsActivity.java b/src/main/java/de/storchp/opentracks/osmplugin/SettingsActivity.java index 12825930..fe88a24b 100644 --- a/src/main/java/de/storchp/opentracks/osmplugin/SettingsActivity.java +++ b/src/main/java/de/storchp/opentracks/osmplugin/SettingsActivity.java @@ -1,11 +1,19 @@ package de.storchp.opentracks.osmplugin; +import static java.util.stream.Collectors.joining; + import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; +import androidx.documentfile.provider.DocumentFile; +import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; +import java.util.Objects; + import de.storchp.opentracks.osmplugin.databinding.ActivitySettingsBinding; +import de.storchp.opentracks.osmplugin.utils.FileUtil; +import de.storchp.opentracks.osmplugin.utils.PreferencesUtils; public class SettingsActivity extends AppCompatActivity { @@ -28,6 +36,72 @@ public static class SettingsFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.root_preferences, rootKey); + + var onlineMapConsentPreference = findPreference(getString(R.string.APP_PREF_ONLINE_MAP_CONSENT)); + if (onlineMapConsentPreference != null && BuildConfig.offline) { + onlineMapConsentPreference.setVisible(false); + } + + var mapDownloadPreference = findPreference(getString(R.string.APP_PREF_MAP_DOWNLOAD)); + if (mapDownloadPreference != null && BuildConfig.offline) { + mapDownloadPreference.setVisible(false); + } + + setSummaries(); + } + + @Override + public void onResume() { + super.onResume(); + setSummaries(); + } + + private void setSummaries() { + var mapsPreference = findPreference(getString(R.string.APP_PREF_MAP_SELECTION)); + if (mapsPreference != null) { + mapsPreference.setSummaryProvider((Preference.SummaryProvider) preference -> { + var mapUris = PreferencesUtils.getMapUris(); + if (mapUris.isEmpty() && !BuildConfig.offline) { + return getString(R.string.online_osm_mapnick); + } + return mapUris.stream() + .map(uri -> FileUtil.getDocumentFileFromTreeUri(getContext(), uri)) + .filter(Objects::nonNull) + .map(DocumentFile::getName) + .collect(joining(", ")); + }); + } + + var mapDirectoryPreference = findPreference(getString(R.string.APP_PREF_MAP_DIRECTORY)); + if (mapDirectoryPreference != null) { + mapDirectoryPreference.setSummaryProvider((Preference.SummaryProvider) preference -> { + var uri = PreferencesUtils.getMapDirectoryUri(); + return uri != null ? uri.getLastPathSegment() : null; + }); + } + + var themePreference = findPreference(getString(R.string.APP_PREF_MAP_THEME)); + if (themePreference != null) { + themePreference.setSummaryProvider((Preference.SummaryProvider) preference -> { + var themeUri = PreferencesUtils.getMapThemeUri(); + if (themeUri == null) { + return getString(R.string.default_theme); + } + var documentFile = FileUtil.getDocumentFileFromTreeUri(getContext(), themeUri); + if (documentFile == null) { + return getString(R.string.default_theme); + } + return documentFile.getName(); + }); + } + + var themeDirectoryPreference = findPreference(getString(R.string.APP_PREF_MAP_THEME_DIRECTORY)); + if (themeDirectoryPreference != null) { + themeDirectoryPreference.setSummaryProvider((Preference.SummaryProvider) preference -> { + var uri = PreferencesUtils.getMapThemeDirectoryUri(); + return uri != null ? uri.getLastPathSegment() : null; + }); + } } } diff --git a/src/main/res/menu/maps.xml b/src/main/res/menu/maps.xml index b93cabde..d3f93694 100644 --- a/src/main/res/menu/maps.xml +++ b/src/main/res/menu/maps.xml @@ -10,17 +10,6 @@ android:icon="@drawable/ic_baseline_share_24" /> - - - - - - - - - - - diff --git a/src/main/res/values/non-translatable-strings.xml b/src/main/res/values/non-translatable-strings.xml index eda9b3e9..2f4075d3 100644 --- a/src/main/res/values/non-translatable-strings.xml +++ b/src/main/res/values/non-translatable-strings.xml @@ -23,6 +23,8 @@ APP_MAP_TILE_CACHE_CAPACITY_FACTOR APP_PREF_STATISTIC_ELEMENTS APP_PREF_TRACK_COLOR_MODE + APP_PREF_MAP_SELECTION + APP_PREF_MAP_DOWNLOAD OSM: Mapnik - Mapsforge \n- Freizeitkarte Android diff --git a/src/main/res/xml/root_preferences.xml b/src/main/res/xml/root_preferences.xml index 8d7ba126..c2a16676 100644 --- a/src/main/res/xml/root_preferences.xml +++ b/src/main/res/xml/root_preferences.xml @@ -1,8 +1,9 @@ - + @@ -10,7 +11,7 @@ app:defaultValue="BY_SPEED" app:entries="@array/track_color_types" app:entryValues="@array/track_color_type_values" - app:key="APP_PREF_TRACK_COLOR_MODE" + app:key="@string/APP_PREF_TRACK_COLOR_MODE" app:title="@string/track_color" app:useSimpleSummaryProvider="true" /> @@ -18,7 +19,7 @@ app:defaultValue="NORTH" app:entries="@array/map_mode_types" app:entryValues="@array/map_mode_type_values" - app:key="APP_PREF_MAP_MODE" + app:key="@string/APP_PREF_MAP_MODE" app:title="@string/map_mode" app:useSimpleSummaryProvider="true" /> @@ -26,7 +27,7 @@ app:defaultValue="DIRECTION" app:entries="@array/arrow_mode_types" app:entryValues="@array/arrow_mode_type_values" - app:key="APP_PREF_ARROW_MODE" + app:key="@string/APP_PREF_ARROW_MODE" app:title="@string/arrow_mode" app:useSimpleSummaryProvider="true" /> @@ -34,29 +35,66 @@ + + + + + + + + + + + + + + + + +