diff --git a/.clang-format b/.clang-format index 2f5f16771..a5b87e0ba 100644 --- a/.clang-format +++ b/.clang-format @@ -1,48 +1,59 @@ # Configuration file for clang-format, based on docs/CPP_STYLE.md. - ---- BasedOnStyle: Google AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignArrayOfStructures: Right +AlignConsecutiveMacros: AcrossEmptyLinesAndComments +AlignEscapedNewlines: LeftWithLastLine AlignOperands: AlignAfterOperator AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: Inline AllowShortIfStatementsOnASingleLine: Never AllowShortLoopsOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: true BraceWrapping: AfterCaseLabel: true AfterClass: true AfterControlStatement: Always AfterEnum: true + AfterExternBlock: true AfterFunction: true AfterNamespace: true AfterObjCDeclaration: true AfterStruct: true AfterUnion: true - AfterExternBlock: true BeforeCatch: true BeforeElse: true BeforeLambdaBody: true BeforeWhile: true - IndentBraces: false SplitEmptyFunction: false - SplitEmptyRecord: false SplitEmptyNamespace: false + SplitEmptyRecord: false +BinPackArguments: true +BinPackParameters: true +BreakAfterJavaFieldAnnotations: true BreakBeforeBraces: Custom BreakConstructorInitializers: BeforeComma BreakInheritanceList: BeforeComma ColumnLimit: 120 ConstructorInitializerIndentWidth: 2 -ContinuationIndentWidth: 2 +ContinuationIndentWidth: 4 DerivePointerAlignment: false IncludeBlocks: Preserve -IndentCaseLabels: false +IndentAccessModifiers: false IndentExternBlock: NoIndent +InsertBraces: false InsertNewlineAtEOF: true -PackConstructorInitializers: Never +LambdaBodyIndentation: OuterScope +PackConstructorInitializers: CurrentLine PointerAlignment: Middle +RemoveBracesLLVM: true QualifierAlignment: Right SpacesInContainerLiterals: false Standard: Latest TabWidth: 2 -UseTab: Never + +--- +Language: Java +AllowShortFunctionsOnASingleLine: Empty diff --git a/.forgejo/ISSUE_TEMPLATE/bug-report.yaml b/.forgejo/ISSUE_TEMPLATE/bug-report.yaml index 5ac2e1ce3..8d99c2136 100644 --- a/.forgejo/ISSUE_TEMPLATE/bug-report.yaml +++ b/.forgejo/ISSUE_TEMPLATE/bug-report.yaml @@ -1,6 +1,5 @@ name: 🐞 Bug Report description: Report a problem you've encountered -title: "bug: " labels: - bug body: @@ -67,4 +66,4 @@ body: label: Additional context description: Add any other context or comments that may be useful. validations: - required: false \ No newline at end of file + required: false diff --git a/.forgejo/ISSUE_TEMPLATE/feature-request.yaml b/.forgejo/ISSUE_TEMPLATE/feature-request.yaml index 91a2a6678..b87596114 100644 --- a/.forgejo/ISSUE_TEMPLATE/feature-request.yaml +++ b/.forgejo/ISSUE_TEMPLATE/feature-request.yaml @@ -1,6 +1,5 @@ name: "💡 Feature Request" description: "Suggest an idea or improvement for CoMaps" -title: "feat: " labels: - "enhancement" body: @@ -44,4 +43,4 @@ body: label: "Additional context" description: "Any other context, comments, or screenshots to support your request." validations: - required: false \ No newline at end of file + required: false diff --git a/.forgejo/workflows/android-beta.yaml b/.forgejo/workflows/android-beta.yaml index a58169484..ae052d561 100644 --- a/.forgejo/workflows/android-beta.yaml +++ b/.forgejo/workflows/android-beta.yaml @@ -32,9 +32,6 @@ on: - track_generator/** - xcode/** -env: - JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin - jobs: android-google-beta: name: Android Google Beta @@ -71,10 +68,6 @@ jobs: SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }} RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }} - - name: Configure repository - shell: bash - run: ./configure.sh - - name: Compile shell: bash working-directory: android diff --git a/.forgejo/workflows/android-check.yaml b/.forgejo/workflows/android-check.yaml index 41fc04745..de191b613 100644 --- a/.forgejo/workflows/android-check.yaml +++ b/.forgejo/workflows/android-check.yaml @@ -34,9 +34,6 @@ on: - track_generator/** - xcode/** -env: - JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin - jobs: lint: name: Android Lint @@ -51,10 +48,6 @@ jobs: shell: bash run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20)) - - name: Configure repository - shell: bash - run: ./configure.sh - - name: Lint shell: bash working-directory: android @@ -93,10 +86,6 @@ jobs: shell: bash run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20)) - - name: Configure repository - shell: bash - run: ./configure.sh - - name: Configure ccache uses: hendrikmuhs/ccache-action@v1.2 with: diff --git a/.forgejo/workflows/android-monkey.yaml b/.forgejo/workflows/android-monkey.yaml index c9b8f202c..dca83d79c 100644 --- a/.forgejo/workflows/android-monkey.yaml +++ b/.forgejo/workflows/android-monkey.yaml @@ -4,9 +4,6 @@ on: schedule: - cron: '0 5 * * 0' # Once per week at 05:00 UTC -env: - JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin - jobs: precondition: runs-on: ubuntu-latest @@ -73,10 +70,6 @@ jobs: SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }} RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }} - - name: Configure repository - shell: bash - run: ./configure.sh - - name: Compile shell: bash working-directory: android diff --git a/.forgejo/workflows/android-release-metadata.yaml b/.forgejo/workflows/android-release-metadata.yaml index 460cade7b..eb47f95b8 100644 --- a/.forgejo/workflows/android-release-metadata.yaml +++ b/.forgejo/workflows/android-release-metadata.yaml @@ -2,9 +2,6 @@ name: Android Release Metadata on: workflow_dispatch: # Manual trigger -env: - JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin - jobs: android-release-metadata: name: Upload Google Play metadata diff --git a/.forgejo/workflows/android-release.yaml b/.forgejo/workflows/android-release.yaml index d9b6ced05..33514ea08 100644 --- a/.forgejo/workflows/android-release.yaml +++ b/.forgejo/workflows/android-release.yaml @@ -5,7 +5,6 @@ on: env: RELEASE_NOTES: android/app/src/google/play/release-notes/en-US/default.txt FDROID_VERSION: android/app/src/fdroid/play/version.yaml - JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin jobs: tag: @@ -117,10 +116,6 @@ jobs: SECURE_PROPERTIES: ${{ secrets.SECURE_PROPERTIES }} RELEASE_KEYSTORE: ${{ secrets.RELEASE_KEYSTORE }} - - name: Configure repository - shell: bash - run: ./configure.sh - - name: Set up SDK shell: bash run: echo "sdk.dir=$ANDROID_SDK_ROOT" > android/local.properties diff --git a/.forgejo/workflows/appstream-check.yaml b/.forgejo/workflows/appstream-check.yaml index 5bd0d9bfb..459dfe03d 100644 --- a/.forgejo/workflows/appstream-check.yaml +++ b/.forgejo/workflows/appstream-check.yaml @@ -3,20 +3,20 @@ on: workflow_dispatch: # Manual trigger pull_request: paths: - - packaging/app.organicmaps.desktop.metainfo.xml - - .forgejo/workflows/appstream-check.yaml # Run check on self change + - packaging/app.comaps.comaps.metainfo.xml + - .forgejo/workflows/appstream-check.yaml # Run check on self change jobs: validate-appstream: name: Validate appstream metadata xml - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest steps: - name: Checkout sources uses: actions/checkout@v4 with: fetch-depth: 1 sparse-checkout: | - packaging/app.organicmaps.desktop.metainfo.xml + packaging/app.comaps.comaps.metainfo.xml - name: Install appstream validator and flatpak Builder shell: bash @@ -29,8 +29,8 @@ jobs: - name: Lint appstream data with flatpak Builder shell: bash - run: flatpak run --command=flatpak-builder-lint org.flatpak.Builder appstream packaging/app.organicmaps.desktop.metainfo.xml + run: flatpak run --command=flatpak-builder-lint org.flatpak.Builder appstream packaging/app.comaps.comaps.metainfo.xml - name: Run appstreamcli in pedantic mode shell: bash - run: flatpak run --command=appstreamcli org.flatpak.Builder validate --pedantic packaging/app.organicmaps.desktop.metainfo.xml + run: flatpak run --command=appstreamcli org.flatpak.Builder validate --pedantic packaging/app.comaps.comaps.metainfo.xml diff --git a/.forgejo/workflows/coverage-check.yaml b/.forgejo/workflows/coverage-check.yaml index 833b5180f..a67e3e83c 100644 --- a/.forgejo/workflows/coverage-check.yaml +++ b/.forgejo/workflows/coverage-check.yaml @@ -33,7 +33,7 @@ concurrency: jobs: should-run-check: name: Should run coverage - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest outputs: run-from-pr: ${{ steps.run-from-pr.outputs.run-from-pr }} manually-triggered: ${{ steps.manually-triggered.outputs.manually-triggered }} @@ -59,14 +59,9 @@ jobs: coverage: needs: should-run-check name: Generate coverage report - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest if: ${{ needs.should-run-check.outputs.run-from-pr == 'true' || needs.should-run-check.outputs.manually-triggered == 'true'}} steps: - - name: Free disk space by removing .NET, Android and Haskell - shell: bash - run: | - sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc - - name: Checkout sources uses: actions/checkout@v4 with: @@ -94,10 +89,6 @@ jobs: llvm \ gcovr - - name: Configure repository - shell: bash - run: ./configure.sh - - name: Configure ccache uses: hendrikmuhs/ccache-action@v1.2 with: diff --git a/.forgejo/workflows/dco.yml b/.forgejo/workflows/dco.yml index 8eed9448c..13e796fcb 100644 --- a/.forgejo/workflows/dco.yml +++ b/.forgejo/workflows/dco.yml @@ -5,4 +5,4 @@ jobs: check: runs-on: codeberg-tiny steps: - - uses: https://github.com/KineticCafe/actions-dco@v1 \ No newline at end of file + - uses: https://github.com/KineticCafe/actions-dco@v1 diff --git a/.forgejo/workflows/desktop-file-check.yaml b/.forgejo/workflows/desktop-file-check.yaml index 006ef8981..b0f6c0a7e 100644 --- a/.forgejo/workflows/desktop-file-check.yaml +++ b/.forgejo/workflows/desktop-file-check.yaml @@ -3,20 +3,20 @@ on: workflow_dispatch: # Manual trigger pull_request: paths: - - qt/res/app.organicmaps.desktop.desktop - - .forgejo/workflows/desktop-file-check.yaml # Run check on self change + - qt/res/app.comaps.comaps.desktop + - .forgejo/workflows/desktop-file-check.yaml # Run check on self change jobs: validate-desktop-file: name: Validate .desktop file - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest steps: - name: Checkout sources uses: actions/checkout@v4 with: fetch-depth: 1 sparse-checkout: | - qt/res/app.organicmaps.desktop.desktop + qt/res/app.comaps.comaps.desktop - name: Install desktop-file-validate tool shell: bash @@ -27,4 +27,4 @@ jobs: - name: Validate desktop file shell: bash - run: desktop-file-validate qt/res/app.organicmaps.desktop.desktop && echo "Successfully validated .desktop file" + run: desktop-file-validate qt/res/app.comaps.comaps.desktop && echo "Successfully validated .desktop file" diff --git a/.forgejo/workflows/ios-check.yaml b/.forgejo/workflows/ios-check.yaml index b8b1c3352..840d9b313 100644 --- a/.forgejo/workflows/ios-check.yaml +++ b/.forgejo/workflows/ios-check.yaml @@ -103,4 +103,4 @@ jobs: -destination 'generic/platform=iOS' \ -quiet \ CODE_SIGNING_REQUIRED=NO \ - CODE_SIGNING_ALLOWED=NO \ No newline at end of file + CODE_SIGNING_ALLOWED=NO diff --git a/.forgejo/workflows/linux-check.yaml b/.forgejo/workflows/linux-check.yaml index 75874fc81..ee76ec45a 100644 --- a/.forgejo/workflows/linux-check.yaml +++ b/.forgejo/workflows/linux-check.yaml @@ -31,18 +31,13 @@ on: jobs: linux-no-unity: name: Linux no unity build - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest # Cancels previous jobs if the same branch or PR was updated again. concurrency: group: ${{ github.workflow }}-no-unity-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true steps: - - name: Free disk space by removing .NET, Android and Haskell - shell: bash - run: | - sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc - - name: Checkout sources uses: actions/checkout@v4 with: @@ -71,10 +66,6 @@ jobs: libqt6positioning6-plugins \ libqt6positioning6 - - name: Configure repository - shell: bash - run: ./configure.sh - - name: Configure ccache uses: hendrikmuhs/ccache-action@v1.2 with: @@ -99,7 +90,7 @@ jobs: linux-matrix: name: Linux builds and tests - runs-on: ubuntu-24.04 + runs-on: ubuntu-latest strategy: fail-fast: false matrix: @@ -111,11 +102,6 @@ jobs: cancel-in-progress: true steps: - - name: Free disk space by removing .NET, Android and Haskell - shell: bash - run: | - sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc - - name: Checkout sources uses: actions/checkout@v4 @@ -142,10 +128,6 @@ jobs: libqt6positioning6-plugins \ libqt6positioning6 - - name: Configure repository - shell: bash - run: ./configure.sh - - name: Configure ccache uses: hendrikmuhs/ccache-action@v1.2 with: diff --git a/.forgejo/workflows/macos-check.yaml b/.forgejo/workflows/macos-check.yaml index 7a4737028..5c694e0f9 100644 --- a/.forgejo/workflows/macos-check.yaml +++ b/.forgejo/workflows/macos-check.yaml @@ -57,10 +57,6 @@ jobs: run: | HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install ninja qt@6 - - name: Configure repository - shell: bash - run: ./configure.sh - - name: Configure ccache uses: hendrikmuhs/ccache-action@v1.2 with: diff --git a/.github/workflows/android-check.yaml b/.github/workflows/android-check.yaml index a89939d8e..0e8146026 100644 --- a/.github/workflows/android-check.yaml +++ b/.github/workflows/android-check.yaml @@ -7,6 +7,7 @@ on: env: JAVA_HOME: /usr/lib/jvm/temurin-17-jdk-amd64 # Java 17 is required for Android Gradle 8 plugin + SKIP_MAP_DOWNLOAD: true jobs: lint: @@ -22,10 +23,6 @@ jobs: shell: bash run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20)) - - name: Init boost, generate textures - shell: bash - run: ./configure.sh --skip-map-download - - name: Lint shell: bash working-directory: android @@ -76,10 +73,6 @@ jobs: shell: bash run: git submodule update --depth 1 --init --recursive --jobs=$(($(nproc) * 20)) - - name: Init boost, generate textures - shell: bash - run: ./configure.sh --skip-map-download - - name: Configure ccache uses: hendrikmuhs/ccache-action@v1.2 with: diff --git a/.github/workflows/clang-format.yaml b/.github/workflows/clang-format.yaml new file mode 100644 index 000000000..f74088c8e --- /dev/null +++ b/.github/workflows/clang-format.yaml @@ -0,0 +1,43 @@ +name: clang-format + +on: + push: + branches: [ master ] + paths: + - 'android/app/src/**.java' + - '.clang-format' + - '.github/workflows/clang-format.yml' + pull_request: + branches: [ master ] + paths: + - 'android/app/src/**.java' + - '.clang-format' + - '.github/workflows/clang-format.yml' + +jobs: + check-formatting: + runs-on: ubuntu-latest + continue-on-error: true # TODO(AB): Remove this line when ready to enforce formatting. + + steps: + - uses: actions/checkout@v4 + + - name: Install clang-format + run: | + sudo apt-get update + sudo apt-get install -y clang-format-19 + clang-format-19 --version + + - name: Check Java formatting + run: | + JAVA_FILES=($(find android/app/src -name '*.java')) + + FORMATTING_ISSUES=$(clang-format-19 --dry-run --Werror $JAVA_FILES 2>&1 || true) + + if [ -n "$FORMATTING_ISSUES" ]; then + echo "$FORMATTING_ISSUES" + echo "" + echo "To fix formatting, please run:" + echo " clang-format -i " + exit 1 + fi diff --git a/.github/workflows/ios-check.yaml b/.github/workflows/ios-check.yaml index a732a887c..b644403c6 100644 --- a/.github/workflows/ios-check.yaml +++ b/.github/workflows/ios-check.yaml @@ -37,7 +37,7 @@ jobs: shell: bash run: git submodule update --depth 1 --init --recursive --jobs=$(($(sysctl -n hw.logicalcpu) * 20)) - - name: Init boost, download World map, generate textures + - name: Configure repository shell: bash run: ./configure.sh diff --git a/.gitignore b/.gitignore index 390e52bf4..de99b911d 100644 --- a/.gitignore +++ b/.gitignore @@ -14,12 +14,10 @@ stxxl.errlog stxxl.log screenlog.0 -data/styles/*/*/out/* -data/resources-*_design/* +data/symbols/*/design/ # symbols png/sdf are now generated at build -data/resources-*_*/symbols.png -data/resources-*_*/symbols.sdf -data/drules_proto_default_design.bin +data/symbols/**/symbols.png +data/symbols/**/symbols.sdf data/colors_design.txt data/patterns_design.txt data/bookmarks @@ -27,6 +25,14 @@ data/edits.xml data/traffic.xml data/World.mwm data/WorldCoasts.mwm +data/world_mwm/* +data/*_hash +data/drules_proto* +data/classificator.txt +data/types.txt +data/visibility.txt +data/colors.txt +data/patterns.txt # Compiled Python *.pyc @@ -47,8 +53,7 @@ omim.sdf *.rc !qt/res/windows.rc *.pdb -out/* -qt/mapswithme.log +out/ # XCode xcode/keys/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c0d227e1..975286cbd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ cmake_minimum_required(VERSION 3.22.1) + project(omim C CXX) set(CMAKE_CXX_STANDARD 20) @@ -48,6 +49,8 @@ if (APPLE AND NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL Android)) set(CMAKE_OBJCXX_VISIBILITY_PRESET hidden) endif() +execute_process(COMMAND "./configure.sh" WORKING_DIRECTORY ${OMIM_ROOT}) + message(STATUS "Using compiler ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}") if (CMAKE_UNITY_BUILD) @@ -103,12 +106,29 @@ if (${CMAKE_BUILD_TYPE} STREQUAL "Debug") elseif (${CMAKE_BUILD_TYPE} MATCHES "Rel") add_definitions(-DRELEASE) if (NOT MSVC) - add_compile_options(-Ofast) # Also enables -ffast-math + add_compile_options(-O3 $<$:-flto=auto>) endif() else() message(FATAL_ERROR "Unknown build type: " ${CMAKE_BUILD_TYPE}) endif() +if (${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo") + add_compile_options(-fno-omit-frame-pointer) +endif() + +# Linux GCC LTO plugin fix. +if (PLATFORM_LINUX AND (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND (CMAKE_BUILD_TYPE MATCHES "^Rel")) + # To force errors if LTO was not enabled. + add_compile_options(-fno-fat-lto-objects) + # To fix ar and ranlib "plugin needed to handle lto object". + string(REGEX MATCH "[0-9]+" GCC_MAJOR_VERSION ${CMAKE_CXX_COMPILER_VERSION}) + file(GLOB_RECURSE plugin /usr/lib/gcc/*/${GCC_MAJOR_VERSION}/liblto_plugin.so) + set(CMAKE_C_ARCHIVE_CREATE " --plugin ${plugin} qcs ") + set(CMAKE_C_ARCHIVE_FINISH " --plugin ${plugin} ") + set(CMAKE_CXX_ARCHIVE_CREATE " --plugin ${plugin} qcs ") + set(CMAKE_CXX_ARCHIVE_FINISH " --plugin ${plugin} ") +endif() + message(STATUS "Build type: " ${CMAKE_BUILD_TYPE}) if (PLATFORM_LINUX OR PLATFORM_ANDROID) @@ -243,11 +263,15 @@ if (PLATFORM_DESKTOP) add_subdirectory(qt) omim_add_tool_subdirectory(skin_generator) endif() + if (GENERATOR_TOOL) + add_compile_options(-march=native -mtune=native) + message(STATUS "target CPU optimizations enabled, produced binaries will NOT work on a different CPU") + endif() add_subdirectory(dev_sandbox) endif() omim_add_test_subdirectory(qt_tstfrm) if (PLATFORM_ANDROID) - add_subdirectory(android/app/src/main/cpp) + add_subdirectory(android/sdk/src/main/cpp) endif() diff --git a/INSTALL.md b/INSTALL.md index 273824947..162f96b5b 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1 +1 @@ -See [docs/INSTALL.md](docs/INSTALL.md) \ No newline at end of file +See [docs/INSTALL.md](docs/INSTALL.md) diff --git a/README.md b/README.md index 8c59e63c0..bb8cf175c 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,9 @@ A community-led free & open source maps app based on [OpenStreetMap](https://www F-Droid + + Obtainium + Codeberg @@ -122,10 +125,8 @@ You can help by donating, contributing code, translating, or by telling others a - Build instructions: [docs/INSTALL.md](docs/INSTALL.md) - Contribution guide: [docs/CONTRIBUTING.md](docs/CONTRIBUTING.md) -> [!NOTE] -> Some docs might be outdated, contain broken links or old references to Organic Maps, etc. Its a work in progress and help is much appreciated! -There is a dedicated Zulip chat for active contributors: [Zulip](https://comaps.zulipchat.com) +There is a dedicated [Zulip](https://codeberg.org/comaps/Governance/src/branch/main/contribute.md#3-team-messaging) chat for active contributors. --- @@ -160,4 +161,4 @@ MD5: 9cce0ffea281dc2f0e0a154d6d2e281e ## ⚖️ License Licensed under the Apache License 2.0. -See [LICENSE](LICENSE), [NOTICE](NOTICE), and [data/copyright.html](data/copyright.html). \ No newline at end of file +See [LICENSE](LICENSE), [NOTICE](NOTICE), and [data/copyright.html](data/copyright.html). diff --git a/android/Dockerfile b/android/Dockerfile index e65cf8a91..583c834ae 100644 --- a/android/Dockerfile +++ b/android/Dockerfile @@ -18,5 +18,4 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libxi-dev \ optipng WORKDIR /root/comaps -RUN ./configure.sh CMD ./gradlew -Parm64 assembleFdroidDebug diff --git a/android/app/build.gradle b/android/app/build.gradle index 548788f2f..23da71be5 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -15,43 +15,17 @@ buildscript { } } -repositories { - google() - mavenCentral() - maven { url 'https://www.jitpack.io' } // MPAndroidChart -} - apply plugin: 'com.android.application' apply plugin: 'com.github.triplet.play' apply plugin: 'ru.cian.huawei-publish-gradle-plugin' -def run(cmd) { - def stdout = new ByteArrayOutputStream() - exec { - commandLine = cmd - standardOutput = stdout - } - return stdout.toString() -} - import com.github.triplet.gradle.androidpublisher.ReleaseStatus -import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform - -def getVersion() { - def isWindows = DefaultNativePlatform.getCurrentOperatingSystem().isWindows() - def bash = isWindows ? 'C:\\Program Files\\Git\\bin\\bash.exe' : 'bash' - def versionCode = Integer.parseInt(run([bash, '../../tools/unix/version.sh', 'android_code']).trim()) - def versionName = run([bash, '../../tools/unix/version.sh', 'android_name']).trim() - return new Tuple2(versionCode, versionName) -} def getCommitMessage() { return run(['git', '--no-pager', 'show', '-s', '--format=%s%n%n%b', 'HEAD']).trim() } -def osName = System.properties['os.name'].toLowerCase() - project.ext.appId = 'app.comaps' project.ext.appName = 'CoMaps' @@ -63,7 +37,10 @@ project.ext.appName = 'CoMaps' //} android { - namespace 'app.organicmaps' + namespace = 'app.organicmaps' + + // TODO: it should not be here, but in sdk/build.gradle. But for some reason it should be specified here as well. + ndkVersion = '28.2.13676358' dependenciesInfo { // Disables dependency metadata when building APKs (for IzzyOnDroid/F-Droid) @@ -76,80 +53,32 @@ android { dataBinding = true buildConfig = true } - // All properties are read from gradle.properties file - compileSdk propCompileSdkVersion.toInteger() - ndkVersion '27.2.12479018' + // Users are complaining that the app should be re-downloaded from the Play Store after changing the language. + bundle { + language { + enableSplit = false + } + } + + // All properties are read from gradle.properties file + compileSdk = propCompileSdkVersion.toInteger() defaultConfig { - // Default package name is taken from the manifest and should be app.comaps - def ver = getVersion() - versionCode = ver.V1 - versionName = ver.V2 + versionCode = rootProject.ext.versionCode + versionName = rootProject.ext.versionName println('Version: ' + versionName) println('VersionCode: ' + versionCode) - minSdk propMinSdkVersion.toInteger() - targetSdk propTargetSdkVersion.toInteger() + minSdk = propMinSdkVersion.toInteger() + targetSdk = propTargetSdkVersion.toInteger() applicationId project.ext.appId buildConfigField 'String', 'SUPPORT_MAIL', '"android@comaps.app"' // Should be customized in flavors. buildConfigField 'String', 'REVIEW_URL', '""' - externalNativeBuild { - def pchFlag = 'OFF' - if (project.hasProperty('pch')) pchFlag = 'ON' + base.archivesName = appName.replaceAll('\\s','') + '-' + defaultConfig.versionCode - def njobs = '' - if (project.hasProperty('njobs')) njobs = project.getProperty('njobs') - - def enableVulkanDiagnostics = 'OFF' - if (project.hasProperty('enableVulkanDiagnostics')) { - enableVulkanDiagnostics = project.getProperty('enableVulkanDiagnostics') - } - - def enableTrace = 'OFF' - if (project.hasProperty('enableTrace')) { - enableTrace = project.getProperty('enableTrace') - } - - cmake { - cppFlags '-fexceptions', '-frtti' - // There is no sense to enable sections without gcc's --gc-sections flag. - cFlags '-fno-function-sections', '-fno-data-sections', - '-Wno-extern-c-compat' - arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static', - "-DOS=$osName", '-DSKIP_TESTS=ON', '-DSKIP_TOOLS=ON', "-DUSE_PCH=$pchFlag", - "-DNJOBS=$njobs", "-DENABLE_VULKAN_DIAGNOSTICS=$enableVulkanDiagnostics", - "-DENABLE_TRACE=$enableTrace" - targets 'organicmaps' - } - } - - // Use, for example, -Parm32 gradle parameter to build only for armeabi-v7a. - ndk { - abiFilters = new HashSet<>() - if (project.hasProperty('arm32') || project.hasProperty('armeabi-v7a')) { - abiFilters.add('armeabi-v7a') - } - if (project.hasProperty('arm64') || project.hasProperty('arm64-v8a')) { - abiFilters.add('arm64-v8a') - } - if (project.hasProperty('x86')) { - abiFilters.add('x86') - } - if (project.hasProperty('x86_64') || project.hasProperty('x64')) { - abiFilters.add('x86_64') - } - if (abiFilters.isEmpty()) { - abiFilters.add('armeabi-v7a') - abiFilters.add('arm64-v8a') - // For the emulator, chromebooks and some Intel Atom devices. - abiFilters.add('x86_64') - } - println('Building for ' + abiFilters + ' archs.') - } - - setProperty('archivesBaseName', appName.replaceAll('\\s','') + '-' + defaultConfig.versionCode) + ndk.debugSymbolLevel = 'full' } flavorDimensions += 'default' @@ -199,10 +128,10 @@ android { splits.abi { boolean enabled = project.hasProperty('splitApk') println ('Create separate apks: ' + enabled) - enable enabled + enable = enabled reset() include 'x86', 'armeabi-v7a', 'arm64-v8a', 'x86_64' - universalApk true + universalApk = true } lint { @@ -215,7 +144,7 @@ android { disable 'CustomSplashScreen' // https://github.com/organicmaps/organicmaps/issues/3610 disable 'InsecureBaseConfiguration' - abortOnError true + abortOnError = true } gradle.projectsEvaluated { @@ -274,33 +203,29 @@ android { debug { applicationIdSuffix '.debug' // Allows to install debug and release builds together versionNameSuffix '-debug' - jniDebuggable true // Enable jni debug build zipAlignEnabled true - signingConfig signingConfigs.debug + signingConfig = signingConfigs.debug resValue 'string', 'app_name', 'CoMaps Debug' - // Do not generate separate debug symbols for debug apps, because we don't distribute them. - ndk.debugSymbolLevel = 'none' } release { if (taskName.contains('release')) { if (secureReleasePropertiesFileExists) { println('Using RELEASE signing keys from secure.properties.release') - signingConfig signingConfigs.release + signingConfig = signingConfigs.release } else { println('NO RELEASE signing keys found') println('Using DEBUG signing keys') - signingConfig signingConfigs.debug + signingConfig = signingConfigs.debug } } + minifyEnabled true - shrinkResources true + shrinkResources = true // Includes the default ProGuard rules files that are packaged with the Android Gradle plugin. // To learn more, go to the documentation section about R8 configuration files. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' resValue 'string', 'app_name', project.ext.appName - // Full size symbols are too big for Google, 217mb aab vs 95mb. - ndk.debugSymbolLevel = 'symbol_table' } beta { @@ -309,37 +234,27 @@ android { if (taskName.contains('beta')) { if (secureTestPropertiesFileExists) { println('Using TEST signing keys from secure.properties.test') - signingConfig signingConfigs.test + signingConfig = signingConfigs.test } else { println('NO TEST signing keys found') println('Using DEBUG signing keys') - signingConfig signingConfigs.debug + signingConfig = signingConfigs.debug } } minifyEnabled true - shrinkResources true + shrinkResources = true // Includes the default ProGuard rules files that are packaged with the Android Gradle plugin. // To learn more, go to the documentation section about R8 configuration files. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' matchingFallbacks = ['release'] // use dependencies of "release" build type resValue 'string', 'app_name', 'CoMaps Test' - // Full size symbols are too big for Google, 217mb aab vs 95mb. - ndk.debugSymbolLevel = 'symbol_table' - } - } - - externalNativeBuild { - cmake { - version '3.22.1+' - buildStagingDirectory './nativeOutputs' - path '../../CMakeLists.txt' } } // We don't compress these extensions in assets/ because our random FileReader can't read zip-compressed files from apk. // TODO: Load all minor files via separate call to ReadAsString which can correctly handle compressed files in zip containers. androidResources { - ignoreAssetsPattern '!.svn:!.git:!.DS_Store:!*.scc:.*:_*:!CVS:!thumbs.db:!picasa.ini:!*~' + ignoreAssetsPattern = '!.svn:!.git:!.DS_Store:!*.scc:.*:_*:!CVS:!thumbs.db:!picasa.ini:!*~' noCompress = ['txt', 'bin', 'html', 'png', 'json', 'mwm', 'ttf', 'sdf', 'ui', 'config', 'csv', 'spv', 'obj'] localeFilters += [ "af", @@ -396,7 +311,7 @@ android { } compileOptions { - coreLibraryDesugaringEnabled true + coreLibraryDesugaringEnabled = true sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 @@ -404,6 +319,8 @@ android { } dependencies { + implementation project(':sdk') + coreLibraryDesugaring libs.android.tools.desugar // Google Play Location Services @@ -449,10 +366,6 @@ dependencies { testImplementation libs.mockito.core } -tasks.withType(JavaCompile) { - options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation' -} - android.applicationVariants.all { variant -> def authorityValue = variant.applicationId + ".provider" def authority = "\"" + authorityValue + "\"" @@ -500,3 +413,7 @@ huaweiPublish { } } } + +tasks.withType(JavaCompile).configureEach { + options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation' +} diff --git a/android/app/src/beta/res/mipmap-hdpi/ic_launcher.png b/android/app/src/beta/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 3eb6f9a55..000000000 Binary files a/android/app/src/beta/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/beta/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/beta/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index b63e3f330..000000000 Binary files a/android/app/src/beta/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/beta/res/mipmap-mdpi/ic_launcher.png b/android/app/src/beta/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 8c43219a3..000000000 Binary files a/android/app/src/beta/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/beta/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/beta/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index d4ea8a846..000000000 Binary files a/android/app/src/beta/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/beta/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/beta/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index b8cfe99b6..000000000 Binary files a/android/app/src/beta/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/beta/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/beta/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index c9d6adea7..000000000 Binary files a/android/app/src/beta/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/beta/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/beta/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 068405fb6..000000000 Binary files a/android/app/src/beta/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/beta/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/beta/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index f4f14ed6e..000000000 Binary files a/android/app/src/beta/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/beta/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/beta/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 0d71208ab..000000000 Binary files a/android/app/src/beta/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/beta/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/beta/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index d347b5e92..000000000 Binary files a/android/app/src/beta/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/android/app/src/debug/res/mipmap-hdpi/ic_launcher.png b/android/app/src/debug/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 25cea1a69..000000000 Binary files a/android/app/src/debug/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/debug/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/debug/res/mipmap-hdpi/ic_launcher_foreground.png deleted file mode 100644 index 7c95ae3b8..000000000 Binary files a/android/app/src/debug/res/mipmap-hdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/debug/res/mipmap-mdpi/ic_launcher.png b/android/app/src/debug/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c39a6ea6e..000000000 Binary files a/android/app/src/debug/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/debug/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/debug/res/mipmap-mdpi/ic_launcher_foreground.png deleted file mode 100644 index e049c0bc1..000000000 Binary files a/android/app/src/debug/res/mipmap-mdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/debug/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/debug/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index d0aeb2ccc..000000000 Binary files a/android/app/src/debug/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/debug/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/debug/res/mipmap-xhdpi/ic_launcher_foreground.png deleted file mode 100644 index bead024b0..000000000 Binary files a/android/app/src/debug/res/mipmap-xhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/debug/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/debug/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index bcf93bd22..000000000 Binary files a/android/app/src/debug/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/debug/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/debug/res/mipmap-xxhdpi/ic_launcher_foreground.png deleted file mode 100644 index caff93fb9..000000000 Binary files a/android/app/src/debug/res/mipmap-xxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 856ae7f43..000000000 Binary files a/android/app/src/debug/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_foreground.png deleted file mode 100644 index c21da8b40..000000000 Binary files a/android/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_foreground.png and /dev/null differ diff --git a/android/app/src/fdroid/java/app/organicmaps/location b/android/app/src/fdroid/java/app/organicmaps/location deleted file mode 120000 index c3bacf635..000000000 --- a/android/app/src/fdroid/java/app/organicmaps/location +++ /dev/null @@ -1 +0,0 @@ -../../../../google/java/app/organicmaps/location \ No newline at end of file diff --git a/android/app/src/fdroid/java/app/organicmaps/sdk/location b/android/app/src/fdroid/java/app/organicmaps/sdk/location new file mode 120000 index 000000000..f41d2255b --- /dev/null +++ b/android/app/src/fdroid/java/app/organicmaps/sdk/location @@ -0,0 +1 @@ +../../../../../google/java/app/organicmaps/sdk/location \ No newline at end of file diff --git a/android/app/src/fdroid/play/listings/bn/short-description.txt b/android/app/src/fdroid/play/listings/bn/short-description.txt new file mode 100644 index 000000000..aac6a2300 --- /dev/null +++ b/android/app/src/fdroid/play/listings/bn/short-description.txt @@ -0,0 +1 @@ +সহজ মানচিত্র নেভিগেশন - আপনার যাত্রা সম্পর্কে আরও জানুন - সম্প্রদায় কর্তৃক পরিচালিত diff --git a/android/app/src/fdroid/play/listings/bn/title.txt b/android/app/src/fdroid/play/listings/bn/title.txt new file mode 100644 index 000000000..6123e8757 --- /dev/null +++ b/android/app/src/fdroid/play/listings/bn/title.txt @@ -0,0 +1 @@ +কোম্যাপস - অফলাইনে হাইকিং, সাইকেলিং এবং ড্রাইভিং করুন গোপনীয়তা সহ diff --git a/android/app/src/fdroid/play/listings/ca/short-description.txt b/android/app/src/fdroid/play/listings/ca/short-description.txt new file mode 100644 index 000000000..9f18db629 --- /dev/null +++ b/android/app/src/fdroid/play/listings/ca/short-description.txt @@ -0,0 +1 @@ +Navegació intuïtiva - Descobreix el teu camí - El poder de la comunitat diff --git a/android/app/src/fdroid/play/listings/cs-CZ/release-notes.txt b/android/app/src/fdroid/play/listings/cs-CZ/release-notes.txt new file mode 100644 index 000000000..b6009257a --- /dev/null +++ b/android/app/src/fdroid/play/listings/cs-CZ/release-notes.txt @@ -0,0 +1,7 @@ +• Data OpenStreetMap k 4. 8. +• vylepšené barvy mapy pro vodu, lesy, křoviny, různé vybavení, pěší zóny atd. +• přidány stanice lesní stráže, krytých parkovišť pro jízdní kola, únikových her, úschoven zavazadel, partnerských pošt +• vylepšeny výškové vrstevnice na 20 m pro některé oblíbené turistické oblasti +• podpora více zkratek a aliasů pro vyhledávání +• přidání ikon pro vyhledávání a záložky pro rychlé občerstvení, jízdní kola a dobíjecí stanice +• plynulejší pohyb šipky pro určení polohy diff --git a/android/app/src/fdroid/play/listings/de-DE/release-notes.txt b/android/app/src/fdroid/play/listings/de-DE/release-notes.txt index 83c0a7f5a..6c49d88e9 100644 --- a/android/app/src/fdroid/play/listings/de-DE/release-notes.txt +++ b/android/app/src/fdroid/play/listings/de-DE/release-notes.txt @@ -1,9 +1,7 @@ -Wir stellen vor: Das neue CoMaps-Logo! -• Verbesserte Höhenlinien in vielen Regionen (Stufen von 20/50 m) -• Links zu Panoramax-Bildern für ausgewählte POIs -• OpenStreetMap-Daten vom 13. Juli -• Neue Farben für viele Objekte und Farben werden früher angezeigt -• Öffnungszeiten werden beim Antippen eines POI angezeigt -• Verschiedene Arten von Feuchtgebieten -• Neue Farben für Vegetation und andere Features; einige neue Icons -• Wandern: bessere Darstellung der Höhenlinien \ No newline at end of file +• OpenStreetMap-Daten vom 4. August +• Verbesserte Farben für Wasser, Wälder, Gestrüpp, verschiedene Einrichtungen, Fussgängerbereiche etc. +• Besucherstationen, überdachte Fahrradparkplätze, Escaperooms, Gepäckschließfächer, und Postpartner hinzugefügt +• Konturhöhenlinien aktualisiert, bis zu 20m für beliebte Wanderregionen +• Unterstützung für mehr Such-Abkürzungen und Synonyme +• Such- und Lesezeichen-Symbole für Fast Food, Rad- und Lade-Stationen +• Der Positionspfeil bewegt sich gleichmässiger diff --git a/android/app/src/fdroid/play/listings/en-US/release-notes.txt b/android/app/src/fdroid/play/listings/en-US/release-notes.txt index c29d708be..30680de88 100644 --- a/android/app/src/fdroid/play/listings/en-US/release-notes.txt +++ b/android/app/src/fdroid/play/listings/en-US/release-notes.txt @@ -1,10 +1,7 @@ -Introducing CoMaps logo! - -• upgrade altitude contour lines for many regions to 20 or 50 meters step -• add Panoramax Picture links to selected POIs -• OpenStreetMap data as of July 13 -• add color fills to many features and display fills earlier for existing features -• display opening hours state when selecting a POI -• split all wetlands into several distinct types -• update vegetation and other map colors, update some map icons -• outdoors: bolder altitude contour lines +• OpenStreetMap data as of August 4 +• improve map colors for water, forests, scrubs, various amenities, pedestrian areas etc. +• add ranger stations, covered bicycle parkings, escape games, luggage lockers, post office partners +• upgrade altitude contour lines to 20m step for some popular hiking regions +• support more search abbreviations and aliases +• add search and bookmark icons for fast food, bicycle and charging stations +• more smooth position arrow movements diff --git a/android/app/src/fdroid/play/listings/es-ES/full-description.txt b/android/app/src/fdroid/play/listings/es-ES/full-description.txt new file mode 100644 index 000000000..dc9c35d8c --- /dev/null +++ b/android/app/src/fdroid/play/listings/es-ES/full-description.txt @@ -0,0 +1,65 @@ +Una aplicación de mapas gratuita y de código abierto liderada por la comunidad, basada en los datos de OpenStreetMap y reforzada con un compromiso con la transparencia, la privacidad y la ausencia de fines de lucro. CoMaps es un fork o derivado de Organic Maps, que a su vez es un fork de Maps.ME. + +

+ +Lee más sobre los motivos del proyecto y su dirección en codeberg.org/comaps. + +

+ +Únete allí a la comunidad y ayuda a crear la mejor app de mapas + +• Usa la aplicación y corre la voz sobre ella + +• Envía comentarios y reporta problemas + +• Actualiza los datos del mapa en la app o en el sitio web de OpenStreetMap + +

+ +‣ Enfocada en el uso sin conexión: Planifica y navega tus viajes sin necesidad de conexión móvil, busca puntos de paso en rutas remotas, etc. Todas las funciones están diseñadas para funcionar sin conexión. + +‣ Respeta tu Privacidad: La app está diseñada pensando en tu privacidad: no identifica personas, no rastrea y no recoge datos personales. Sin publicidad. + +‣ Sencilla y Pulida: funciones esenciales fáciles de usar que simplemente funcionan. + +‣ Ahorra Batería y Espacio: No consume la batería como otras apps de navegación. Los mapas compactos ahorran espacio valioso en tu teléfono. + +‣ Gratuita y Creada por la Comunidad: Personas como tú ayudaron a construir la app añadiendo lugares a OpenStreetMap, probando funciones, dando opiniones y contribuyendo con desarrollo o financiación. + +‣ Toma de decisiones y finanzas abiertas y transparentes, sin ánimo de lucro y completamente de código abierto. + +

+ +Funciones Principales: + +• Mapas detallados descargables con lugares que no aparecen en Google Maps + +• Modo exterior con rutas de senderismo destacadas, campings, fuentes de agua, picos, curvas de nivel, etc. + +• Caminos peatonales y carriles bici + +• Puntos de interés como restaurantes, gasolineras, hoteles, tiendas, lugares turísticos y muchos más + +• Búsqueda por nombre, dirección o categoría de punto de interés + +• Navegación con indicaciones por voz para caminar, ir en bici o conducir + +• Guarda tus lugares favoritos con un solo toque + +• Artículos de Wikipedia sin conexión + +• Capa de transporte subterráneo y rutas + +• Grabación de rutas + +• Exporta e importa favoritos y rutas en formatos KML, KMZ y GPX + +• Modo oscuro para usar de noche + +• Mejora los datos del mapa para todos usando un editor básico integrado + +

+ +La Libertad Está Aquí + +Descubre tu camino, navega el mundo con privacidad y con la comunidad como prioridad. diff --git a/android/app/src/fdroid/play/listings/es-ES/release-notes.txt b/android/app/src/fdroid/play/listings/es-ES/release-notes.txt index ef0e7485f..9ea20621d 100644 --- a/android/app/src/fdroid/play/listings/es-ES/release-notes.txt +++ b/android/app/src/fdroid/play/listings/es-ES/release-notes.txt @@ -1,9 +1,7 @@ -¡Presentamos el logo de CoMaps! -• mejora de isolíneas con más detalle para muchas regiones -• añade enlaces de imágenes de Panoramax a POIs seleccionados -• datos de OpenStreetMap a 13 de julio -• añadidos rellenos de color a muchas características -• se muestra el estado de horarios de apertura al seleccionar un POI -• se dividen los humedales en tipos distintos -• se actualiza la vegetación y otros colores del mapa, así como otros iconos -• exteriores: líneas de contorno de altitud más gruesas \ No newline at end of file +• Datos de OpenStreetMap a fecha 2025.08.04 +• Mejora de colores del mapa para agua, bosques, matorrales, servicios, zonas peatonales, etc. +• Añadidas estaciones de guardabosques, aparcamientos cubiertos de bicis, juegos de escape, consignas y oficinas de correo +• Nuevas curvas de nivel (20 m) en regiones populares para senderismo +• Más abreviaturas y alias de búsqueda +• Iconos de búsqueda y marcadores para comida rápida, bicicletas y estaciones de recarga +• Más fluidez de la flecha de posición diff --git a/android/app/src/fdroid/play/listings/es-ES/short-description.txt b/android/app/src/fdroid/play/listings/es-ES/short-description.txt new file mode 100644 index 000000000..f45617084 --- /dev/null +++ b/android/app/src/fdroid/play/listings/es-ES/short-description.txt @@ -0,0 +1 @@ +Navegación de mapa fácil - Descubre más en tu camino - Creado por la comunidad diff --git a/android/app/src/fdroid/play/listings/es-ES/title.txt b/android/app/src/fdroid/play/listings/es-ES/title.txt new file mode 100644 index 000000000..d1d88becf --- /dev/null +++ b/android/app/src/fdroid/play/listings/es-ES/title.txt @@ -0,0 +1 @@ +CoMaps - Senderismo, ciclismo y conducción offline diff --git a/android/app/src/fdroid/play/listings/fa-IR/short-description.txt b/android/app/src/fdroid/play/listings/fa-IR/short-description.txt new file mode 100644 index 000000000..0bf48b4da --- /dev/null +++ b/android/app/src/fdroid/play/listings/fa-IR/short-description.txt @@ -0,0 +1 @@ +ناوبری آسان نقشه - کشف بیشتر از سفر شما - توسط جامعه diff --git a/android/app/src/fdroid/play/listings/fa-IR/title.txt b/android/app/src/fdroid/play/listings/fa-IR/title.txt new file mode 100644 index 000000000..4c116ac10 --- /dev/null +++ b/android/app/src/fdroid/play/listings/fa-IR/title.txt @@ -0,0 +1 @@ +CoMaps - کوه نوردی، دوچرخه سواری و رانندگی افلاین و خصوصی diff --git a/android/app/src/fdroid/play/listings/fr-FR/release-notes.txt b/android/app/src/fdroid/play/listings/fr-FR/release-notes.txt deleted file mode 100644 index 8403d45dd..000000000 --- a/android/app/src/fdroid/play/listings/fr-FR/release-notes.txt +++ /dev/null @@ -1,7 +0,0 @@ -Présentation du logo CoMaps ! -• Amélioration des courbes d’altitude à une précision de 20 ou 50 mètres pour de nombreuses régions -• Ajout d'un lien vers les images Panoramax des POI -• Données OpenStreetMap du 13 juillet -• Affichage de l’état des heures d’ouverture lors de la sélection d’un POI -• Mise à jour du style(végétation et zones humides), mise à jour de certaines icônes de la carte -• Outdoors: Améliorations de la visibilité des courbes d'altitude diff --git a/android/app/src/fdroid/play/listings/fr-FR/short-description.txt b/android/app/src/fdroid/play/listings/fr-FR/short-description.txt index 3a6d8ef89..dc5921a55 100644 --- a/android/app/src/fdroid/play/listings/fr-FR/short-description.txt +++ b/android/app/src/fdroid/play/listings/fr-FR/short-description.txt @@ -1 +1 @@ -Navigation cartographique facile - Découvrez davantage de votre voyage - Propulsé par la communauté +Navigation de cartes facile - Découvrez le monde - Propulsé par la communauté diff --git a/android/app/src/fdroid/play/listings/hu-HU/short-description.txt b/android/app/src/fdroid/play/listings/hu-HU/short-description.txt new file mode 100644 index 000000000..e818f3e16 --- /dev/null +++ b/android/app/src/fdroid/play/listings/hu-HU/short-description.txt @@ -0,0 +1 @@ +Könnyű térképes navigáció - Fedezz fel többet az útjaidról - A közösség erejével diff --git a/android/app/src/fdroid/play/listings/ia/short-description.txt b/android/app/src/fdroid/play/listings/ia/short-description.txt new file mode 100644 index 000000000..df5517d58 --- /dev/null +++ b/android/app/src/fdroid/play/listings/ia/short-description.txt @@ -0,0 +1 @@ +Navigation facile del mappa – Discoperi tu viage – Alimentate per le communitate diff --git a/android/app/src/fdroid/play/listings/it-IT/release-notes.txt b/android/app/src/fdroid/play/listings/it-IT/release-notes.txt new file mode 100644 index 000000000..a2a553b3a --- /dev/null +++ b/android/app/src/fdroid/play/listings/it-IT/release-notes.txt @@ -0,0 +1,7 @@ +• Dati di OpenStreetMap aggiornati al 4 Agosto +• Migliorati i colori per acqua, foreste, servizi etc +• Aggiunte le stazioni delle guardie forestali, i parcheggi coperti per bici, gli escape games e altri servizi +• Aggiornato l'intervallo delle isolinee a 20 m per le zone escursionistiche più popolari +• Aggiunto il supporto per un maggior numero di alias +• Aggiunte le icone per i fast food, i punti di ricarica e le biciclette +• Resi più fluidi i movimenti della freccia di posizione diff --git a/android/app/src/fdroid/play/listings/pl-PL/release-notes.txt b/android/app/src/fdroid/play/listings/pl-PL/release-notes.txt deleted file mode 100644 index af93517ac..000000000 --- a/android/app/src/fdroid/play/listings/pl-PL/release-notes.txt +++ /dev/null @@ -1,9 +0,0 @@ -Wprowadzamy logo CoMaps! -• zwiększenie dokładności izolinii w wielu regionach w krokach 20 do 50 metrów -• dodanie linków do zdjęć z Panoramax do wybranych POI -• aktualizacja danych OpenStreetMap z 13 lipca -• dodanie wypełnienia kolorem dla wielu typów obiektów -• wyświetlanie stanu godzin otwarcia przy wyborze POI -• podział mokradeł na kilka typów -• aktualizacja koloru roślinności i innych kolorów, aktualizacja części ikon na mapie -• tryb outdoorowy: pogrubione warstwice wysokości \ No newline at end of file diff --git a/android/app/src/fdroid/play/listings/pt-BR/release-notes.txt b/android/app/src/fdroid/play/listings/pt-BR/release-notes.txt index 5a2007378..d9ed20642 100644 --- a/android/app/src/fdroid/play/listings/pt-BR/release-notes.txt +++ b/android/app/src/fdroid/play/listings/pt-BR/release-notes.txt @@ -1,9 +1,7 @@ -Apresentamos o logo do CoMaps! -• Curvas de nível mais detalhadas em muitas regiões -• Adicionados links de imagens do Panoramax para pontos de interesse selecionados -• Dados OSM de 13/07 -• Adicionados preenchimentos de cor a muitos elementos -• Exibição de horário de funcionamento ao selecionar um ponto de interesse -• Divididas áreas úmidas em vários tipos distintos -• Atualizada cores/ícones para vegetação e outros elementos -• Ar livre: curvas de nível de altitude mais destacadas \ No newline at end of file +• Dados OSM de 4/08 +• Melhoria nas cores para água, florestas, matagais, serviços, áreas de pedestres, etc. +• Adição de guarda-florestais, estacionamentos cobertos para bicicletas, jogos de fuga, armários para bagagem e parceiros postais +• Melhoria na precisão de curvas de nível para 20 m em algumas regiões populares +• Suporte a mais abreviações para busca +• Adição de ícones de pesquisa e favoritos para fast food, bicicletas e estações de recarga +• Movimentos mais suaves para seta de posição diff --git a/android/app/src/fdroid/play/listings/pt-BR/title.txt b/android/app/src/fdroid/play/listings/pt-BR/title.txt index 1600419ea..b472b9ea1 100644 --- a/android/app/src/fdroid/play/listings/pt-BR/title.txt +++ b/android/app/src/fdroid/play/listings/pt-BR/title.txt @@ -1 +1 @@ -CoMaps - Mapas com Privacidade +CoMaps - Mapas e Navegação Offline com Privacidade diff --git a/android/app/src/fdroid/play/listings/pt-PT/short-description.txt b/android/app/src/fdroid/play/listings/pt-PT/short-description.txt new file mode 100644 index 000000000..fb5a97658 --- /dev/null +++ b/android/app/src/fdroid/play/listings/pt-PT/short-description.txt @@ -0,0 +1 @@ +Navegação fácil nos mapas - Descubra mais sobre o seu percurso - Feito por todos diff --git a/android/app/src/fdroid/play/listings/pt-PT/title.txt b/android/app/src/fdroid/play/listings/pt-PT/title.txt new file mode 100644 index 000000000..e7d14d499 --- /dev/null +++ b/android/app/src/fdroid/play/listings/pt-PT/title.txt @@ -0,0 +1 @@ +CoMaps - Mapas e Navegação - Offline e Privada diff --git a/android/app/src/fdroid/play/listings/ru-RU/release-notes.txt b/android/app/src/fdroid/play/listings/ru-RU/release-notes.txt index 7711dd695..75b7bbda7 100644 --- a/android/app/src/fdroid/play/listings/ru-RU/release-notes.txt +++ b/android/app/src/fdroid/play/listings/ru-RU/release-notes.txt @@ -1,9 +1,7 @@ -Представляем логотип CoMaps! -• Линии высот для многих регионов с шагом 20м или 50м -• Ссылки на изображения Panoramax к выбранным POI -• Карты OpenStreetMap от 13 июля -• Заливки цветом ко многим объектам и более ранняя заливка для существующих объектов -• Показ часов работы при выборе POI -• Разные водно-болотные угодья отличаются цветом -• Обновлены цвета растительности и другие цвета на карте, изменены некоторые иконки -• В стиле "Активный отдых" более четкие линии высот \ No newline at end of file +• Карты OpenStreetMap от 4 августа +• Улучшен цвет воды, леса, кустарников, различных объектов инфраструктуры, пешеходных зон и т.д. +• Добавлены лесничества, крытые велопарковки, квесты, камеры хранения +• Для некоторых популярных туристических регионов добавлены линии высот 20м +• Поддержка дополнительных поисковых сокращений и синонимов +• Добавлены иконки меток и результатов поиска для фастфуда, велопарковок и зарядных станций +• Более плавное движение стрелки местоположения diff --git a/android/app/src/fdroid/play/listings/sr/release-notes.txt b/android/app/src/fdroid/play/listings/sr/release-notes.txt index 1882318fe..1ff7167c5 100644 --- a/android/app/src/fdroid/play/listings/sr/release-notes.txt +++ b/android/app/src/fdroid/play/listings/sr/release-notes.txt @@ -1,9 +1,7 @@ -Представљамо CoMaps лого! -• ажуриране изохипсе за многе регионе на кораке од 20 или 50 метара -• додате везе ка Panoramax сликама за изабране тачке интересовања (POI) -• подаци са OpenStreetMap-а од 13. јула -• додате боје за многе елементе и раније приказивање постојећих површина -• приказ стања радног времена при избору POI-ја -• мочваре подељене на неколико различитих типова -• ажуриране боје вегетације и других елемената на мапи, ажуриране поједине иконе -• на отвореном: наглашеније изохипсе \ No newline at end of file +• подаци из OpenStreetMap-а од 4. августа +• побољшане боје на мапи за воду, шуме, жбуње, разне објекте, пешачке зоне итд. +• додате станице ренџера, наткривена паркинг места за бицикле, escape room-ови, ормарићи за пртљаг +• унапређене изохипсе на кораке од 20 м за популарне планинарске регионе +• подршка за више скраћеница и алтернативних назива у претрази +• додате иконе за претрагу и обележавање за брзу храну, бицикле и станице за пуњење +• равномерније кретање стрелице која приказује позицију \ No newline at end of file diff --git a/android/app/src/google/java/app/organicmaps/location/GoogleFusedLocationProvider.java b/android/app/src/google/java/app/organicmaps/location/GoogleFusedLocationProvider.java deleted file mode 100644 index f33db2a8d..000000000 --- a/android/app/src/google/java/app/organicmaps/location/GoogleFusedLocationProvider.java +++ /dev/null @@ -1,148 +0,0 @@ -package app.organicmaps.location; - -import static android.Manifest.permission.ACCESS_COARSE_LOCATION; -import static android.Manifest.permission.ACCESS_FINE_LOCATION; -import static app.organicmaps.util.concurrency.UiThread.runLater; - -import android.app.PendingIntent; -import android.content.Context; -import android.location.Location; -import android.os.Looper; - -import androidx.annotation.NonNull; -import androidx.annotation.RequiresPermission; - -import com.google.android.gms.common.api.ApiException; -import com.google.android.gms.common.api.ResolvableApiException; -import com.google.android.gms.location.FusedLocationProviderClient; -import com.google.android.gms.location.Granularity; -import com.google.android.gms.location.LocationAvailability; -import com.google.android.gms.location.LocationCallback; -import com.google.android.gms.location.LocationRequest; -import com.google.android.gms.location.LocationResult; -import com.google.android.gms.location.LocationServices; -import com.google.android.gms.location.LocationSettingsRequest; -import com.google.android.gms.location.LocationSettingsStatusCodes; -import com.google.android.gms.location.Priority; -import com.google.android.gms.location.SettingsClient; - -import app.organicmaps.util.LocationUtils; -import app.organicmaps.util.log.Logger; - -class GoogleFusedLocationProvider extends BaseLocationProvider -{ - private static final String TAG = GoogleFusedLocationProvider.class.getSimpleName(); - @NonNull - private final FusedLocationProviderClient mFusedLocationClient; - @NonNull - private final SettingsClient mSettingsClient; - @NonNull - private final Context mContext; - - private class GoogleLocationCallback extends LocationCallback - { - @Override - public void onLocationResult(@NonNull LocationResult result) - { - final Location location = result.getLastLocation(); - if (location != null) - mListener.onLocationChanged(location); - } - - @Override - public void onLocationAvailability(@NonNull LocationAvailability availability) - { - Logger.w(TAG, "isLocationAvailable = " + availability.isLocationAvailable()); - } - } - - private final GoogleLocationCallback mCallback = new GoogleLocationCallback(); - - GoogleFusedLocationProvider(@NonNull Context context, @NonNull BaseLocationProvider.Listener listener) - { - super(listener); - mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context); - mSettingsClient = LocationServices.getSettingsClient(context); - mContext = context; - } - - @Override - @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) - public void start(long interval) - { - Logger.d(TAG); - - final LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, interval) - // Wait a few seconds for accurate locations initially, when accurate locations could not be computed on the device immediately. - // https://github.com/organicmaps/organicmaps/issues/2149 - .setWaitForAccurateLocation(true) - // The desired location granularity should correspond to the client permission level. The client will be - // delivered fine locations while it has the Manifest.permission.ACCESS_FINE_LOCATION permission, coarse - // locations while it has only the Manifest.permission.ACCESS_COARSE_LOCATION permission, and no location - // if it lacks either. - .setGranularity(Granularity.GRANULARITY_PERMISSION_LEVEL) - // Sets the maximum age of an initial historical location delivered for this request. - .setMaxUpdateAgeMillis(60 * 60 * 1000L) // 1 hour - .build(); - - LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); - builder.addLocationRequest(locationRequest); - builder.setAlwaysShow(true); // improves the wording/appearance of the dialog - final LocationSettingsRequest locationSettingsRequest = builder.build(); - - mSettingsClient.checkLocationSettings(locationSettingsRequest).addOnSuccessListener(locationSettingsResponse -> { - Logger.d(TAG, "Service is available"); - mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper()); - }).addOnFailureListener(e -> { - try - { - int statusCode = ((ApiException) e).getStatusCode(); - if (statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) - { - // This case happens if at least one of the following system settings is off: - // 1. Location Services a.k.a GPS; - // 2. Google Location Accuracy a.k.a High Accuracy; - // 3. Both Wi-Fi && Mobile Data together (needed for 2). - // - // PendingIntent below will show a special Google "For better experience... enable (1) and/or (2) and/or (3)" - // dialog. This system dialog can change system settings if "Yes" is pressed. We can't do it from our app. - // However, we don't want to annoy a user who disabled (2) or (3) intentionally. GPS (1) is mandatory to - // continue, while (2) and (3) are not dealbreakers here. - // - // See https://github.com/organicmaps/organicmaps/issues/3846 - // - if (LocationUtils.areLocationServicesTurnedOn(mContext)) - { - Logger.d(TAG, "Don't show 'location resolution' dialog because location services are already on"); - mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper()); - return; - } - Logger.d(TAG, "Requesting 'location resolution' dialog"); - final ResolvableApiException resolvable = (ResolvableApiException) e; - final PendingIntent pendingIntent = resolvable.getResolution(); - // Call this callback in the next event loop to allow LocationHelper::start() to finish. - runLater(() -> mListener.onLocationResolutionRequired(pendingIntent)); - return; - } - } - catch (ClassCastException ex) - { - // Ignore, should be an impossible error. - // https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient - Logger.e(TAG, "An error that should be impossible: " + ex); - } - // Location settings are not satisfied. However, we have no way to fix the - // settings so we won't show the dialog. - Logger.e(TAG, "Service is not available: " + e); - // Call this callback in the next event loop to allow LocationHelper::start() to finish. - runLater(mListener::onFusedLocationUnsupported); - }); - } - - @Override - protected void stop() - { - Logger.d(TAG); - mFusedLocationClient.removeLocationUpdates(mCallback); - } -} diff --git a/android/app/src/google/java/app/organicmaps/sdk/location/GoogleFusedLocationProvider.java b/android/app/src/google/java/app/organicmaps/sdk/location/GoogleFusedLocationProvider.java new file mode 100644 index 000000000..22182ceb8 --- /dev/null +++ b/android/app/src/google/java/app/organicmaps/sdk/location/GoogleFusedLocationProvider.java @@ -0,0 +1,149 @@ +package app.organicmaps.sdk.location; + +import static android.Manifest.permission.ACCESS_COARSE_LOCATION; +import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static app.organicmaps.sdk.util.concurrency.UiThread.runLater; + +import android.app.PendingIntent; +import android.content.Context; +import android.location.Location; +import android.os.Looper; +import androidx.annotation.NonNull; +import androidx.annotation.RequiresPermission; +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.log.Logger; +import com.google.android.gms.common.api.ApiException; +import com.google.android.gms.common.api.ResolvableApiException; +import com.google.android.gms.location.FusedLocationProviderClient; +import com.google.android.gms.location.Granularity; +import com.google.android.gms.location.LocationAvailability; +import com.google.android.gms.location.LocationCallback; +import com.google.android.gms.location.LocationRequest; +import com.google.android.gms.location.LocationResult; +import com.google.android.gms.location.LocationServices; +import com.google.android.gms.location.LocationSettingsRequest; +import com.google.android.gms.location.LocationSettingsStatusCodes; +import com.google.android.gms.location.Priority; +import com.google.android.gms.location.SettingsClient; + +class GoogleFusedLocationProvider extends BaseLocationProvider +{ + private static final String TAG = GoogleFusedLocationProvider.class.getSimpleName(); + @NonNull + private final FusedLocationProviderClient mFusedLocationClient; + @NonNull + private final SettingsClient mSettingsClient; + @NonNull + private final Context mContext; + + private class GoogleLocationCallback extends LocationCallback + { + @Override + public void onLocationResult(@NonNull LocationResult result) + { + final Location location = result.getLastLocation(); + if (location != null) + mListener.onLocationChanged(location); + } + + @Override + public void onLocationAvailability(@NonNull LocationAvailability availability) + { + Logger.w(TAG, "isLocationAvailable = " + availability.isLocationAvailable()); + } + } + + private final GoogleLocationCallback mCallback = new GoogleLocationCallback(); + + GoogleFusedLocationProvider(@NonNull Context context, @NonNull BaseLocationProvider.Listener listener) + { + super(listener); + mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context); + mSettingsClient = LocationServices.getSettingsClient(context); + mContext = context; + } + + @Override + @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) + public void start(long interval) + { + Logger.d(TAG); + + final LocationRequest locationRequest = + new LocationRequest + .Builder(Priority.PRIORITY_HIGH_ACCURACY, interval) + // Wait a few seconds for accurate locations initially, when accurate locations could not be computed on the + // device immediately. https://github.com/organicmaps/organicmaps/issues/2149 + .setWaitForAccurateLocation(true) + // The desired location granularity should correspond to the client permission level. The client will be + // delivered fine locations while it has the Manifest.permission.ACCESS_FINE_LOCATION permission, coarse + // locations while it has only the Manifest.permission.ACCESS_COARSE_LOCATION permission, and no location + // if it lacks either. + .setGranularity(Granularity.GRANULARITY_PERMISSION_LEVEL) + // Sets the maximum age of an initial historical location delivered for this request. + .setMaxUpdateAgeMillis(60 * 60 * 1000L) // 1 hour + .build(); + + LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); + builder.addLocationRequest(locationRequest); + builder.setAlwaysShow(true); // improves the wording/appearance of the dialog + final LocationSettingsRequest locationSettingsRequest = builder.build(); + + mSettingsClient.checkLocationSettings(locationSettingsRequest) + .addOnSuccessListener(locationSettingsResponse -> { + Logger.d(TAG, "Service is available"); + mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper()); + }) + .addOnFailureListener(e -> { + try + { + int statusCode = ((ApiException) e).getStatusCode(); + if (statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) + { + // This case happens if at least one of the following system settings is off: + // 1. Location Services a.k.a GPS; + // 2. Google Location Accuracy a.k.a High Accuracy; + // 3. Both Wi-Fi && Mobile Data together (needed for 2). + // + // PendingIntent below will show a special Google "For better experience... enable (1) and/or (2) and/or + // (3)" dialog. This system dialog can change system settings if "Yes" is pressed. We can't do it from our + // app. However, we don't want to annoy a user who disabled (2) or (3) intentionally. GPS (1) is mandatory + // to continue, while (2) and (3) are not dealbreakers here. + // + // See https://github.com/organicmaps/organicmaps/issues/3846 + // + if (LocationUtils.areLocationServicesTurnedOn(mContext)) + { + Logger.d(TAG, "Don't show 'location resolution' dialog because location services are already on"); + mFusedLocationClient.requestLocationUpdates(locationRequest, mCallback, Looper.myLooper()); + return; + } + Logger.d(TAG, "Requesting 'location resolution' dialog"); + final ResolvableApiException resolvable = (ResolvableApiException) e; + final PendingIntent pendingIntent = resolvable.getResolution(); + // Call this callback in the next event loop to allow LocationHelper::start() to finish. + runLater(() -> mListener.onLocationResolutionRequired(pendingIntent)); + return; + } + } + catch (ClassCastException ex) + { + // Ignore, should be an impossible error. + // https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient + Logger.e(TAG, "An error that should be impossible: " + ex); + } + // Location settings are not satisfied. However, we have no way to fix the + // settings so we won't show the dialog. + Logger.e(TAG, "Service is not available: " + e); + // Call this callback in the next event loop to allow LocationHelper::start() to finish. + runLater(mListener::onFusedLocationUnsupported); + }); + } + + @Override + protected void stop() + { + Logger.d(TAG); + mFusedLocationClient.removeLocationUpdates(mCallback); + } +} diff --git a/android/app/src/google/java/app/organicmaps/location/LocationProviderFactory.java b/android/app/src/google/java/app/organicmaps/sdk/location/LocationProviderFactory.java similarity index 79% rename from android/app/src/google/java/app/organicmaps/location/LocationProviderFactory.java rename to android/app/src/google/java/app/organicmaps/sdk/location/LocationProviderFactory.java index 5b802eb03..eea7c1207 100644 --- a/android/app/src/google/java/app/organicmaps/location/LocationProviderFactory.java +++ b/android/app/src/google/java/app/organicmaps/sdk/location/LocationProviderFactory.java @@ -1,12 +1,11 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; import android.content.Context; - import androidx.annotation.NonNull; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.log.Logger; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; -import app.organicmaps.util.Config; -import app.organicmaps.util.log.Logger; public class LocationProviderFactory { @@ -17,7 +16,8 @@ public class LocationProviderFactory return GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS; } - public static BaseLocationProvider getProvider(@NonNull Context context, @NonNull BaseLocationProvider.Listener listener) + public static BaseLocationProvider getProvider(@NonNull Context context, + @NonNull BaseLocationProvider.Listener listener) { if (isGoogleLocationAvailable(context) && Config.useGoogleServices()) { diff --git a/android/app/src/google/play/listings/bn/short-description.txt b/android/app/src/google/play/listings/bn/short-description.txt new file mode 100644 index 000000000..aac6a2300 --- /dev/null +++ b/android/app/src/google/play/listings/bn/short-description.txt @@ -0,0 +1 @@ +সহজ মানচিত্র নেভিগেশন - আপনার যাত্রা সম্পর্কে আরও জানুন - সম্প্রদায় কর্তৃক পরিচালিত diff --git a/android/app/src/google/play/listings/bn/title.txt b/android/app/src/google/play/listings/bn/title.txt new file mode 100644 index 000000000..17ed9d481 --- /dev/null +++ b/android/app/src/google/play/listings/bn/title.txt @@ -0,0 +1 @@ +CoMaps - গোপনীয়তা সহ যাতায়াত diff --git a/android/app/src/google/play/listings/ca/full-description.txt b/android/app/src/google/play/listings/ca/full-description.txt new file mode 100644 index 000000000..23853e37d --- /dev/null +++ b/android/app/src/google/play/listings/ca/full-description.txt @@ -0,0 +1,36 @@ +CoMaps és una aplicació de mapes lliure i de codi obert a càrrec de la comunitat que es basa en les dades OpenStreetMap i es fonamenta en el compromís amb la transparència i la privadesa sense ànim de lucre. + +Uneix-te a la comunitat i ajuda a crear la millor aplicació de mapes. +• Fes servir l'aplicació i recomana-la. +• Dona la teva opinió i comunica qualsevol problema. +• Actualitza les dades de mapes a l'aplicació o al web d'OpenStreetMap. + +Els teus comentaris i les valoracions de 5 estrelles són el que més ens ajuda. + +‣ Disseny senzill i polit: funcions bàsiques i fàcils de fer servir que funcionen i punt. +‣ Centrada en l'ús sense connexió: planifica viatges a l'estranger i navega sense haver d'accedir a les dades mòbils o cerca punts d'interès durant rutes d'excursionisme llargues. Totes les funcions de l'aplicació s'han dissenyat perquè funcionin sense connexió. +‣ Respecte per la privadesa: el disseny de l'aplicació prioritza la privadesa. No t'identifica, no fa cap seguiment i no recull dades personals. A més, no té anuncis. +‣ Ús eficient de la bateria i l'espai: consumeix menys bateria que altres aplicacions de navegació. Els mapes compactes ocupen molt poc espai al telèfon. +‣ Lliure gràcies a la comunitat: aquesta aplicació s'ha desenvolupat gràcies a persones com tu que han afegit llocs a OpenStreetMap, han provat funcions, n'han aportat comentaris i hi han contribuït amb diners i esforç. +‣ És un projecte obert i transparent en les seves decisions i finances. No té cap ànim de lucre i és completament de codi obert. + +Funcions principals: +• Mapes detallats que es poden baixar i inclouen llocs que no apareixen a Google Maps +• Mode exterior en què es ressalten les rutes d'excursionisme, els llocs d'acampada, les fonts d'aigua, els pics i les línies de contorn, entre altres coses +• Zones per a vianants i carrils bici +• Punts d'interès, com ara restaurants, benzineres, hotels, botigues, atraccions turístiques i molt més +• Cerques per nom, adreça o categoria de punt d'interès +• Navegació amb indicacions per veu mentre camines, vas amb bicicleta o condueixes +• Adreces d'interès perquè desis els teus llocs preferits amb un toc +• Articles de Wikipedia sense connexió +• Capa de línies de metro amb direccions +• Enregistrament d'itineraris +• Exportació i importació d'adreces d'interès i itineraris en els formats KML, KMZ i GPX +• Mode fosc per fer servir l'aplicació a la nit +• Millora de les dades de mapes per a tothom amb un editor integrat bàsic +• Compatibilitat amb Android Auto + +Pots informar de problemes a l'aplicació, suggerir idees i unir-te a la comunitat al web comaps.app. + +La llibertat ha arribat +Descobreix el teu camí i explora el món amb la privadesa i la comunitat com a eix central! diff --git a/android/app/src/google/play/listings/ca/short-description.txt b/android/app/src/google/play/listings/ca/short-description.txt new file mode 100644 index 000000000..9f18db629 --- /dev/null +++ b/android/app/src/google/play/listings/ca/short-description.txt @@ -0,0 +1 @@ +Navegació intuïtiva - Descobreix el teu camí - El poder de la comunitat diff --git a/android/app/src/google/play/listings/ca/title.txt b/android/app/src/google/play/listings/ca/title.txt new file mode 100644 index 000000000..aae972518 --- /dev/null +++ b/android/app/src/google/play/listings/ca/title.txt @@ -0,0 +1 @@ +CoMaps – Navega amb privadesa diff --git a/android/app/src/google/play/listings/da-DK/full-description.txt b/android/app/src/google/play/listings/da-DK/full-description.txt new file mode 100644 index 000000000..3cf4ebed5 --- /dev/null +++ b/android/app/src/google/play/listings/da-DK/full-description.txt @@ -0,0 +1,36 @@ +En fællesskabsdrevet gratis og open source-kortapp baseret på OpenStreetMap-data og forstærket med en forpligtelse til gennemsigtighed, privatliv og non-profit. + +Bliv en del af fællesskabet og vær med til at skabe den bedste kortapp +• Brug appen og fortæl andre om den +• Giv feedback og rapporter problemer +• Opdater kortdata i appen eller på OpenStreetMap-webstedet + +Din feedback og 5-stjernede anmeldelser er den bedste støtte for os! + +‣ Enkel og poleret: væsentlige, brugervenlige funktioner, der bare virker. +‣ Offline-focused: Planlæg og naviger på din rejse i udlandet uden behov for mobilfordbindelse, søg efter rutepunkter, mens du er på en lang vandretur osv. Alle app-funktioner er designet til at fungere offline.. +‣ Respekt for privatlivets fred: Appen er designet med fokus på privatlivets fred – den identificerer ikke personer, sporer ikke og indsamler ikke personlige oplysninger. Annoncefri. +‣ Sparer på batteriet og plads: Dræner ikke dit batteri som andre navigationsapps. Kompakte kort sparer værdifuld plads på din telefon. +‣ Gratis og udviklet af fællesskabet: Folk som dig har været med til at udvikle appen ved at tilføje steder til OpenStreetMap, teste og give feedback på funktioner samt bidrage med deres udviklingskompetencer og penge. +‣ Åben og gennemsigtig beslutningstagning og økonomi, non-profit og fuldstændig open source. + +Vigtigste funktioner: +• Detaljerede kort med steder, der ikke er tilgængelige på Google Maps, kan downloades. +• Udendørstilstand med fremhævede vandreruter, campingpladser, vandkilder, bjergtoppe, højdekurver osv. +• Gang- og cykelstier +• Interessepunkter som restauranter, tankstationer, hoteller, butikker, seværdigheder og meget mere +• Søg efter navn, adresse eller efter interessepunkt-kategori +• Navigation med stemmevejledning til gående, cyklende eller kørende +• Bogmærk dine yndlingssteder med ét enkelt tryk +• Offline Wikipedia-artikler +• Lag med metrolinjer og rutevejledning +• Sporoptagelse +• Eksportér og importér bogmærker og ruter i KML, KMZ, GPX-formater +• En mørk tilstand til brug om natten +• Forbedr kortdata for alle ved hjælp af en simpel, indbygget redigeringsfunktion +• Android Auto-understøttelse + +Rapportér app-problemer, kom med forslag og bliv en del af vores fællesskab på comaps.app webstedet. + +Nu med frihed +Udforsk din rejse, og navigér i verden med fokus på privatliv og fællesskab! diff --git a/android/app/src/google/play/listings/da-DK/title.txt b/android/app/src/google/play/listings/da-DK/title.txt new file mode 100644 index 000000000..8995258ba --- /dev/null +++ b/android/app/src/google/play/listings/da-DK/title.txt @@ -0,0 +1 @@ +CoMaps - Naviger med privatliv diff --git a/android/app/src/google/play/listings/es-ES/full-description.txt b/android/app/src/google/play/listings/es-ES/full-description.txt new file mode 100644 index 000000000..c7a53a4c1 --- /dev/null +++ b/android/app/src/google/play/listings/es-ES/full-description.txt @@ -0,0 +1,71 @@ +Una aplicación de mapas gratuita y de código abierto liderada por la comunidad, basada en los datos de OpenStreetMap y reforzada con un compromiso con la transparencia, la privacidad y la ausencia de fines de lucro. + +

+ +Únete a la comunidad y ayuda a crear la mejor app de mapas + +• Usa la aplicación y corre la voz sobre ella + +• Envía comentarios y reporta problemas + +• Actualiza los datos del mapa en la app o en el sitio web de OpenStreetMap + +

+ +¡Tus comentarios y valoraciones de 5 estrellas son el mejor apoyo para nosotros! + +

+ +‣ Sencilla y Pulida: funciones esenciales fáciles de usar que simplemente funcionan. + +‣ Enfocada en el uso sin conexión: Planifica y navega tus viajes sin necesidad de conexión móvil, busca puntos de paso en rutas remotas, etc. Todas las funciones están diseñadas para funcionar sin conexión. + +‣ Respeta tu Privacidad: La app está diseñada pensando en tu privacidad: no identifica personas, no rastrea y no recoge datos personales. Sin publicidad. + +‣ Ahorra Batería y Espacio: No consume la batería como otras apps de navegación. Los mapas compactos ahorran espacio valioso en tu teléfono. + +‣ Gratuita y Creada por la Comunidad: Personas como tú ayudaron a construir la app añadiendo lugares a OpenStreetMap, probando funciones, dando opiniones y contribuyendo con desarrollo o financiación. + +‣ Toma de decisiones y finanzas abiertas y transparentes, sin ánimo de lucro y completamente de código abierto. + +

+ +Funciones Principales: + +• Mapas detallados descargables con lugares que no aparecen en Google Maps + +• Modo exterior con rutas de senderismo destacadas, campings, fuentes de agua, picos, curvas de nivel, etc. + +• Caminos peatonales y carriles bici + +• Puntos de interés como restaurantes, gasolineras, hoteles, tiendas, lugares turísticos y muchos más + +• Búsqueda por nombre, dirección o categoría de punto de interés + +• Navegación con indicaciones por voz para caminar, ir en bici o conducir + +• Guarda tus lugares favoritos con un solo toque + +• Artículos de Wikipedia sin conexión + +• Capa de transporte subterráneo y rutas + +• Grabación de rutas + +• Exporta e importa favoritos y rutas en formatos KML, KMZ y GPX + +• Modo oscuro para usar de noche + +• Mejora los datos del mapa para todos usando un editor básico integrado + +• Compatibilidad con Android Auto + +

+ +Por favor, informa de errores, sugiere ideas y únete a nuestra comunidad en el sitio web comaps.app. + +

+ +La Libertad Está Aquí + +Descubre tu camino, navega el mundo con privacidad y con la comunidad como prioridad. diff --git a/android/app/src/google/play/listings/es-ES/short-description.txt b/android/app/src/google/play/listings/es-ES/short-description.txt new file mode 100644 index 000000000..f45617084 --- /dev/null +++ b/android/app/src/google/play/listings/es-ES/short-description.txt @@ -0,0 +1 @@ +Navegación de mapa fácil - Descubre más en tu camino - Creado por la comunidad diff --git a/android/app/src/google/play/listings/es-ES/title.txt b/android/app/src/google/play/listings/es-ES/title.txt new file mode 100644 index 000000000..2f4185c16 --- /dev/null +++ b/android/app/src/google/play/listings/es-ES/title.txt @@ -0,0 +1 @@ +CoMaps - Navega con Privacidad diff --git a/android/app/src/google/play/listings/eu-ES/full-description.txt b/android/app/src/google/play/listings/eu-ES/full-description.txt new file mode 100644 index 000000000..caf95caa8 --- /dev/null +++ b/android/app/src/google/play/listings/eu-ES/full-description.txt @@ -0,0 +1,35 @@ +Komunitateak gidatutako doako eta kode irekiko aplikazioa OpenStreetMap datuetan oinarrituta, gardentasuna, pribatutasuna eta irabazi asmorik gabeko konpromisoarekin indartua. + +Sartu komunitatean eta lagundu mapa aplikaziorik onena egiten +• Erabili aplikazioa eta horri buruzko iritsia zabaldu +• Eman feedbacka eta txostenetako gaiak +• Eguneratu maparen datuak aplikazioan edo OpenStreetMap webgunean + Zure iritzia eta 5 izarreko berrikuspenak dira guretzako laguntza onena! + +‣ Sinplea: oso erraza da ondo funtzionatzen duten funtzioak erabiltzea. +‣ Lineaz kanpo erabiltzeko prest Planifikatu eta nabigatu atzerrira bidaiatzea, konexio beharrik gabe, bilatu bideak urruneko ibilaldi batean, etab. Aplikazioaren funtzio guztiak lineaz kanpo lan egiteko diseinatuta daude. +‣ Pribatutasuna errespetatzea : aplikazioa pribatutasunarekin diseinatuta dago, ez du pertsonak identifikatzen, ez du jarraipena egiten, eta ez du informazio pertsonala biltzen. Iragarkirik gabe. +‣ Zure bateria eta espazioa gordetzen ditu : ez du bateria xukatu beste nabigazio aplikazioak bezala. Mapa trinkoek espazioa aurrezten dute zure telefonoan. +‣ Libre eta komunitateak eraikitakoa: Zu bezalako jendeak aplikazioa eraikitzen lagundu du tokiak gehituz OpenStreetMapen, probatuz eta funtzioei buruzko iritzia emanez eta iritsiz eta diruz lagunduz. +‣ Erabakiak hartzea eta finantza gardenak, irabazi asmorik gabekoa eta guztiz iturburu irekikoa. + + Ezaugarri nagusiak : +• Deskargatu mapa zehatzak Google Maps-ekin eskuragarri ez dauden lekuekin +• Landa eremua moduan nabarmendutako mendi ibilbideak, kanpinak, ur iturriak, gailurrak, sestra-lerroak, etab +• Bideak eta bidegorriak +• Jatetxe, gasolindegiak, hotelak, dendak, bisitak eta bestelako interesguneak +• Bilatu izenaren edo helbide baten arabera, edo kategoriaren arabera +• Oinez, txirrindularitzarako edo gidatzeko ahots-oharrak dituen nabigazioa +• Markatu zure gogoko lekuak ikutu bakarrarekin +• Lineaz kanpoko Wikipedia artikuluak +• Metroaren garraio geruza eta jarraibideak +• Arrastoen grabazioa +• Laster-markak eta ibilbideak esportatu eta inportatu KML, KMZ, GPX formatuetan +• Gauean erabiltzeko modu iluna +• Hobetu mapako datuak oinarrizko editore integratua erabiliz +• Android Auto laguntza + +Mesedez, jakinarazi aplikazioaren gorabeherak, ideiak proposatu eta sartu gure komunitatean comaps.app webgunean. + + Askatasuna hemen da +Ezagutu zure bidaia, nabigatu munduan pribatutasunarekin eta komunitatearen abangoardian! diff --git a/android/app/src/google/play/listings/eu-ES/title.txt b/android/app/src/google/play/listings/eu-ES/title.txt new file mode 100644 index 000000000..0bb3e8703 --- /dev/null +++ b/android/app/src/google/play/listings/eu-ES/title.txt @@ -0,0 +1 @@ +Comaps - Pribatuki nabigatu diff --git a/android/app/src/google/play/listings/fr-FR/short-description.txt b/android/app/src/google/play/listings/fr-FR/short-description.txt index 9b00be32b..1acd0ceac 100644 --- a/android/app/src/google/play/listings/fr-FR/short-description.txt +++ b/android/app/src/google/play/listings/fr-FR/short-description.txt @@ -1 +1 @@ -Navigation cartographique facile - Propulsé par la communauté +Navigation cartographique facile - Vivez de grands voyages - Propulsé par la communauté diff --git a/android/app/src/google/play/listings/hu-HU/short-description.txt b/android/app/src/google/play/listings/hu-HU/short-description.txt new file mode 100644 index 000000000..e818f3e16 --- /dev/null +++ b/android/app/src/google/play/listings/hu-HU/short-description.txt @@ -0,0 +1 @@ +Könnyű térképes navigáció - Fedezz fel többet az útjaidról - A közösség erejével diff --git a/android/app/src/google/play/listings/hu-HU/title.txt b/android/app/src/google/play/listings/hu-HU/title.txt new file mode 100644 index 000000000..b382a2159 --- /dev/null +++ b/android/app/src/google/play/listings/hu-HU/title.txt @@ -0,0 +1 @@ +CoMaps - Az adatvédő navigáció diff --git a/android/app/src/google/play/listings/ia/short-description.txt b/android/app/src/google/play/listings/ia/short-description.txt new file mode 100644 index 000000000..df5517d58 --- /dev/null +++ b/android/app/src/google/play/listings/ia/short-description.txt @@ -0,0 +1 @@ +Navigation facile del mappa – Discoperi tu viage – Alimentate per le communitate diff --git a/android/app/src/google/play/listings/ia/title.txt b/android/app/src/google/play/listings/ia/title.txt new file mode 100644 index 000000000..3d7c0ec50 --- /dev/null +++ b/android/app/src/google/play/listings/ia/title.txt @@ -0,0 +1 @@ +CoMaps – Naviga private diff --git a/android/app/src/google/play/listings/ml-IN/title.txt b/android/app/src/google/play/listings/ml-IN/title.txt new file mode 100644 index 000000000..970488d93 --- /dev/null +++ b/android/app/src/google/play/listings/ml-IN/title.txt @@ -0,0 +1 @@ +കോമാപ്പ്സ് - സ്വകാര്യതയോടെ സഞ്ചരിക്കൂ diff --git a/android/app/src/google/play/listings/pl-PL/title.txt b/android/app/src/google/play/listings/pl-PL/title.txt new file mode 100644 index 000000000..62c8f3993 --- /dev/null +++ b/android/app/src/google/play/listings/pl-PL/title.txt @@ -0,0 +1 @@ +CoMaps - Nawigacja szanująca prywatność diff --git a/android/app/src/google/play/listings/pt-BR/title.txt b/android/app/src/google/play/listings/pt-BR/title.txt index d64397c3c..b2f4278f8 100644 --- a/android/app/src/google/play/listings/pt-BR/title.txt +++ b/android/app/src/google/play/listings/pt-BR/title.txt @@ -1 +1 @@ -CoMaps - Navegue privadamente +CoMaps - Navegue Privadamente diff --git a/android/app/src/google/play/listings/ru-RU/title.txt b/android/app/src/google/play/listings/ru-RU/title.txt index 152b53f66..dc3323a0f 100644 --- a/android/app/src/google/play/listings/ru-RU/title.txt +++ b/android/app/src/google/play/listings/ru-RU/title.txt @@ -1 +1 @@ -CoMaps - Оффлайн навигация +CoMaps - Приватная навигация diff --git a/android/app/src/google/play/listings/tr-TR/full-description.txt b/android/app/src/google/play/listings/tr-TR/full-description.txt index 37008422e..2e21034a5 100644 --- a/android/app/src/google/play/listings/tr-TR/full-description.txt +++ b/android/app/src/google/play/listings/tr-TR/full-description.txt @@ -7,12 +7,12 @@ Topluluğa katılın ve en iyi harita uygulamasını oluşturmamıza yardım edi Geri bildirimleriniz ve 5 yıldızlı yorumlarınız bizim için en iyi destektir! -‣ Basit ve Temiz: Sadece temel, kullanımı basit, işe yarayan özellikler. -‣ Çevrimdışı Odaklı: Mobil veriye ihtiyaç duymadan yurt dışı seyahatinizi planlayın ve gezin, uzun bir yürüyüş sırasında rotanızdaki noktaları bulun ve daha fazlası . Tüm özellikler çevrimdışı çalışmak üzere tasarlanmıştır. +‣ Basit ve Temiz: Sadece temel, kullanımı basit ve işe yarayan özellikler. +‣ Çevrimdışı Odaklı: Mobil veriye ihtiyaç duymadan yurt dışı seyahatinizi planlayın ve gezin, uzun bir yürüyüş sırasında rotanızdaki noktaları bulun ve daha fazlası. Tüm özellikler çevrimdışı çalışmak üzere tasarlanmıştır. ‣ Gizliliğe Saygılı: Uygulama gizliliğe saygılı olarak tasarlanmıştır. Kullanıcı profilinizi çıkarmaz, sizi takip etmez ve kişisel bilgi toplamaz. Üstelik tamamen reklamsızdır. -‣ Pil ve Depolamanızdan Tasarruf Eder: Diğer navigasyon uygulamaları gibi pilinizi sömürmez. Compact maps değerli depolama alanınızdan tasarruf eder. -‣ Ücretsizdir ve Gücünü Topluluktan Alır: Sizin gibi insanlar OpenStreetMap'e yer ekleyerek, yeni özellikleri test ederek, geri bildirimde bulunarak, program geliştirme becerileri ve bağışlarla katkıda bulunarak uygulamanın oluşturulmasına yardımcı oldu. -‣ Açık ve Şeffaf Şekilde Yürütülen Karar Alma ve Fonlama Süreçleri, Kâr Amacı Gütmez ve Tamamen Açık Kaynaklı. +‣ Pil ve Depolamanızdan Tasarruf Eder: Diğer navigasyon uygulamaları gibi pilinizi sömürmez. Kompakt harita dosyaları, değerli depolama alanınızdan tasarruf eder. +‣ Ücretsizdir ve Gücünü Topluluktan Alır: Sizin gibi insanlar OpenStreetMap'e yer ekleyerek, yeni özellikleri test ederek, geri bildirimde bulunarak, program geliştirme becerileri ve bağışlarla katkıda bulunarak bu uygulamanın oluşturulmasına yardımcı oldular. +‣ Açık ve Şeffaf Bir Şekilde Yürütülen Karar Alma ve Fonlama Süreçlerine Sahip, Kâr Amacı Gütmeyen ve Tamamen Açık Kaynaklı Bir Uygulama. Ana Özellikler: • Google Haritalar'da bulunmayan yerleri içeren, çevrimdışı detaylı haritalar diff --git a/android/app/src/huawei/java/app/organicmaps/location b/android/app/src/huawei/java/app/organicmaps/location deleted file mode 120000 index c3bacf635..000000000 --- a/android/app/src/huawei/java/app/organicmaps/location +++ /dev/null @@ -1 +0,0 @@ -../../../../google/java/app/organicmaps/location \ No newline at end of file diff --git a/android/app/src/huawei/java/app/organicmaps/sdk/location b/android/app/src/huawei/java/app/organicmaps/sdk/location new file mode 120000 index 000000000..f41d2255b --- /dev/null +++ b/android/app/src/huawei/java/app/organicmaps/sdk/location @@ -0,0 +1 @@ +../../../../../google/java/app/organicmaps/sdk/location \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1ed8d7833..8453ff612 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -90,6 +90,7 @@ android:backupInForeground="true" android:fullBackupContent="@xml/backup_content" android:dataExtractionRules="@xml/backup_content_v31" + android:enableOnBackInvokedCallback="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:localeConfig="@xml/locales_config" @@ -391,6 +392,7 @@ NativeFramework(); - ASSERT(fr, ()); - search::DisplayedCategories categories = fr->GetDisplayedCategories(); - return jni::ToJavaStringArray(env, categories.GetKeys()); -} -} // extern "C" diff --git a/android/app/src/main/cpp/app/organicmaps/settings/MapLanguageCode.cpp b/android/app/src/main/cpp/app/organicmaps/settings/MapLanguageCode.cpp deleted file mode 100644 index 5436f3e96..000000000 --- a/android/app/src/main/cpp/app/organicmaps/settings/MapLanguageCode.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "app/organicmaps/Framework.hpp" - -#include "platform/settings.hpp" - -#include "app/organicmaps/core/jni_helper.hpp" - -extern "C" -{ -JNIEXPORT void JNICALL -Java_app_organicmaps_settings_MapLanguageCode_setMapLanguageCode(JNIEnv * env, jobject, jstring languageCode) -{ - g_framework->SetMapLanguageCode(jni::ToNativeString(env, languageCode)); -} - -JNIEXPORT jstring JNICALL -Java_app_organicmaps_settings_MapLanguageCode_getMapLanguageCode(JNIEnv * env, jobject) -{ - return jni::ToJavaString(env, g_framework->GetMapLanguageCode()); -} -} diff --git a/android/app/src/main/cpp/app/organicmaps/util/UiThread.cpp b/android/app/src/main/cpp/app/organicmaps/util/UiThread.cpp deleted file mode 100644 index bd54eec30..000000000 --- a/android/app/src/main/cpp/app/organicmaps/util/UiThread.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "app/organicmaps/core/jni_helper.hpp" -#include "app/organicmaps/platform/GuiThread.hpp" - -extern "C" -{ -// static void nativeProcessTask(long taskPointer); -JNIEXPORT void JNICALL -Java_app_organicmaps_util_concurrency_UiThread_nativeProcessTask(JNIEnv * env, jclass clazz, jlong taskPointer) -{ - android::GuiThread::ProcessTask(taskPointer); -} -} diff --git a/android/app/src/main/java/app/organicmaps/ChartController.java b/android/app/src/main/java/app/organicmaps/ChartController.java index 89141b7b2..acfbb704f 100644 --- a/android/app/src/main/java/app/organicmaps/ChartController.java +++ b/android/app/src/main/java/app/organicmaps/ChartController.java @@ -5,10 +5,16 @@ import android.content.res.Resources; import android.graphics.Color; import android.view.View; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; - +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.ElevationInfo; +import app.organicmaps.util.ThemeUtils; +import app.organicmaps.util.Utils; +import app.organicmaps.widget.placepage.AxisValueFormatter; +import app.organicmaps.widget.placepage.CurrentLocationMarkerView; +import app.organicmaps.widget.placepage.FloatingMarkerView; import com.github.mikephil.charting.charts.LineChart; import com.github.mikephil.charting.components.Legend; import com.github.mikephil.charting.components.MarkerView; @@ -20,15 +26,6 @@ import com.github.mikephil.charting.data.LineDataSet; import com.github.mikephil.charting.formatter.ValueFormatter; import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.listener.OnChartValueSelectedListener; - -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.ElevationInfo; -import app.organicmaps.widget.placepage.AxisValueFormatter; -import app.organicmaps.widget.placepage.CurrentLocationMarkerView; -import app.organicmaps.widget.placepage.FloatingMarkerView; -import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.Utils; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -150,7 +147,7 @@ public class ChartController implements OnChartValueSelectedListener, mTrackId = info.getId(); List values = new ArrayList<>(); - for (ElevationInfo.Point point: info.getPoints()) + for (ElevationInfo.Point point : info.getPoints()) values.add(new Entry((float) point.getDistance(), point.getAltitude())); LineDataSet set = new LineDataSet(values, "Elevation_profile_points"); @@ -183,15 +180,15 @@ public class ChartController implements OnChartValueSelectedListener, } @Override - public void onValueSelected(Entry e, Highlight h) { + public void onValueSelected(Entry e, Highlight h) + { mFloatingMarkerView.updateOffsets(e, h); Highlight curPos = getCurrentPosHighlight(); if (mCurrentPositionOutOfTrack) mChart.highlightValues(Collections.singletonList(h), Collections.singletonList(mFloatingMarkerView)); else - mChart.highlightValues(Arrays.asList(curPos, h), Arrays.asList(mCurrentLocationMarkerView, - mFloatingMarkerView)); + mChart.highlightValues(Arrays.asList(curPos, h), Arrays.asList(mCurrentLocationMarkerView, mFloatingMarkerView)); if (mTrackId == Utils.INVALID_ID) return; diff --git a/android/app/src/main/java/app/organicmaps/DownloadResourcesLegacyActivity.java b/android/app/src/main/java/app/organicmaps/DownloadResourcesLegacyActivity.java index c7aff32ba..afbb787d5 100644 --- a/android/app/src/main/java/app/organicmaps/DownloadResourcesLegacyActivity.java +++ b/android/app/src/main/java/app/organicmaps/DownloadResourcesLegacyActivity.java @@ -1,5 +1,15 @@ package app.organicmaps; +import static app.organicmaps.sdk.DownloadResourcesLegacyActivity.ERR_DISK_ERROR; +import static app.organicmaps.sdk.DownloadResourcesLegacyActivity.ERR_DOWNLOAD_ERROR; +import static app.organicmaps.sdk.DownloadResourcesLegacyActivity.ERR_DOWNLOAD_SUCCESS; +import static app.organicmaps.sdk.DownloadResourcesLegacyActivity.ERR_NOT_ENOUGH_FREE_SPACE; +import static app.organicmaps.sdk.DownloadResourcesLegacyActivity.ERR_NO_MORE_FILES; +import static app.organicmaps.sdk.DownloadResourcesLegacyActivity.ERR_STORAGE_DISCONNECTED; +import static app.organicmaps.sdk.DownloadResourcesLegacyActivity.nativeCancelCurrentFile; +import static app.organicmaps.sdk.DownloadResourcesLegacyActivity.nativeGetBytesToDownload; +import static app.organicmaps.sdk.DownloadResourcesLegacyActivity.nativeStartNextFileDownload; + import android.annotation.SuppressLint; import android.app.Dialog; import android.content.ComponentName; @@ -8,35 +18,31 @@ import android.location.Location; import android.os.Bundle; import android.text.TextUtils; import android.view.View; - import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.CallSuper; -import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.StyleRes; import androidx.core.view.ViewCompat; import app.organicmaps.base.BaseMwmFragmentActivity; -import app.organicmaps.downloader.CountryItem; -import app.organicmaps.downloader.MapManager; import app.organicmaps.intent.Factory; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.LocationListener; -import app.organicmaps.util.Config; -import app.organicmaps.util.ConnectionState; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.location.LocationListener; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.ConnectionState; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Utils; import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener; - import com.google.android.material.button.MaterialButton; import com.google.android.material.checkbox.MaterialCheckBox; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.progressindicator.LinearProgressIndicator; import com.google.android.material.textview.MaterialTextView; - import java.util.List; import java.util.Objects; @@ -45,15 +51,6 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity { private static final String TAG = DownloadResourcesLegacyActivity.class.getSimpleName(); - // Error codes, should match the same codes in JNI - private static final int ERR_DOWNLOAD_SUCCESS = 0; - private static final int ERR_DISK_ERROR = -1; - private static final int ERR_NOT_ENOUGH_FREE_SPACE = -2; - private static final int ERR_STORAGE_DISCONNECTED = -3; - private static final int ERR_DOWNLOAD_ERROR = -4; - private static final int ERR_NO_MORE_FILES = -5; - private static final int ERR_FILE_IN_PROGRESS = -6; - private MaterialTextView mTvMessage; private LinearProgressIndicator mProgress; private MaterialButton mBtnDownload; @@ -81,23 +78,9 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity private int mCountryDownloadListenerSlot; - private interface Listener - { - // Called by JNI. - @Keep - @SuppressWarnings("unused") - void onProgress(int percent); - - // Called by JNI. - @Keep - @SuppressWarnings("unused") - void onFinish(int errorCode); - } - - private final LocationListener mLocationListener = new LocationListener() - { + private final LocationListener mLocationListener = new LocationListener() { @Override - public void onLocationUpdated(Location location) + public void onLocationUpdated(@NonNull Location location) { if (mCurrentCountry != null) return; @@ -126,38 +109,37 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity mChbDownloadCountry.setText(checkBoxText); } - LocationHelper.from(DownloadResourcesLegacyActivity.this).removeListener(this); + MwmApplication.from(DownloadResourcesLegacyActivity.this).getLocationHelper().removeListener(this); } }; - private final Listener mResourcesDownloadListener = new Listener() - { - @Override - public void onProgress(final int percent) - { - if (!isFinishing()) - mProgress.setProgressCompat(percent, true); - } + private final app.organicmaps.sdk.DownloadResourcesLegacyActivity.Listener mResourcesDownloadListener = + new app.organicmaps.sdk.DownloadResourcesLegacyActivity.Listener() { + @Override + public void onProgress(final int percent) + { + if (!isFinishing()) + mProgress.setProgressCompat(percent, true); + } - @Override - public void onFinish(final int errorCode) - { - if (isFinishing()) - return; + @Override + public void onFinish(final int errorCode) + { + if (isFinishing()) + return; - if (errorCode == ERR_DOWNLOAD_SUCCESS) - { - final int res = nativeStartNextFileDownload(mResourcesDownloadListener); - if (res == ERR_NO_MORE_FILES) - finishFilesDownload(res); - } - else - finishFilesDownload(errorCode); - } - }; + if (errorCode == ERR_DOWNLOAD_SUCCESS) + { + final int res = nativeStartNextFileDownload(mResourcesDownloadListener); + if (res == ERR_NO_MORE_FILES) + finishFilesDownload(res); + } + else + finishFilesDownload(errorCode); + } + }; - private final MapManager.StorageCallback mCountryDownloadListener = new MapManager.StorageCallback() - { + private final MapManager.StorageCallback mCountryDownloadListener = new MapManager.StorageCallback() { @Override public void onStatusChanged(List data) { @@ -168,14 +150,14 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity switch (item.newStatus) { - case CountryItem.STATUS_DONE: - mAreResourcesDownloaded = true; - showMap(); - return; + case CountryItem.STATUS_DONE: + mAreResourcesDownloaded = true; + showMap(); + return; - case CountryItem.STATUS_FAILED: - MapManager.showError(DownloadResourcesLegacyActivity.this, item, null); - return; + case CountryItem.STATUS_FAILED: + MapManager.showError(DownloadResourcesLegacyActivity.this, item, null); + return; } } } @@ -235,14 +217,14 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity { super.onResume(); if (!isFinishing()) - LocationHelper.from(this).addListener(mLocationListener); + MwmApplication.from(this).getLocationHelper().addListener(mLocationListener); } @Override protected void onPause() { super.onPause(); - LocationHelper.from(this).removeListener(mLocationListener); + MwmApplication.from(this).getLocationHelper().removeListener(mLocationListener); if (mAlertDialog != null && mAlertDialog.isShowing()) mAlertDialog.dismiss(); mAlertDialog = null; @@ -250,8 +232,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity private void setDownloadMessage(int bytesToDownload) { - mTvMessage.setText(getString(R.string.download_resources, - StringUtils.getFileSizeString(this, bytesToDownload))); + mTvMessage.setText(getString(R.string.download_resources, StringUtils.getFileSizeString(this, bytesToDownload))); } private boolean prepareFilesDownload(boolean showMap) @@ -388,7 +369,7 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity CountryItem item = CountryItem.fill(mCurrentCountry); String fileSizeString = StringUtils.getFileSizeString(this, item.totalSize); mTvMessage.setText(getString(R.string.downloading_country_can_proceed, item.name, fileSizeString)); - mProgress.setMax((int)item.totalSize); + mProgress.setMax((int) item.totalSize); mProgress.setProgressCompat(0, true); mCountryDownloadListenerSlot = MapManager.nativeSubscribe(mCountryDownloadListener); @@ -412,8 +393,10 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity if (mAlertDialog != null && mAlertDialog.isShowing()) return; - @StringRes final int titleId; - @StringRes final int messageId = switch (result) + @StringRes + final int titleId; + @StringRes + final int messageId = switch (result) { case ERR_NOT_ENOUGH_FREE_SPACE -> { @@ -428,8 +411,8 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity case ERR_DOWNLOAD_ERROR -> { titleId = R.string.connection_failure; - yield (ConnectionState.INSTANCE.isConnected() ? R.string.download_has_failed - : R.string.common_check_internet_connection_dialog); + yield(ConnectionState.INSTANCE.isConnected() ? R.string.download_has_failed + : R.string.common_check_internet_connection_dialog); } case ERR_DISK_ERROR -> { @@ -439,17 +422,18 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity default -> throw new AssertionError("Unexpected result code = " + result); }; - mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(titleId) - .setMessage(messageId) - .setCancelable(true) - .setOnCancelListener((dialog) -> setAction(PAUSE)) - .setPositiveButton(R.string.try_again, (dialog, which) -> { - setAction(TRY_AGAIN); - onTryAgainClicked(); - }) - .setOnDismissListener(dialog -> mAlertDialog = null) - .show(); + mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) + .setTitle(titleId) + .setMessage(messageId) + .setCancelable(true) + .setOnCancelListener((dialog) -> setAction(PAUSE)) + .setPositiveButton(R.string.try_again, + (dialog, which) -> { + setAction(TRY_AGAIN); + onTryAgainClicked(); + }) + .setOnDismissListener(dialog -> mAlertDialog = null) + .show(); } @Override @@ -458,8 +442,4 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity { return R.style.MwmTheme_DownloadResourcesLegacy; } - - private static native int nativeGetBytesToDownload(); - private static native int nativeStartNextFileDownload(Listener listener); - private static native void nativeCancelCurrentFile(); } diff --git a/android/app/src/main/java/app/organicmaps/MapFragment.java b/android/app/src/main/java/app/organicmaps/MapFragment.java index 58f8e9fcc..df0feaae6 100644 --- a/android/app/src/main/java/app/organicmaps/MapFragment.java +++ b/android/app/src/main/java/app/organicmaps/MapFragment.java @@ -10,15 +10,14 @@ import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.res.ConfigurationHelper; - import app.organicmaps.base.BaseMwmFragment; -import app.organicmaps.display.DisplayType; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.Map; +import app.organicmaps.sdk.MapRenderingListener; +import app.organicmaps.sdk.display.DisplayType; +import app.organicmaps.sdk.util.log.Logger; import com.google.android.material.dialog.MaterialAlertDialogBuilder; public class MapFragment extends BaseMwmFragment implements View.OnTouchListener, SurfaceHolder.Callback @@ -69,7 +68,8 @@ public class MapFragment extends BaseMwmFragment implements View.OnTouchListener public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) { Logger.d(TAG); - mMap.onSurfaceChanged(requireContext(), surfaceHolder.getSurface(), surfaceHolder.getSurfaceFrame(), surfaceHolder.isCreating()); + mMap.onSurfaceChanged(requireContext(), surfaceHolder.getSurface(), surfaceHolder.getSurfaceFrame(), + surfaceHolder.isCreating()); } @Override diff --git a/android/app/src/main/java/app/organicmaps/MapPlaceholderActivity.java b/android/app/src/main/java/app/organicmaps/MapPlaceholderActivity.java index 0d0a0db50..bf1651c04 100644 --- a/android/app/src/main/java/app/organicmaps/MapPlaceholderActivity.java +++ b/android/app/src/main/java/app/organicmaps/MapPlaceholderActivity.java @@ -2,14 +2,12 @@ package app.organicmaps; import android.content.Intent; import android.os.Bundle; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.base.BaseMwmFragmentActivity; -import app.organicmaps.display.DisplayChangedListener; -import app.organicmaps.display.DisplayManager; -import app.organicmaps.display.DisplayType; +import app.organicmaps.sdk.display.DisplayChangedListener; +import app.organicmaps.sdk.display.DisplayManager; +import app.organicmaps.sdk.display.DisplayType; public class MapPlaceholderActivity extends BaseMwmFragmentActivity implements DisplayChangedListener { @@ -24,7 +22,7 @@ public class MapPlaceholderActivity extends BaseMwmFragmentActivity implements D super.onSafeCreate(savedInstanceState); setContentView(R.layout.activity_map_placeholder); - mDisplayManager = DisplayManager.from(this); + mDisplayManager = MwmApplication.from(this).getDisplayManager(); mDisplayManager.addListener(DisplayType.Device, this); findViewById(R.id.btn_continue).setOnClickListener((unused) -> mDisplayManager.changeDisplay(DisplayType.Device)); @@ -34,8 +32,7 @@ public class MapPlaceholderActivity extends BaseMwmFragmentActivity implements D public void onDisplayChangedToDevice(@NonNull Runnable onTaskFinishedCallback) { mRemoveDisplayListener = false; - startActivity(new Intent(this, MwmActivity.class) - .putExtra(MwmActivity.EXTRA_UPDATE_THEME, true)); + startActivity(new Intent(this, MwmActivity.class).putExtra(MwmActivity.EXTRA_UPDATE_THEME, true)); finish(); onTaskFinishedCallback.run(); } diff --git a/android/app/src/main/java/app/organicmaps/MwmActivity.java b/android/app/src/main/java/app/organicmaps/MwmActivity.java index 096fbe6fa..47a97b0a7 100644 --- a/android/app/src/main/java/app/organicmaps/MwmActivity.java +++ b/android/app/src/main/java/app/organicmaps/MwmActivity.java @@ -1,5 +1,18 @@ package app.organicmaps; +import static android.Manifest.permission.ACCESS_COARSE_LOCATION; +import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static android.Manifest.permission.POST_NOTIFICATIONS; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_ADD_PLACE_CODE; +import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_HELP_CODE; +import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_RECORD_TRACK_CODE; +import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_SETTINGS_CODE; +import static app.organicmaps.sdk.location.LocationState.FOLLOW; +import static app.organicmaps.sdk.location.LocationState.FOLLOW_AND_ROTATE; +import static app.organicmaps.sdk.location.LocationState.LOCATION_TAG; +import static app.organicmaps.sdk.util.PowerManagment.POWER_MANAGEMENT_TAG; + import android.annotation.SuppressLint; import android.app.Activity; import android.app.Dialog; @@ -23,7 +36,6 @@ import android.view.Window; import android.view.WindowManager; import android.widget.TextView; import android.widget.Toast; - import androidx.activity.result.ActivityResult; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.IntentSenderRequest; @@ -48,115 +60,92 @@ import app.organicmaps.backup.PeriodicBackupRunner; import app.organicmaps.base.BaseMwmFragmentActivity; import app.organicmaps.base.OnBackPressListener; import app.organicmaps.bookmarks.BookmarkCategoriesActivity; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.display.DisplayChangedListener; -import app.organicmaps.display.DisplayManager; -import app.organicmaps.display.DisplayType; import app.organicmaps.downloader.DownloaderActivity; import app.organicmaps.downloader.DownloaderFragment; -import app.organicmaps.downloader.MapManager; import app.organicmaps.downloader.OnmapDownloader; -import app.organicmaps.downloader.UpdateInfo; -import app.organicmaps.editor.Editor; import app.organicmaps.editor.EditorActivity; import app.organicmaps.editor.EditorHostFragment; import app.organicmaps.editor.FeatureCategoryActivity; import app.organicmaps.editor.OsmLoginActivity; -import app.organicmaps.editor.OsmOAuth; import app.organicmaps.editor.ReportFragment; import app.organicmaps.help.HelpActivity; import app.organicmaps.intent.Factory; import app.organicmaps.intent.IntentProcessor; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.LocationListener; -import app.organicmaps.location.LocationState; -import app.organicmaps.location.SensorHelper; -import app.organicmaps.location.SensorListener; -import app.organicmaps.location.TrackRecorder; +import app.organicmaps.leftbutton.LeftButton; +import app.organicmaps.leftbutton.LeftButtonsHolder; +import app.organicmaps.leftbutton.LeftToggleButton; import app.organicmaps.location.TrackRecordingService; import app.organicmaps.maplayer.MapButtonsController; import app.organicmaps.maplayer.MapButtonsViewModel; import app.organicmaps.maplayer.ToggleMapLayerFragment; -import app.organicmaps.maplayer.isolines.IsolinesManager; -import app.organicmaps.maplayer.isolines.IsolinesState; import app.organicmaps.routing.ManageRouteBottomSheet; import app.organicmaps.routing.NavigationController; import app.organicmaps.routing.NavigationService; -import app.organicmaps.sdk.routing.RouteMarkType; import app.organicmaps.routing.RoutingBottomMenuListener; import app.organicmaps.routing.RoutingController; import app.organicmaps.routing.RoutingErrorDialogFragment; -import app.organicmaps.sdk.routing.RoutingOptions; import app.organicmaps.routing.RoutingPlanFragment; import app.organicmaps.routing.RoutingPlanInplaceController; import app.organicmaps.sdk.ChoosePositionMode; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.Map; +import app.organicmaps.sdk.MapRenderingListener; import app.organicmaps.sdk.PlacePageActivationListener; import app.organicmaps.sdk.Router; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.display.DisplayChangedListener; +import app.organicmaps.sdk.display.DisplayManager; +import app.organicmaps.sdk.display.DisplayType; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.downloader.UpdateInfo; +import app.organicmaps.sdk.editor.Editor; +import app.organicmaps.sdk.editor.OsmOAuth; +import app.organicmaps.sdk.location.LocationHelper; +import app.organicmaps.sdk.location.LocationListener; +import app.organicmaps.sdk.location.LocationState; +import app.organicmaps.sdk.location.SensorListener; +import app.organicmaps.sdk.location.TrackRecorder; +import app.organicmaps.sdk.maplayer.isolines.IsolinesState; +import app.organicmaps.sdk.routing.RouteMarkType; +import app.organicmaps.sdk.routing.RoutingOptions; +import app.organicmaps.sdk.search.SearchEngine; +import app.organicmaps.sdk.settings.RoadType; +import app.organicmaps.sdk.settings.UnitLocale; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.PowerManagment; +import app.organicmaps.sdk.util.ThemeSwitcher; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.log.Logger; +import app.organicmaps.sdk.widget.placepage.PlacePageData; import app.organicmaps.search.FloatingSearchToolbarController; import app.organicmaps.search.SearchActivity; -import app.organicmaps.sdk.search.SearchEngine; import app.organicmaps.search.SearchFragment; import app.organicmaps.settings.DrivingOptionsActivity; -import app.organicmaps.settings.RoadType; import app.organicmaps.settings.SettingsActivity; -import app.organicmaps.settings.UnitLocale; -import app.organicmaps.leftbutton.LeftButton; -import app.organicmaps.leftbutton.LeftButtonsHolder; -import app.organicmaps.leftbutton.LeftToggleButton; -import app.organicmaps.util.Config; -import app.organicmaps.util.LocationUtils; -import app.organicmaps.util.PowerManagment; import app.organicmaps.util.SharingUtils; -import app.organicmaps.util.ThemeSwitcher; import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.UiUtils; import app.organicmaps.util.Utils; import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment; import app.organicmaps.util.bottomsheet.MenuBottomSheetItem; -import app.organicmaps.util.log.Logger; import app.organicmaps.widget.StackedButtonsDialog; import app.organicmaps.widget.menu.MainMenu; import app.organicmaps.widget.placepage.PlacePageController; -import app.organicmaps.widget.placepage.PlacePageData; import app.organicmaps.widget.placepage.PlacePageViewModel; - import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.floatingactionbutton.FloatingActionButton; - import java.util.ArrayList; import java.util.Objects; -import static android.Manifest.permission.ACCESS_COARSE_LOCATION; -import static android.Manifest.permission.ACCESS_FINE_LOCATION; -import static android.Manifest.permission.POST_NOTIFICATIONS; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static app.organicmaps.location.LocationState.FOLLOW; -import static app.organicmaps.location.LocationState.FOLLOW_AND_ROTATE; -import static app.organicmaps.location.LocationState.LOCATION_TAG; -import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_ADD_PLACE_CODE; -import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_HELP_CODE; -import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_RECORD_TRACK_CODE; -import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_SETTINGS_CODE; -import static app.organicmaps.util.PowerManagment.POWER_MANAGEMENT_TAG; -import static app.organicmaps.util.concurrency.UiThread.runLater; - public class MwmActivity extends BaseMwmFragmentActivity - implements PlacePageActivationListener, - View.OnTouchListener, - MapRenderingListener, - RoutingController.Container, - LocationListener, - SensorListener, - LocationState.ModeChangeListener, - RoutingPlanInplaceController.RoutingPlanListener, - RoutingBottomMenuListener, - BookmarkManager.BookmarksLoadingListener, - FloatingSearchToolbarController.SearchToolbarListener, + implements PlacePageActivationListener, View.OnTouchListener, MapRenderingListener, RoutingController.Container, + LocationListener, SensorListener, LocationState.ModeChangeListener, + RoutingPlanInplaceController.RoutingPlanListener, RoutingBottomMenuListener, + BookmarkManager.BookmarksLoadingListener, FloatingSearchToolbarController.SearchToolbarListener, MenuBottomSheetFragment.MenuBottomSheetInterfaceWithHeader, - PlacePageController.PlacePageRouteSettingsListener, - MapButtonsController.MapButtonClickListener, + PlacePageController.PlacePageRouteSettingsListener, MapButtonsController.MapButtonClickListener, DisplayChangedListener { private static final String TAG = MwmActivity.class.getSimpleName(); @@ -169,17 +158,15 @@ public class MwmActivity extends BaseMwmFragmentActivity private static final String EXTRA_CONSUMED = "mwm.extra.intent.processed"; private boolean mPreciseLocationDialogShown = false; - private static final String[] DOCKED_FRAGMENTS = { SearchFragment.class.getName(), - DownloaderFragment.class.getName(), - RoutingPlanFragment.class.getName(), - EditorHostFragment.class.getName(), - ReportFragment.class.getName() }; + private static final String[] DOCKED_FRAGMENTS = {SearchFragment.class.getName(), DownloaderFragment.class.getName(), + RoutingPlanFragment.class.getName(), + EditorHostFragment.class.getName(), ReportFragment.class.getName()}; - public final ActivityResultLauncher startDrivingOptionsForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> - { - if( activityResult.getResultCode() == Activity.RESULT_OK) - rebuildLastRoute(); - }); + public final ActivityResultLauncher startDrivingOptionsForResult = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { + if (activityResult.getResultCode() == Activity.RESULT_OK) + rebuildLastRoute(); + }); private static final String MAIN_MENU_ID = "MAIN_MENU_BOTTOM_SHEET"; private static final String LAYERS_MENU_ID = "LAYERS_MENU_BOTTOM_SHEET"; @@ -273,8 +260,7 @@ public class MwmActivity extends BaseMwmFragmentActivity public static Intent createShowMapIntent(@NonNull Context context, @Nullable String countryId) { - return new Intent(context, DownloadResourcesLegacyActivity.class) - .putExtra(EXTRA_COUNTRY_ID, countryId); + return new Intent(context, DownloadResourcesLegacyActivity.class).putExtra(EXTRA_COUNTRY_ID, countryId); } @Override @@ -283,10 +269,8 @@ public class MwmActivity extends BaseMwmFragmentActivity checkMeasurementSystem(); } - // Called from JNI. @Override @Keep - @SuppressWarnings("unused") public void onRenderingInitializationFinished() { ThemeSwitcher.INSTANCE.restart(true); @@ -363,14 +347,15 @@ public class MwmActivity extends BaseMwmFragmentActivity private void migrateOAuthCredentials() { - if (OsmOAuth.containsOAuth1Credentials(this)) + if (OsmOAuth.containsOAuth1Credentials()) { // Remove old OAuth v1 secrets - OsmOAuth.clearOAuth1Credentials(this); + OsmOAuth.clearOAuth1Credentials(); // Notify user to re-login dismissAlertDialog(); - final DialogInterface.OnClickListener navigateToLoginHandler = (dialog, which) -> startActivity(new Intent(MwmActivity.this, OsmLoginActivity.class)); + final DialogInterface.OnClickListener navigateToLoginHandler = + (dialog, which) -> startActivity(new Intent(MwmActivity.this, OsmLoginActivity.class)); final int marginBase = getResources().getDimensionPixelSize(R.dimen.margin_base); final float textSize = getResources().getDimension(R.dimen.line_spacing_extra_1); @@ -381,12 +366,12 @@ public class MwmActivity extends BaseMwmFragmentActivity text.setMovementMethod(LinkMovementMethod.getInstance()); mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.login_osm) - .setView(text) - .setPositiveButton(R.string.login, navigateToLoginHandler) - .setNegativeButton(R.string.cancel, null) - .setOnDismissListener(dialog -> mAlertDialog = null) - .show(); + .setTitle(R.string.login_osm) + .setView(text) + .setPositiveButton(R.string.login, navigateToLoginHandler) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(dialog -> mAlertDialog = null) + .show(); } } @@ -398,8 +383,7 @@ public class MwmActivity extends BaseMwmFragmentActivity @Override protected int getFragmentContentResId() { - return (mIsTabletLayout ? R.id.fragment_container - : super.getFragmentContentResId()); + return (mIsTabletLayout ? R.id.fragment_container : super.getFragmentContentResId()); } @Nullable @@ -417,7 +401,8 @@ public class MwmActivity extends BaseMwmFragmentActivity } @Override - public void replaceFragment(@NonNull Class fragmentClass, @Nullable Bundle args, @Nullable Runnable completionListener) + public void replaceFragment(@NonNull Class fragmentClass, @Nullable Bundle args, + @Nullable Runnable completionListener) { if (mPanelAnimator.isVisible() && getFragment(fragmentClass) != null) { @@ -472,7 +457,7 @@ public class MwmActivity extends BaseMwmFragmentActivity private void shareMyLocation() { - final Location loc = LocationHelper.from(this).getSavedLocation(); + final Location loc = MwmApplication.from(this).getLocationHelper().getSavedLocation(); if (loc != null) { SharingUtils.shareLocation(this, loc); @@ -481,11 +466,11 @@ public class MwmActivity extends BaseMwmFragmentActivity dismissLocationErrorDialog(); mLocationErrorDialog = new MaterialAlertDialogBuilder(MwmActivity.this, R.style.MwmTheme_AlertDialog) - .setMessage(R.string.unknown_current_position) - .setCancelable(true) - .setPositiveButton(R.string.ok, null) - .setOnDismissListener(dialog -> mLocationErrorDialog = null) - .show(); + .setMessage(R.string.unknown_current_position) + .setCancelable(true) + .setPositiveButton(R.string.ok, null) + .setOnDismissListener(dialog -> mLocationErrorDialog = null) + .show(); } private void showDownloader(boolean openDownloaded) @@ -534,7 +519,8 @@ public class MwmActivity extends BaseMwmFragmentActivity final int newUiMode = newConfig.uiMode & Configuration.UI_MODE_TYPE_MASK; final boolean newUiModeIsCarConnected = newUiMode == Configuration.UI_MODE_TYPE_CAR; - final boolean newUiModeIsCarDisconnected = mLastUiMode == Configuration.UI_MODE_TYPE_CAR && newUiMode == Configuration.UI_MODE_TYPE_NORMAL; + final boolean newUiModeIsCarDisconnected = + mLastUiMode == Configuration.UI_MODE_TYPE_CAR && newUiMode == Configuration.UI_MODE_TYPE_NORMAL; mLastUiMode = newUiMode; if (newUiModeIsCarConnected || newUiModeIsCarDisconnected) @@ -566,25 +552,24 @@ public class MwmActivity extends BaseMwmFragmentActivity mMapButtonsViewModel.getLayoutMode().observe(this, this::initNavigationButtons); mSearchController = new FloatingSearchToolbarController(this, this); - mSearchController.getToolbar() - .getViewTreeObserver(); + mSearchController.getToolbar().getViewTreeObserver(); // Note: You must call registerForActivityResult() before the fragment or activity is created. mLocationPermissionRequest = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), - this::onLocationPermissionsResult); + this::onLocationPermissionsResult); mLocationResolutionRequest = registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), - this::onLocationResolutionResult); + this::onLocationResolutionResult); mPostNotificationPermissionRequest = registerForActivityResult(new ActivityResultContracts.RequestPermission(), - this::onPostNotificationPermissionResult); - mPowerSaveSettings = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), - this::onPowerSaveResult); + this::onPostNotificationPermissionResult); + mPowerSaveSettings = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), this::onPowerSaveResult); - mSettingsLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), - this::onSettingsResult); + mSettingsLauncher = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), this::onSettingsResult); mShareLauncher = SharingUtils.RegisterLauncher(this); - mDisplayManager = DisplayManager.from(this); + mDisplayManager = MwmApplication.from(this).getDisplayManager(); if (mDisplayManager.isCarDisplayUsed()) { mRemoveDisplayListener = false; @@ -622,7 +607,8 @@ public class MwmActivity extends BaseMwmFragmentActivity Intent data = activityResult.getData(); if (data != null && data.hasExtra(MwmActivity.this.getString(R.string.pref_left_button))) { - MapButtonsController mMapButtonsController = (MapButtonsController) getSupportFragmentManager().findFragmentById(R.id.map_buttons); + MapButtonsController mMapButtonsController = + (MapButtonsController) getSupportFragmentManager().findFragmentById(R.id.map_buttons); if (mMapButtonsController != null) { mMapButtonsController.reloadLeftButton(buttonsHolder.getActiveButton()); @@ -633,11 +619,8 @@ public class MwmActivity extends BaseMwmFragmentActivity private void refreshLightStatusBar() { - UiUtils.setLightStatusBar(this, !( - ThemeUtils.isNightTheme(this) - || RoutingController.get().isPlanning() - || ChoosePositionMode.get() != ChoosePositionMode.None - )); + UiUtils.setLightStatusBar(this, !(ThemeUtils.isNightTheme(this) || RoutingController.get().isPlanning() + || ChoosePositionMode.get() != ChoosePositionMode.None)); } private void updateViewsInsets() @@ -645,13 +628,15 @@ public class MwmActivity extends BaseMwmFragmentActivity ViewCompat.setOnApplyWindowInsetsListener(mPointChooser, (view, windowInsets) -> { UiUtils.setViewInsetsPaddingBottom(mPointChooser, windowInsets); UiUtils.setViewInsetsPaddingNoBottom(mPointChooserToolbar, windowInsets); - final int trackRecorderOffset = TrackRecorder.nativeIsTrackRecordingEnabled() ? UiUtils.dimen(this, R.dimen.map_button_size) : 0; + final int trackRecorderOffset = + TrackRecorder.nativeIsTrackRecordingEnabled() ? UiUtils.dimen(this, R.dimen.map_button_size) : 0; mNavBarHeight = isFullscreen() ? 0 : windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom; // For the first loading, set compass top margin to status bar size // The top inset will be then be updated by the routing controller if (mCurrentWindowInsets == null) { - updateCompassOffset(trackRecorderOffset + windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).top, windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).right); + updateCompassOffset(trackRecorderOffset + windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).top, + windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).right); } refreshLightStatusBar(); updateBottomWidgetsOffset(windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).left); @@ -677,8 +662,9 @@ public class MwmActivity extends BaseMwmFragmentActivity removeCurrentFragment(false); } - mNavigationController = new NavigationController(this, v -> onSettingsOptionSelected(), this::updateBottomWidgetsOffset); - //TrafficManager.INSTANCE.attach(mNavigationController); + mNavigationController = + new NavigationController(this, v -> onSettingsOptionSelected(), this::updateBottomWidgetsOffset); + // TrafficManager.INSTANCE.attach(mNavigationController); initMainMenu(); initOnmapDownloader(); @@ -694,38 +680,35 @@ public class MwmActivity extends BaseMwmFragmentActivity mPointChooserToolbar = mPointChooser.findViewById(R.id.toolbar_point_chooser); UiUtils.showHomeUpButton(mPointChooserToolbar); mPointChooserToolbar.setNavigationOnClickListener(v -> closePositionChooser()); - mPointChooser.findViewById(R.id.done).setOnClickListener( - v -> - { - switch (ChoosePositionMode.get()) + mPointChooser.findViewById(R.id.done).setOnClickListener(v -> { + switch (ChoosePositionMode.get()) + { + case Api: + final Intent apiResult = new Intent(); + final double[] center = Framework.nativeGetScreenRectCenter(); + apiResult.putExtra(Const.EXTRA_POINT_LAT, center[0]); + apiResult.putExtra(Const.EXTRA_POINT_LON, center[1]); + apiResult.putExtra(Const.EXTRA_ZOOM_LEVEL, Framework.nativeGetDrawScale()); + setResult(Activity.RESULT_OK, apiResult); + finish(); + break; + case Editor: + if (Framework.nativeIsDownloadedMapAtScreenCenter()) + startActivity(new Intent(MwmActivity.this, FeatureCategoryActivity.class)); + else { - case Api: - final Intent apiResult = new Intent(); - final double[] center = Framework.nativeGetScreenRectCenter(); - apiResult.putExtra(Const.EXTRA_POINT_LAT, center[0]); - apiResult.putExtra(Const.EXTRA_POINT_LON, center[1]); - apiResult.putExtra(Const.EXTRA_ZOOM_LEVEL, Framework.nativeGetDrawScale()); - setResult(Activity.RESULT_OK, apiResult); - finish(); - break; - case Editor: - if (Framework.nativeIsDownloadedMapAtScreenCenter()) - startActivity(new Intent(MwmActivity.this, FeatureCategoryActivity.class)); - else - { - dismissAlertDialog(); - mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.message_invalid_feature_position) - .setPositiveButton(R.string.ok, null) - .setOnDismissListener(dialog -> mAlertDialog = null) - .show(); - } - break; - case None: - throw new IllegalStateException("Unexpected Framework.nativeGetChoosePositionMode()"); + dismissAlertDialog(); + mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) + .setTitle(R.string.message_invalid_feature_position) + .setPositiveButton(R.string.ok, null) + .setOnDismissListener(dialog -> mAlertDialog = null) + .show(); } - closePositionChooser(); - }); + break; + case None: throw new IllegalStateException("Unexpected Framework.nativeGetChoosePositionMode()"); + } + closePositionChooser(); + }); UiUtils.hide(mPointChooser); } @@ -750,9 +733,10 @@ public class MwmActivity extends BaseMwmFragmentActivity } } - /** Hides/shows UI while keeping state + /** + *Hides/shows UI while keeping state * @param isUiHidden True to hide the UI - **/ + **/ public void hideOrShowUIWithoutClosingPlacePage(boolean isUiHidden) { // Used instead of closeBottomSheet to preserve state and hide instantly @@ -783,6 +767,16 @@ public class MwmActivity extends BaseMwmFragmentActivity private void showPositionChooser(ChoosePositionMode mode, boolean isBusiness, boolean applyPosition) { closeFloatingToolbarsAndPanels(false); + if (mMapFragment != null) + { + final View mapView = mMapFragment.getView(); + if (mapView != null) + { + int width = mapView.getWidth(); + int height = mapView.getHeight(); + Framework.nativeSetVisibleRect(0, 0, width, height); + } + } UiUtils.show(mPointChooser); mMapButtonsViewModel.setButtonsHidden(true); ChoosePositionMode.set(mode, isBusiness, applyPosition); @@ -795,6 +789,7 @@ public class MwmActivity extends BaseMwmFragmentActivity ChoosePositionMode mode = ChoosePositionMode.get(); ChoosePositionMode.set(ChoosePositionMode.None, false, false); mMapButtonsViewModel.setButtonsHidden(false); + Framework.nativeDeactivatePopup(); refreshLightStatusBar(); if (mode == ChoosePositionMode.Api) finish(); @@ -811,8 +806,7 @@ public class MwmActivity extends BaseMwmFragmentActivity final FragmentFactory factory = manager.getFragmentFactory(); mMapFragment = (MapFragment) factory.instantiate(getClassLoader(), MapFragment.class.getName()); mMapFragment.setArguments(args); - manager - .beginTransaction() + manager.beginTransaction() .replace(R.id.map_fragment_container, mMapFragment, MapFragment.class.getName()) .commit(); } @@ -833,8 +827,7 @@ public class MwmActivity extends BaseMwmFragmentActivity private void prepareNavigationButtons() { buttonsHolder = LeftButtonsHolder.getInstance(this); - buttonsHolder.registerButton(new LeftButton() - { + buttonsHolder.registerButton(new LeftButton() { @Override public String getCode() { @@ -860,8 +853,7 @@ public class MwmActivity extends BaseMwmFragmentActivity MwmActivity.this.startActivity(intent); } }); - buttonsHolder.registerButton(new LeftButton() - { + buttonsHolder.registerButton(new LeftButton() { @Override public String getCode() { @@ -886,8 +878,7 @@ public class MwmActivity extends BaseMwmFragmentActivity onAddPlace(); } }); - buttonsHolder.registerButton(new LeftButton() - { + buttonsHolder.registerButton(new LeftButton() { @Override public String getCode() { @@ -913,8 +904,7 @@ public class MwmActivity extends BaseMwmFragmentActivity } }); - buttonsHolder.registerButton(new LeftToggleButton() - { + buttonsHolder.registerButton(new LeftToggleButton() { private boolean isRecording = TrackRecorder.nativeIsTrackRecordingEnabled(); @Override @@ -940,9 +930,8 @@ public class MwmActivity extends BaseMwmFragmentActivity { imageView.setImageResource(R.drawable.ic_track_recording_off); - int color = isRecording - ? ContextCompat.getColor(MwmActivity.this, R.color.active_track_recording) - : ThemeUtils.getColor(MwmActivity.this, R.attr.iconTint); + int color = isRecording ? ContextCompat.getColor(MwmActivity.this, R.color.active_track_recording) + : ThemeUtils.getColor(MwmActivity.this, R.attr.iconTint); ColorStateList colorStateList = ColorStateList.valueOf(color); imageView.setImageTintList(colorStateList); @@ -965,8 +954,8 @@ public class MwmActivity extends BaseMwmFragmentActivity MapButtonsController mapButtonsController = new MapButtonsController(); mapButtonsController.setLeftButton(buttonsHolder.getActiveButton()); - FragmentTransaction transaction = getSupportFragmentManager() - .beginTransaction().replace(R.id.map_buttons, mapButtonsController); + FragmentTransaction transaction = + getSupportFragmentManager().beginTransaction().replace(R.id.map_buttons, mapButtonsController); transaction.commit(); mPreviousMapLayoutMode = layoutMode; } @@ -1004,11 +993,9 @@ public class MwmActivity extends BaseMwmFragmentActivity } } - private boolean closeBottomSheet(String id) { - MenuBottomSheetFragment bottomSheet = - (MenuBottomSheetFragment) getSupportFragmentManager().findFragmentByTag(id); + MenuBottomSheetFragment bottomSheet = (MenuBottomSheetFragment) getSupportFragmentManager().findFragmentByTag(id); if (bottomSheet == null || !bottomSheet.isAdded()) return false; bottomSheet.dismiss(); @@ -1140,7 +1127,7 @@ public class MwmActivity extends BaseMwmFragmentActivity LocationState.nativeSwitchToNextMode(); } - MapObject startPoint = LocationHelper.from(this).getMyPosition(); + MapObject startPoint = MwmApplication.from(this).getLocationHelper().getMyPosition(); RoutingController.get().prepare(startPoint, endPoint); // TODO: check for tablet. @@ -1244,12 +1231,13 @@ public class MwmActivity extends BaseMwmFragmentActivity dismissAlertDialog(); mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.downloader_update_maps) - .setMessage(R.string.isolines_activation_error_dialog) - .setPositiveButton(R.string.ok, (dialog, which) -> startActivity(new Intent(this, DownloaderActivity.class))) - .setNegativeButton(R.string.cancel, null) - .setOnDismissListener(dialog -> mAlertDialog = null) - .show(); + .setTitle(R.string.downloader_update_maps) + .setMessage(R.string.isolines_activation_error_dialog) + .setPositiveButton(R.string.ok, + (dialog, which) -> startActivity(new Intent(this, DownloaderActivity.class))) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(dialog -> mAlertDialog = null) + .show(); } @Override @@ -1259,20 +1247,17 @@ public class MwmActivity extends BaseMwmFragmentActivity super.onNewIntent(intent); if (isMapRendererActive()) processIntent(); - if (intent.getAction() != null && intent.getAction() - .equals(TrackRecordingService.STOP_TRACK_RECORDING)) + if (intent.getAction() != null && intent.getAction().equals(TrackRecordingService.STOP_TRACK_RECORDING)) { - //closes the bottom sheet in case it is opened to deal with updation of track recording status in bottom sheet. + // closes the bottom sheet in case it is opened to deal with updation of track recording status in bottom sheet. closeBottomSheet(MAIN_MENU_ID); showTrackSaveDialog(); } } - private boolean isMapRendererActive() { - return mMapFragment != null && Map.isEngineCreated() - && mMapFragment.isContextCreated(); + return mMapFragment != null && Map.isEngineCreated() && mMapFragment.isContextCreated(); } @CallSuper @@ -1295,7 +1280,7 @@ public class MwmActivity extends BaseMwmFragmentActivity mNavigationController.refresh(); refreshLightStatusBar(); - SensorHelper.from(this).addListener(this); + MwmApplication.from(this).getSensorHelper().addListener(this); } @Override @@ -1319,7 +1304,7 @@ public class MwmActivity extends BaseMwmFragmentActivity { if (mOnmapDownloader != null) mOnmapDownloader.onPause(); - SensorHelper.from(this).removeListener(this); + MwmApplication.from(this).getSensorHelper().removeListener(this); dismissLocationErrorDialog(); dismissAlertDialog(); super.onPause(); @@ -1332,9 +1317,9 @@ public class MwmActivity extends BaseMwmFragmentActivity Framework.nativePlacePageActivationListener(this); BookmarkManager.INSTANCE.addLoadingListener(this); RoutingController.get().attach(this); - IsolinesManager.from(getApplicationContext()).attach(this::onIsolinesStateChanged); + MwmApplication.from(getApplicationContext()).getIsolinesManager().attach(this::onIsolinesStateChanged); LocationState.nativeSetListener(this); - LocationHelper.from(this).addListener(this); + MwmApplication.from(this).getLocationHelper().addListener(this); mSearchController.attach(this); Utils.keepScreenOn(Config.isKeepScreenOnEnabled() || RoutingController.get().isNavigating(), getWindow()); } @@ -1345,13 +1330,13 @@ public class MwmActivity extends BaseMwmFragmentActivity super.onStop(); Framework.nativeRemovePlacePageActivationListener(this); BookmarkManager.INSTANCE.removeLoadingListener(this); - LocationHelper.from(this).removeListener(this); + MwmApplication.from(this).getLocationHelper().removeListener(this); if (mDisplayManager.isDeviceDisplayUsed() && !RoutingController.get().isNavigating()) { LocationState.nativeRemoveListener(); RoutingController.get().detach(); } - IsolinesManager.from(getApplicationContext()).detach(); + MwmApplication.from(getApplicationContext()).getIsolinesManager().detach(); mSearchController.detach(); Utils.keepScreenOn(false, getWindow()); @@ -1386,10 +1371,9 @@ public class MwmActivity extends BaseMwmFragmentActivity public void onBackPressed() { final RoutingController routingController = RoutingController.get(); - if (!closeBottomSheet(MAIN_MENU_ID) && !closeBottomSheet(LAYERS_MENU_ID) && - !collapseNavMenu() && !closePlacePage() && !closeSearchToolbar(true, true) && - !closeSidePanel() && !closePositionChooser() && - !routingController.resetToPlanningStateIfNavigating() && !routingController.cancel()) + if (!closeBottomSheet(MAIN_MENU_ID) && !closeBottomSheet(LAYERS_MENU_ID) && !collapseNavMenu() && !closePlacePage() + && !closeSearchToolbar(true, true) && !closeSidePanel() && !closePositionChooser() + && !routingController.resetToPlanningStateIfNavigating() && !routingController.cancel()) { try { @@ -1421,9 +1405,7 @@ public class MwmActivity extends BaseMwmFragmentActivity if (fm.isDestroyed()) return; - fm.beginTransaction() - .remove(fragment) - .commitAllowingStateLoss(); + fm.beginTransaction().remove(fragment).commitAllowingStateLoss(); fm.executePendingTransactions(); } @@ -1453,26 +1435,20 @@ public class MwmActivity extends BaseMwmFragmentActivity return true; } - // Called from JNI. @Override - @SuppressWarnings("unused") public void onPlacePageActivated(@NonNull PlacePageData data) { // This will open the place page mPlacePageViewModel.setMapObject((MapObject) data); } - // Called from JNI. @Override - @SuppressWarnings("unused") public void onPlacePageDeactivated() { closePlacePage(); } - // Called from JNI. @Override - @SuppressWarnings("unused") public void onSwitchFullScreenMode() { if ((mPanelAnimator != null && mPanelAnimator.isVisible()) || UiUtils.isVisible(mSearchController.getToolbar())) @@ -1490,9 +1466,8 @@ public class MwmActivity extends BaseMwmFragmentActivity private void setFullscreen(boolean isFullscreen) { - if (RoutingController.get().isNavigating() - || RoutingController.get().isBuilding() - || RoutingController.get().isPlanning()) + if (RoutingController.get().isNavigating() || RoutingController.get().isBuilding() + || RoutingController.get().isPlanning()) return; mMapButtonsViewModel.setButtonsHidden(isFullscreen); @@ -1502,13 +1477,15 @@ public class MwmActivity extends BaseMwmFragmentActivity private boolean isFullscreen() { // Buttons are hidden in position chooser mode but we are not in fullscreen - return Boolean.TRUE.equals(mMapButtonsViewModel.getButtonsHidden().getValue()) && - ChoosePositionMode.get() == ChoosePositionMode.None; + return Boolean.TRUE.equals(mMapButtonsViewModel.getButtonsHidden().getValue()) + && ChoosePositionMode.get() == ChoosePositionMode.None; } @Override - public boolean dispatchGenericMotionEvent(MotionEvent event) { - if (event.getActionMasked() == MotionEvent.ACTION_SCROLL) { + public boolean dispatchGenericMotionEvent(MotionEvent event) + { + if (event.getActionMasked() == MotionEvent.ACTION_SCROLL) + { int exponent = event.getAxisValue(MotionEvent.AXIS_VSCROLL) < 0 ? -1 : 1; Map.onScale(Math.pow(1.7f, exponent), event.getX(), event.getY(), true); return true; @@ -1542,12 +1519,13 @@ public class MwmActivity extends BaseMwmFragmentActivity mMapFragment.updateCompassOffset(offsetX, offsetY); - final double north = SensorHelper.from(this).getSavedNorth(); + final double north = MwmApplication.from(this).getSensorHelper().getSavedNorth(); if (!Double.isNaN(north)) Map.onCompassUpdated(north, true); } - public void onMapBottomButtonsHeightChange(float height) { + public void onMapBottomButtonsHeightChange(float height) + { updateBottomWidgetsOffset(); } @@ -1614,8 +1592,7 @@ public class MwmActivity extends BaseMwmFragmentActivity mMainMenu.setState(MainMenu.State.MENU, isFullscreen()); } - private boolean showAddStartOrFinishFrame(@NonNull RoutingController controller, - boolean showFrame) + private boolean showAddStartOrFinishFrame(@NonNull RoutingController controller, boolean showFrame) { // S - start, F - finish, L - my position // -S-F-L -> Start @@ -1627,7 +1604,7 @@ public class MwmActivity extends BaseMwmFragmentActivity // +S+F-L -> Hide // +S+F+L -> Hide - MapObject myPosition = LocationHelper.from(this).getMyPosition(); + MapObject myPosition = MwmApplication.from(this).getLocationHelper().getMyPosition(); if (myPosition != null && controller.getEndPoint() == null) { @@ -1690,7 +1667,8 @@ public class MwmActivity extends BaseMwmFragmentActivity { // TODO This code section may be called when insets are not yet initialized // This is only a workaround to prevent crashes but a proper fix should be implemented - if (mCurrentWindowInsets == null) { + if (mCurrentWindowInsets == null) + { return; } int offsetY = mCurrentWindowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).top; @@ -1886,8 +1864,8 @@ public class MwmActivity extends BaseMwmFragmentActivity @Override public void onCommonBuildError(int lastResultCode, @NonNull String[] lastMissingMaps) { - RoutingErrorDialogFragment fragment = RoutingErrorDialogFragment.create(getSupportFragmentManager().getFragmentFactory(), - getApplicationContext(), lastResultCode, lastMissingMaps); + RoutingErrorDialogFragment fragment = RoutingErrorDialogFragment.create( + getSupportFragmentManager().getFragmentFactory(), getApplicationContext(), lastResultCode, lastMissingMaps); fragment.show(getSupportFragmentManager(), RoutingErrorDialogFragment.class.getSimpleName()); } @@ -1895,13 +1873,15 @@ public class MwmActivity extends BaseMwmFragmentActivity public void onDrivingOptionsBuildError() { dismissAlertDialog(); - mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.unable_to_calc_alert_title) - .setMessage(R.string.unable_to_calc_alert_subtitle) - .setPositiveButton(R.string.settings, (dialog, which) -> DrivingOptionsActivity.start(this, startDrivingOptionsForResult)) - .setNegativeButton(R.string.cancel, null) - .setOnDismissListener(dialog -> mAlertDialog = null) - .show(); + mAlertDialog = + new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) + .setTitle(R.string.unable_to_calc_alert_title) + .setMessage(R.string.unable_to_calc_alert_subtitle) + .setPositiveButton(R.string.settings, + (dialog, which) -> DrivingOptionsActivity.start(this, startDrivingOptionsForResult)) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(dialog -> mAlertDialog = null) + .show(); } private boolean showRoutingDisclaimer() @@ -1910,23 +1890,25 @@ public class MwmActivity extends BaseMwmFragmentActivity return true; final StringBuilder builder = new StringBuilder(); - for (int resId : new int[]{R.string.dialog_routing_disclaimer_priority, R.string.dialog_routing_disclaimer_precision, - R.string.dialog_routing_disclaimer_recommendations, R.string.dialog_routing_disclaimer_borders, - R.string.dialog_routing_disclaimer_beware}) + for (int resId : + new int[] {R.string.dialog_routing_disclaimer_priority, R.string.dialog_routing_disclaimer_precision, + R.string.dialog_routing_disclaimer_recommendations, R.string.dialog_routing_disclaimer_borders, + R.string.dialog_routing_disclaimer_beware}) builder.append(getString(resId)).append("\n\n"); dismissAlertDialog(); mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.dialog_routing_disclaimer_title) - .setMessage(builder.toString()) - .setCancelable(false) - .setNegativeButton(R.string.decline, null) - .setPositiveButton(R.string.accept, (dlg, which) -> { - Config.acceptRoutingDisclaimer(); - onRoutingStart(); - }) - .setOnDismissListener(dialog -> mAlertDialog = null) - .show(); + .setTitle(R.string.dialog_routing_disclaimer_title) + .setMessage(builder.toString()) + .setCancelable(false) + .setNegativeButton(R.string.decline, null) + .setPositiveButton(R.string.accept, + (dlg, which) -> { + Config.acceptRoutingDisclaimer(); + onRoutingStart(); + }) + .setOnDismissListener(dialog -> mAlertDialog = null) + .show(); return false; } @@ -1953,7 +1935,7 @@ public class MwmActivity extends BaseMwmFragmentActivity (dialog, which) -> controller.swapPoints() : (dialog, which) -> { // The current location may change while this dialog is still shown on the screen. - final MapObject myPosition = LocationHelper.from(this).getMyPosition(); + final MapObject myPosition = MwmApplication.from(this).getLocationHelper().getMyPosition(); controller.setStartPoint(myPosition); } ) @@ -1972,7 +1954,7 @@ public class MwmActivity extends BaseMwmFragmentActivity if (controller.isPlanning() || controller.isBuilding() || controller.isErrorEncountered()) showAddStartOrFinishFrame(controller, true); - final LocationHelper locationHelper = LocationHelper.from(this); + final LocationHelper locationHelper = MwmApplication.from(this).getLocationHelper(); // Check if location was disabled by the user. if (LocationState.getMode() == LocationState.NOT_FOLLOW_NO_POSITION) @@ -1992,10 +1974,7 @@ public class MwmActivity extends BaseMwmFragmentActivity Logger.i(LOCATION_TAG, "Requesting ACCESS_FINE_LOCATION + ACCESS_FINE_LOCATION permissions"); dismissLocationErrorDialog(); - mLocationPermissionRequest.launch(new String[]{ - ACCESS_COARSE_LOCATION, - ACCESS_FINE_LOCATION - }); + mLocationPermissionRequest.launch(new String[] {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}); return; } @@ -2006,10 +1985,7 @@ public class MwmActivity extends BaseMwmFragmentActivity // Try to optimistically request FINE permission for FOLLOW and FOLLOW_AND_ROTATE modes. Logger.i(LOCATION_TAG, "Requesting ACCESS_FINE_LOCATION permission for " + LocationState.nameOf(newMode)); dismissLocationErrorDialog(); - mLocationPermissionRequest.launch(new String[]{ - ACCESS_COARSE_LOCATION, - ACCESS_FINE_LOCATION - }); + mLocationPermissionRequest.launch(new String[] {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}); } } @@ -2073,16 +2049,14 @@ public class MwmActivity extends BaseMwmFragmentActivity @UiThread public void onCompassCalibrationRecommended() { - Toast.makeText(this, getString(R.string.compass_calibration_recommended), - Toast.LENGTH_LONG).show(); + Toast.makeText(this, getString(R.string.compass_calibration_recommended), Toast.LENGTH_LONG).show(); } @Override @UiThread public void onCompassCalibrationRequired() { - Toast.makeText(this, getString(R.string.compass_calibration_required), - Toast.LENGTH_LONG).show(); + Toast.makeText(this, getString(R.string.compass_calibration_required), Toast.LENGTH_LONG).show(); } /** @@ -2090,8 +2064,8 @@ public class MwmActivity extends BaseMwmFragmentActivity */ public void requestPostNotificationsPermission() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || - ActivityCompat.checkSelfPermission(this, POST_NOTIFICATIONS) == PERMISSION_GRANTED) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU + || ActivityCompat.checkSelfPermission(this, POST_NOTIFICATIONS) == PERMISSION_GRANTED) { Logger.i(TAG, "Permissions POST_NOTIFICATIONS is granted"); return; @@ -2145,12 +2119,13 @@ public class MwmActivity extends BaseMwmFragmentActivity if (!mPreciseLocationDialogShown) { mPreciseLocationDialogShown = true; - final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle("⚠ " + getString(R.string.limited_accuracy)) - .setMessage(R.string.precise_location_is_disabled_long_text) - .setNegativeButton(R.string.close, (dialog, which) -> dialog.dismiss()) - .setCancelable(true) - .setOnDismissListener(dialog -> mLocationErrorDialog = null); + final MaterialAlertDialogBuilder builder = + new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) + .setTitle("⚠ " + getString(R.string.limited_accuracy)) + .setMessage(R.string.precise_location_is_disabled_long_text) + .setNegativeButton(R.string.close, (dialog, which) -> dialog.dismiss()) + .setCancelable(true) + .setOnDismissListener(dialog -> mLocationErrorDialog = null); final Intent intent = Utils.makeSystemLocationSettingIntent(this); if (intent != null) { @@ -2180,11 +2155,11 @@ public class MwmActivity extends BaseMwmFragmentActivity } mLocationErrorDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.enable_location_services) - .setMessage(R.string.location_is_disabled_long_text) - .setOnDismissListener(dialog -> mLocationErrorDialog = null) - .setNegativeButton(R.string.close, null) - .show(); + .setTitle(R.string.enable_location_services) + .setMessage(R.string.location_is_disabled_long_text) + .setOnDismissListener(dialog -> mLocationErrorDialog = null) + .setNegativeButton(R.string.close, null) + .show(); } /** @@ -2273,10 +2248,10 @@ public class MwmActivity extends BaseMwmFragmentActivity } final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.enable_location_services) - .setMessage(R.string.location_is_disabled_long_text) - .setOnDismissListener(dialog -> mLocationErrorDialog = null) - .setNegativeButton(R.string.close, null); + .setTitle(R.string.enable_location_services) + .setMessage(R.string.location_is_disabled_long_text) + .setOnDismissListener(dialog -> mLocationErrorDialog = null) + .setNegativeButton(R.string.close, null); final Intent intent = Utils.makeSystemLocationSettingIntent(this); if (intent != null) { @@ -2291,7 +2266,7 @@ public class MwmActivity extends BaseMwmFragmentActivity @Override public void onUseMyPositionAsStart() { - RoutingController.get().setStartPoint(LocationHelper.from(this).getMyPosition()); + RoutingController.get().setStartPoint(MwmApplication.from(this).getLocationHelper().getMyPosition()); } @Override @@ -2355,20 +2330,22 @@ public class MwmActivity extends BaseMwmFragmentActivity } dismissAlertDialog(); - final MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.current_location_unknown_error_title) - .setCancelable(true) - .setMessage(R.string.power_save_dialog_summary) - .setNegativeButton(R.string.not_now, (dialog, which) -> { - Logger.d(POWER_MANAGEMENT_TAG, "The Power Save disclaimer was ignored"); - mPowerSaveDisclaimerShown = true; - }) - .setOnDismissListener(dialog -> mAlertDialog = null) - .setPositiveButton(R.string.settings, (dlg, which) -> { - Logger.d(POWER_MANAGEMENT_TAG, "Launching the system Power Save settings"); - mPowerSaveDisclaimerShown = true; - mPowerSaveSettings.launch(intent); - }); + final MaterialAlertDialogBuilder builder = + new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) + .setTitle(R.string.current_location_unknown_error_title) + .setCancelable(true) + .setMessage(R.string.power_save_dialog_summary) + .setNegativeButton(R.string.not_now, + (dialog, which) -> { + Logger.d(POWER_MANAGEMENT_TAG, "The Power Save disclaimer was ignored"); + mPowerSaveDisclaimerShown = true; + }) + .setOnDismissListener(dialog -> mAlertDialog = null) + .setPositiveButton(R.string.settings, (dlg, which) -> { + Logger.d(POWER_MANAGEMENT_TAG, "Launching the system Power Save settings"); + mPowerSaveDisclaimerShown = true; + mPowerSaveSettings.launch(intent); + }); Logger.d(POWER_MANAGEMENT_TAG, "Displaying the Power Save disclaimer"); mAlertDialog = builder.show(); return false; @@ -2378,28 +2355,34 @@ public class MwmActivity extends BaseMwmFragmentActivity public void onBookmarksFileUnsupported(@NonNull Uri uri) { dismissAlertDialog(); - mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.load_kmz_title) - .setMessage(getString(R.string.unknown_file_type, uri)) - .setPositiveButton(R.string.ok, null) - .setNegativeButton(R.string.report_a_bug, (dialog, which) -> Utils.sendBugReport(mShareLauncher, this, - getString(R.string.load_kmz_title), getString(R.string.unknown_file_type, uri))) - .setOnDismissListener(dialog -> mAlertDialog = null) - .show(); + mAlertDialog = + new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) + .setTitle(R.string.load_kmz_title) + .setMessage(getString(R.string.unknown_file_type, uri)) + .setPositiveButton(R.string.ok, null) + .setNegativeButton(R.string.report_a_bug, + (dialog, which) + -> Utils.sendBugReport(mShareLauncher, this, getString(R.string.load_kmz_title), + getString(R.string.unknown_file_type, uri))) + .setOnDismissListener(dialog -> mAlertDialog = null) + .show(); } @Override public void onBookmarksFileDownloadFailed(@NonNull Uri uri, @NonNull String error) { dismissAlertDialog(); - mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.load_kmz_title) - .setMessage(getString(R.string.failed_to_open_file, uri, error)) - .setPositiveButton(R.string.ok, null) - .setNegativeButton(R.string.report_a_bug, (dialog, which) -> Utils.sendBugReport(mShareLauncher, this, - getString(R.string.load_kmz_title), getString(R.string.failed_to_open_file, uri, error))) - .setOnDismissListener(dialog -> mAlertDialog = null) - .show(); + mAlertDialog = + new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) + .setTitle(R.string.load_kmz_title) + .setMessage(getString(R.string.failed_to_open_file, uri, error)) + .setPositiveButton(R.string.ok, null) + .setNegativeButton(R.string.report_a_bug, + (dialog, which) + -> Utils.sendBugReport(mShareLauncher, this, getString(R.string.load_kmz_title), + getString(R.string.failed_to_open_file, uri, error))) + .setOnDismissListener(dialog -> mAlertDialog = null) + .show(); } @Override @@ -2413,11 +2396,11 @@ public class MwmActivity extends BaseMwmFragmentActivity { dismissAlertDialog(); mAlertDialog = new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.load_kmz_title) - .setMessage(R.string.load_kmz_failed) - .setPositiveButton(R.string.ok, null) - .setOnDismissListener(dialog -> mAlertDialog = null) - .show(); + .setTitle(R.string.load_kmz_title) + .setMessage(R.string.load_kmz_failed) + .setPositiveButton(R.string.ok, null) + .setOnDismissListener(dialog -> mAlertDialog = null) + .show(); } @Override @@ -2445,12 +2428,8 @@ public class MwmActivity extends BaseMwmFragmentActivity { switch (keyCode) { - case KeyEvent.KEYCODE_DPAD_DOWN: - Map.zoomOut(); - return true; - case KeyEvent.KEYCODE_DPAD_UP: - Map.zoomIn(); - return true; + case KeyEvent.KEYCODE_DPAD_DOWN: Map.zoomOut(); return true; + case KeyEvent.KEYCODE_DPAD_UP: Map.zoomIn(); return true; case KeyEvent.KEYCODE_ESCAPE: final Intent currIntent = getIntent(); final String backUrl = Framework.nativeGetParsedBackUrl(); @@ -2460,8 +2439,7 @@ public class MwmActivity extends BaseMwmFragmentActivity return true; } return super.onKeyUp(keyCode, event); - default: - return super.onKeyUp(keyCode, event); + default: return super.onKeyUp(keyCode, event); } } @@ -2504,7 +2482,7 @@ public class MwmActivity extends BaseMwmFragmentActivity // according to action of user. Calling it hack because we are avoiding // creation of new methods by using this variable. mLocationPermissionRequestedForRecording = true; - mLocationPermissionRequest.launch(new String[] { ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION }); + mLocationPermissionRequest.launch(new String[] {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}); return false; } @@ -2559,27 +2537,28 @@ public class MwmActivity extends BaseMwmFragmentActivity { if (TrackRecorder.nativeIsTrackRecordingEmpty()) { - Toast.makeText(this, R.string.track_recording_toast_nothing_to_save, Toast.LENGTH_SHORT) - .show(); + Toast.makeText(this, R.string.track_recording_toast_nothing_to_save, Toast.LENGTH_SHORT).show(); stopTrackRecording(); return; } dismissAlertDialog(); mAlertDialog = new StackedButtonsDialog.Builder(this) - .setTitle(R.string.track_recording_alert_title) - .setCancelable(false) - // Negative/Positive/Neutral do not have their usual meaning here. - .setNegativeButton(R.string.continue_recording, (dialog, which) -> mAlertDialog = null) - .setNeutralButton(R.string.stop_without_saving, (dialog, which) -> { - stopTrackRecording(); - mAlertDialog = null; - }) - .setPositiveButton(R.string.save, (dialog, which) -> { - saveAndStopTrackRecording(); - mAlertDialog = null; - }) - .build(); + .setTitle(R.string.track_recording_alert_title) + .setCancelable(false) + // Negative/Positive/Neutral do not have their usual meaning here. + .setNegativeButton(R.string.continue_recording, (dialog, which) -> mAlertDialog = null) + .setNeutralButton(R.string.stop_without_saving, + (dialog, which) -> { + stopTrackRecording(); + mAlertDialog = null; + }) + .setPositiveButton(R.string.save, + (dialog, which) -> { + saveAndStopTrackRecording(); + mAlertDialog = null; + }) + .build(); mAlertDialog.show(); } @@ -2599,20 +2578,25 @@ public class MwmActivity extends BaseMwmFragmentActivity ArrayList items = new ArrayList<>(); if (!BUTTON_ADD_PLACE_CODE.equals(activeLeftButton)) - items.add(new MenuBottomSheetItem(R.string.placepage_add_place_button, R.drawable.ic_plus, this::onAddPlaceOptionSelected)); + items.add(new MenuBottomSheetItem(R.string.placepage_add_place_button, R.drawable.ic_plus, + this::onAddPlaceOptionSelected)); - items.add(new MenuBottomSheetItem(R.string.download_maps, R.drawable.ic_download, getDownloadMapsCounter(), this::onDownloadMapsOptionSelected)); + items.add(new MenuBottomSheetItem(R.string.download_maps, R.drawable.ic_download, getDownloadMapsCounter(), + this::onDownloadMapsOptionSelected)); - if (!Config.getDonateUrl(getApplicationContext()).isEmpty()) + mDonatesUrl = Config.getDonateUrl(getApplicationContext()); + if (!mDonatesUrl.isEmpty()) items.add(new MenuBottomSheetItem(R.string.donate, R.drawable.ic_donate, this::onDonateOptionSelected)); if (!BUTTON_SETTINGS_CODE.equals(activeLeftButton)) items.add(new MenuBottomSheetItem(R.string.settings, R.drawable.ic_settings, this::onSettingsOptionSelected)); if (!BUTTON_RECORD_TRACK_CODE.equals(activeLeftButton)) - items.add(new MenuBottomSheetItem(R.string.start_track_recording, R.drawable.ic_track_recording_off, -1, this::onTrackRecordingOptionSelected)); + items.add(new MenuBottomSheetItem(R.string.start_track_recording, R.drawable.ic_track_recording_off, -1, + this::onTrackRecordingOptionSelected)); - items.add(new MenuBottomSheetItem(R.string.share_my_location, R.drawable.ic_share, this::onShareLocationOptionSelected)); + items.add(new MenuBottomSheetItem(R.string.share_my_location, R.drawable.ic_share, + this::onShareLocationOptionSelected)); if (!BUTTON_HELP_CODE.equals(activeLeftButton)) items.add(new MenuBottomSheetItem(R.string.about_help, R.drawable.ic_logo_monochrome, this::showHelp)); diff --git a/android/app/src/main/java/app/organicmaps/MwmApplication.java b/android/app/src/main/java/app/organicmaps/MwmApplication.java index a3623632c..8aa21dac2 100644 --- a/android/app/src/main/java/app/organicmaps/MwmApplication.java +++ b/android/app/src/main/java/app/organicmaps/MwmApplication.java @@ -1,13 +1,12 @@ package app.organicmaps; -import static app.organicmaps.location.LocationState.LOCATION_TAG; +import static app.organicmaps.sdk.location.LocationState.LOCATION_TAG; import android.app.Activity; import android.app.Application; import android.content.Context; import android.content.SharedPreferences; import android.os.Bundle; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; @@ -15,29 +14,26 @@ import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.ProcessLifecycleOwner; - -import java.io.IOException; -import java.lang.ref.WeakReference; - import app.organicmaps.background.OsmUploadWork; -import app.organicmaps.downloader.Android7RootCertificateWorkaround; import app.organicmaps.downloader.DownloaderNotifier; -import app.organicmaps.display.DisplayManager; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.LocationState; -import app.organicmaps.location.SensorHelper; -import app.organicmaps.location.TrackRecorder; import app.organicmaps.location.TrackRecordingService; -import app.organicmaps.maplayer.isolines.IsolinesManager; -import app.organicmaps.maplayer.subway.SubwayManager; import app.organicmaps.routing.NavigationService; import app.organicmaps.routing.RoutingController; +import app.organicmaps.sdk.Map; import app.organicmaps.sdk.OrganicMaps; -import app.organicmaps.util.Config; -import app.organicmaps.util.ConnectionState; +import app.organicmaps.sdk.display.DisplayManager; +import app.organicmaps.sdk.location.LocationHelper; +import app.organicmaps.sdk.location.LocationState; +import app.organicmaps.sdk.location.SensorHelper; +import app.organicmaps.sdk.location.TrackRecorder; +import app.organicmaps.sdk.maplayer.isolines.IsolinesManager; +import app.organicmaps.sdk.maplayer.subway.SubwayManager; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.ConnectionState; +import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.util.Utils; -import app.organicmaps.util.log.Logger; -import app.organicmaps.util.log.LogsManager; +import java.io.IOException; +import java.lang.ref.WeakReference; public class MwmApplication extends Application implements Application.ActivityLifecycleCallbacks { @@ -48,22 +44,6 @@ public class MwmApplication extends Application implements Application.ActivityL @NonNull private OrganicMaps mOrganicMaps; - @SuppressWarnings("NotNullFieldNotInitialized") - @NonNull - private SubwayManager mSubwayManager; - - @SuppressWarnings("NotNullFieldNotInitialized") - @NonNull - private IsolinesManager mIsolinesManager; - - @SuppressWarnings("NotNullFieldNotInitialized") - @NonNull - private LocationHelper mLocationHelper; - - @SuppressWarnings("NotNullFieldNotInitialized") - @NonNull - private SensorHelper mSensorHelper; - @SuppressWarnings("NotNullFieldNotInitialized") @NonNull private DisplayManager mDisplayManager; @@ -71,6 +51,10 @@ public class MwmApplication extends Application implements Application.ActivityL @Nullable private WeakReference mTopActivity; + @SuppressWarnings("NotNullFieldNotInitialized") + @NonNull + public static MwmApplication sInstance; + @UiThread @Nullable public Activity getTopActivity() @@ -81,25 +65,25 @@ public class MwmApplication extends Application implements Application.ActivityL @NonNull public SubwayManager getSubwayManager() { - return mSubwayManager; + return getOrganicMaps().getSubwayManager(); } @NonNull public IsolinesManager getIsolinesManager() { - return mIsolinesManager; + return getOrganicMaps().getIsolinesManager(); } @NonNull public LocationHelper getLocationHelper() { - return mLocationHelper; + return getOrganicMaps().getLocationHelper(); } @NonNull public SensorHelper getSensorHelper() { - return mSensorHelper; + return getOrganicMaps().getSensorHelper(); } @NonNull @@ -120,13 +104,10 @@ public class MwmApplication extends Application implements Application.ActivityL return (MwmApplication) context.getApplicationContext(); } - @NonNull - public static MwmApplication sInstance; - @NonNull public static SharedPreferences prefs(@NonNull Context context) { - return context.getSharedPreferences(context.getString(R.string.pref_file_name), MODE_PRIVATE); + return from(context).getOrganicMaps().getPreferences(); } @Override @@ -139,10 +120,6 @@ public class MwmApplication extends Application implements Application.ActivityL mOrganicMaps = new OrganicMaps(getApplicationContext()); - LogsManager.INSTANCE.initFileLogging(this); - - Android7RootCertificateWorkaround.initializeIfNeeded(this); - ConnectionState.INSTANCE.initialize(this); DownloaderNotifier.createNotificationChannel(this); @@ -150,10 +127,6 @@ public class MwmApplication extends Application implements Application.ActivityL TrackRecordingService.createNotificationChannel(this); registerActivityLifecycleCallbacks(this); - mSubwayManager = new SubwayManager(this); - mIsolinesManager = new IsolinesManager(this); - mLocationHelper = new LocationHelper(this); - mSensorHelper = new SensorHelper(this); mDisplayManager = new DisplayManager(); } @@ -165,8 +138,7 @@ public class MwmApplication extends Application implements Application.ActivityL }); } - private final LifecycleObserver mProcessLifecycleObserver = new DefaultLifecycleObserver() - { + private final LifecycleObserver mProcessLifecycleObserver = new DefaultLifecycleObserver() { @Override public void onStart(@NonNull LifecycleOwner owner) { @@ -193,7 +165,7 @@ public class MwmApplication extends Application implements Application.ActivityL { Logger.d(TAG, "activity = " + activity); Utils.showOnLockScreen(Config.isShowOnLockScreenEnabled(), activity); - mSensorHelper.setRotation(activity.getWindowManager().getDefaultDisplay().getRotation()); + getSensorHelper().setRotation(activity.getWindowManager().getDefaultDisplay().getRotation()); mTopActivity = new WeakReference<>(activity); } @@ -224,7 +196,7 @@ public class MwmApplication extends Application implements Application.ActivityL { Logger.d(TAG); - mLocationHelper.resumeLocationInForeground(); + getLocationHelper().resumeLocationInForeground(); } private void onBackground() @@ -244,7 +216,7 @@ public class MwmApplication extends Application implements Application.ActivityL else { Logger.i(LOCATION_TAG, "Stopping location in the background"); - mLocationHelper.stop(); + getLocationHelper().stop(); } } } diff --git a/android/app/src/main/java/app/organicmaps/PanelAnimator.java b/android/app/src/main/java/app/organicmaps/PanelAnimator.java index 48fb8a37d..d040d5861 100644 --- a/android/app/src/main/java/app/organicmaps/PanelAnimator.java +++ b/android/app/src/main/java/app/organicmaps/PanelAnimator.java @@ -5,21 +5,19 @@ import android.animation.ValueAnimator; import android.os.Bundle; import android.view.View; import android.view.animation.AccelerateInterpolator; - import androidx.annotation.IntegerRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; - +import app.organicmaps.sdk.util.UiUtils; import org.chromium.base.ObserverList; -import app.organicmaps.util.UiUtils; - class PanelAnimator { private final MwmActivity mActivity; private final ObserverList mAnimationTrackListeners = new ObserverList<>(); - private final ObserverList.RewindableIterator mAnimationTrackIterator = mAnimationTrackListeners.rewindableIterator(); + private final ObserverList.RewindableIterator mAnimationTrackIterator = + mAnimationTrackListeners.rewindableIterator(); private final View mPanel; private final int mWidth; @IntegerRes @@ -50,7 +48,8 @@ class PanelAnimator } /** @param completionListener will be called before the fragment becomes actually visible */ - public void show(final Class clazz, final Bundle args, @Nullable final Runnable completionListener) + public void show(final Class clazz, final Bundle args, + @Nullable final Runnable completionListener) { if (isVisible()) { @@ -78,8 +77,7 @@ class PanelAnimator ValueAnimator animator = ValueAnimator.ofFloat(-mWidth, 0.0f); animator.addUpdateListener(this::track); - animator.addListener(new UiUtils.SimpleAnimatorListener() - { + animator.addListener(new UiUtils.SimpleAnimatorListener() { @Override public void onAnimationEnd(Animator animation) { @@ -109,8 +107,7 @@ class PanelAnimator ValueAnimator animator = ValueAnimator.ofFloat(0.0f, -mWidth); animator.addUpdateListener(this::track); - animator.addListener(new UiUtils.SimpleAnimatorListener() - { + animator.addListener(new UiUtils.SimpleAnimatorListener() { @Override public void onAnimationEnd(Animator animation) { diff --git a/android/app/src/main/java/app/organicmaps/SplashActivity.java b/android/app/src/main/java/app/organicmaps/SplashActivity.java index 14a7dfa91..620f6d500 100644 --- a/android/app/src/main/java/app/organicmaps/SplashActivity.java +++ b/android/app/src/main/java/app/organicmaps/SplashActivity.java @@ -9,7 +9,6 @@ import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; - import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.Keep; @@ -21,20 +20,18 @@ import androidx.core.graphics.Insets; import androidx.core.view.OnApplyWindowInsetsListener; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; - -import app.organicmaps.display.DisplayManager; import app.organicmaps.downloader.DownloaderActivity; import app.organicmaps.intent.Factory; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.util.Config; -import app.organicmaps.util.LocationUtils; +import app.organicmaps.sdk.display.DisplayManager; +import app.organicmaps.sdk.location.LocationHelper; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.util.SharingUtils; import app.organicmaps.util.ThemeUtils; import app.organicmaps.util.Utils; -import app.organicmaps.util.concurrency.UiThread; -import app.organicmaps.util.log.Logger; import com.google.android.material.dialog.MaterialAlertDialogBuilder; - import java.io.IOException; import java.util.Objects; @@ -86,14 +83,14 @@ public class SplashActivity extends AppCompatActivity } }); mPermissionRequest = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), - result -> Config.setLocationRequested()); + result -> Config.setLocationRequested()); mApiRequest = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { setResult(result.getResultCode(), result.getData()); finish(); }); mShareLauncher = SharingUtils.RegisterLauncher(this); - if (DisplayManager.from(this).isCarDisplayUsed()) + if (MwmApplication.from(this).getDisplayManager().isCarDisplayUsed()) { startActivity(new Intent(this, MapPlaceholderActivity.class)); finish(); @@ -109,10 +106,7 @@ public class SplashActivity extends AppCompatActivity if (!Config.isLocationRequested() && !LocationUtils.checkLocationPermission(this)) { Logger.d(TAG, "Requesting location permissions"); - mPermissionRequest.launch(new String[]{ - ACCESS_COARSE_LOCATION, - ACCESS_FINE_LOCATION - }); + mPermissionRequest.launch(new String[] {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}); return; } @@ -140,19 +134,13 @@ public class SplashActivity extends AppCompatActivity { mCanceled = true; new MaterialAlertDialogBuilder(this, R.style.MwmTheme_AlertDialog) - .setTitle(titleId) - .setMessage(messageId) - .setPositiveButton( - R.string.report_a_bug, - (dialog, which) -> Utils.sendBugReport( - mShareLauncher, - this, - "Fatal Error", - Log.getStackTraceString(error) - ) - ) - .setCancelable(false) - .show(); + .setTitle(titleId) + .setMessage(messageId) + .setPositiveButton( + R.string.report_a_bug, + (dialog, which) -> Utils.sendBugReport(mShareLauncher, this, "Fatal Error", Log.getStackTraceString(error))) + .setCancelable(false) + .show(); } private void init() @@ -162,7 +150,8 @@ public class SplashActivity extends AppCompatActivity try { asyncContinue = app.initOrganicMaps(this::processNavigation); - } catch (IOException error) + } + catch (IOException error) { showFatalErrorDialog(R.string.dialog_error_storage_title, R.string.dialog_error_storage_message, error); return; @@ -195,9 +184,12 @@ public class SplashActivity extends AppCompatActivity // https://github.com/organicmaps/organicmaps/issues/6944 final Intent intent = Objects.requireNonNull(getIntent()); - if (isManageSpaceActivity(intent)) { + if (isManageSpaceActivity(intent)) + { intent.setComponent(new ComponentName(this, DownloaderActivity.class)); - } else { + } + else + { intent.setComponent(new ComponentName(this, DownloadResourcesLegacyActivity.class)); } @@ -219,11 +211,14 @@ public class SplashActivity extends AppCompatActivity finish(); } - private boolean isManageSpaceActivity(Intent intent) { + private boolean isManageSpaceActivity(Intent intent) + { var component = intent.getComponent(); - if (!Intent.ACTION_VIEW.equals(intent.getAction())) return false; - if (component == null) return false; + if (!Intent.ACTION_VIEW.equals(intent.getAction())) + return false; + if (component == null) + return false; var manageSpaceActivityName = BuildConfig.APPLICATION_ID + ".ManageSpaceActivity"; diff --git a/android/app/src/main/java/app/organicmaps/WebContainerDelegate.java b/android/app/src/main/java/app/organicmaps/WebContainerDelegate.java index 322018633..a0b3bbd2f 100644 --- a/android/app/src/main/java/app/organicmaps/WebContainerDelegate.java +++ b/android/app/src/main/java/app/organicmaps/WebContainerDelegate.java @@ -7,11 +7,9 @@ import android.net.Uri; import android.view.View; import android.webkit.WebView; import android.webkit.WebViewClient; - import androidx.annotation.NonNull; - import app.organicmaps.base.OnBackPressListener; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.util.UiUtils; public abstract class WebContainerDelegate implements OnBackPressListener { @@ -21,8 +19,7 @@ public abstract class WebContainerDelegate implements OnBackPressListener @SuppressLint("SetJavaScriptEnabled") private void initWebView(String url) { - mWebView.setWebViewClient(new WebViewClient() - { + mWebView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) { @@ -37,7 +34,7 @@ public abstract class WebContainerDelegate implements OnBackPressListener { MailTo parser = MailTo.parse(url); doStartActivity(new Intent(Intent.ACTION_SEND) - .putExtra(Intent.EXTRA_EMAIL, new String[] { parser.getTo() }) + .putExtra(Intent.EXTRA_EMAIL, new String[] {parser.getTo()}) .putExtra(Intent.EXTRA_TEXT, parser.getBody()) .putExtra(Intent.EXTRA_SUBJECT, parser.getSubject()) .putExtra(Intent.EXTRA_CC, parser.getCc()) @@ -46,8 +43,7 @@ public abstract class WebContainerDelegate implements OnBackPressListener return true; } - doStartActivity(new Intent(Intent.ACTION_VIEW) - .setData(Uri.parse(url))); + doStartActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(url))); return true; } }); diff --git a/android/app/src/main/java/app/organicmaps/adapter/DisabledChildSimpleExpandableListAdapter.java b/android/app/src/main/java/app/organicmaps/adapter/DisabledChildSimpleExpandableListAdapter.java index e3bedbf7c..09b4d7638 100644 --- a/android/app/src/main/java/app/organicmaps/adapter/DisabledChildSimpleExpandableListAdapter.java +++ b/android/app/src/main/java/app/organicmaps/adapter/DisabledChildSimpleExpandableListAdapter.java @@ -4,18 +4,23 @@ import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.SimpleExpandableListAdapter; - import java.util.List; import java.util.Map; /** - * Disables child selections, also fixes bug with SimpleExpandableListAdapter not switching expandedGroupLayout and collapsedGroupLayout correctly. + * Disables child selections, also fixes bug with SimpleExpandableListAdapter not switching expandedGroupLayout and + * collapsedGroupLayout correctly. */ public class DisabledChildSimpleExpandableListAdapter extends SimpleExpandableListAdapter { - public DisabledChildSimpleExpandableListAdapter(Context context, List> groupData, int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo, List>> childData, int childLayout, String[] childFrom, int[] childTo) + public DisabledChildSimpleExpandableListAdapter(Context context, List> groupData, + int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, + int[] groupTo, + List>> childData, + int childLayout, String[] childFrom, int[] childTo) { - super(context, groupData, expandedGroupLayout, collapsedGroupLayout, groupFrom, groupTo, childData, childLayout, childFrom, childTo); + super(context, groupData, expandedGroupLayout, collapsedGroupLayout, groupFrom, groupTo, childData, childLayout, + childFrom, childTo); } @Override @@ -29,8 +34,7 @@ public class DisabledChildSimpleExpandableListAdapter extends SimpleExpandableLi * See http://stackoverflow.com/questions/19520037/simpleexpandablelistadapter-and-expandedgrouplayout for details */ @Override - public View getGroupView(int groupPosition, boolean isExpanded, View convertView, - ViewGroup parent) + public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { return super.getGroupView(groupPosition, isExpanded, null, parent); } diff --git a/android/app/src/main/java/app/organicmaps/adapter/OnItemClickListener.java b/android/app/src/main/java/app/organicmaps/adapter/OnItemClickListener.java index b7575d54d..a4a7920ca 100644 --- a/android/app/src/main/java/app/organicmaps/adapter/OnItemClickListener.java +++ b/android/app/src/main/java/app/organicmaps/adapter/OnItemClickListener.java @@ -1,7 +1,6 @@ package app.organicmaps.adapter; import android.view.View; - import androidx.annotation.NonNull; public interface OnItemClickListener diff --git a/android/app/src/main/java/app/organicmaps/api/ParsedSearchRequest.java b/android/app/src/main/java/app/organicmaps/api/ParsedSearchRequest.java deleted file mode 100644 index 2b98aed59..000000000 --- a/android/app/src/main/java/app/organicmaps/api/ParsedSearchRequest.java +++ /dev/null @@ -1,31 +0,0 @@ -package app.organicmaps.api; - - -import androidx.annotation.Keep; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * Represents url_scheme::SearchRequest from core. - */ -// Used by JNI. -@Keep -@SuppressWarnings("unused") -public final class ParsedSearchRequest -{ - @NonNull - public final String mQuery; - @Nullable - public final String mLocale; - public final double mLat; - public final double mLon; - public final boolean mIsSearchOnMap; - - public ParsedSearchRequest(@NonNull String query, @Nullable String locale, double lat, double lon, boolean isSearchOnMap) { - this.mQuery = query; - this.mLocale = locale; - this.mLat = lat; - this.mLon = lon; - this.mIsSearchOnMap = isSearchOnMap; - } -} diff --git a/android/app/src/main/java/app/organicmaps/background/OsmUploadWork.java b/android/app/src/main/java/app/organicmaps/background/OsmUploadWork.java index 52bc6ad2d..cd4945903 100644 --- a/android/app/src/main/java/app/organicmaps/background/OsmUploadWork.java +++ b/android/app/src/main/java/app/organicmaps/background/OsmUploadWork.java @@ -1,23 +1,21 @@ package app.organicmaps.background; import android.content.Context; - import androidx.annotation.NonNull; import androidx.work.Constraints; +import androidx.work.ExistingWorkPolicy; import androidx.work.NetworkType; import androidx.work.OneTimeWorkRequest; import androidx.work.WorkManager; -import androidx.work.WorkRequest; import androidx.work.Worker; import androidx.work.WorkerParameters; import app.organicmaps.MwmApplication; -import app.organicmaps.editor.Editor; -import app.organicmaps.editor.OsmOAuth; -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.editor.Editor; +import app.organicmaps.sdk.editor.OsmOAuth; +import app.organicmaps.sdk.util.log.Logger; public class OsmUploadWork extends Worker { - private static final String TAG = OsmUploadWork.class.getSimpleName(); private final Context mContext; private final WorkerParameters mWorkerParameters; @@ -34,11 +32,11 @@ public class OsmUploadWork extends Worker */ public static void startActionUploadOsmChanges(@NonNull Context context) { - if (Editor.nativeHasSomethingToUpload() && OsmOAuth.isAuthorized(context)) + if (Editor.nativeHasSomethingToUpload() && OsmOAuth.isAuthorized()) { final Constraints c = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build(); - final WorkRequest wr = new OneTimeWorkRequest.Builder(OsmUploadWork.class).setConstraints(c).build(); - WorkManager.getInstance(context).enqueue(wr); + final OneTimeWorkRequest wr = new OneTimeWorkRequest.Builder(OsmUploadWork.class).setConstraints(c).build(); + WorkManager.getInstance(context).beginUniqueWork("UploadOsmChanges", ExistingWorkPolicy.KEEP, wr).enqueue(); } } @@ -46,13 +44,12 @@ public class OsmUploadWork extends Worker @Override public Result doWork() { - final MwmApplication app = MwmApplication.from(mContext); - if (!app.getOrganicMaps().arePlatformAndCoreInitialized()) + if (!MwmApplication.from(mContext).getOrganicMaps().arePlatformAndCoreInitialized()) { Logger.w(TAG, "Application is not initialized, ignoring " + mWorkerParameters); return Result.failure(); } - Editor.uploadChanges(mContext); + Editor.uploadChanges(); return Result.success(); } } diff --git a/android/app/src/main/java/app/organicmaps/backup/BackupUtils.java b/android/app/src/main/java/app/organicmaps/backup/BackupUtils.java index 74d88e65f..91e814e81 100644 --- a/android/app/src/main/java/app/organicmaps/backup/BackupUtils.java +++ b/android/app/src/main/java/app/organicmaps/backup/BackupUtils.java @@ -1,10 +1,9 @@ package app.organicmaps.backup; +import static app.organicmaps.sdk.util.StorageUtils.isFolderWritable; import static app.organicmaps.settings.BackupSettingsFragment.MAX_BACKUPS_DEFAULT_COUNT; import static app.organicmaps.settings.BackupSettingsFragment.MAX_BACKUPS_KEY; -import static app.organicmaps.util.StorageUtils.isFolderWritable; -import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.net.Uri; @@ -13,30 +12,23 @@ import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; import android.text.style.AbsoluteSizeSpan; - import androidx.annotation.NonNull; import androidx.documentfile.provider.DocumentFile; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import app.organicmaps.R; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.log.Logger; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; import java.util.Locale; -import app.organicmaps.R; -import app.organicmaps.util.UiUtils; -import app.organicmaps.util.log.Logger; - public class BackupUtils { private static final String BACKUP_PREFIX = "backup_"; private static final String BACKUP_EXTENSION = ".kmz"; - private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").withLocale(Locale.US); + private static final DateTimeFormatter DATE_FORMATTER = + DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").withLocale(Locale.US); private static final String TAG = BackupUtils.class.getSimpleName(); public static CharSequence formatReadableFolderPath(Context context, @NonNull Uri uri) @@ -63,8 +55,10 @@ public class BackupUtils volumeName = context.getString(R.string.maps_storage_removable); SpannableStringBuilder sb = new SpannableStringBuilder(); - sb.append(volumeName + ": \n", new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_body_3)), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - sb.append("/" + subPath, new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_body_4)), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + sb.append(volumeName + ": \n", new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_body_3)), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + sb.append("/" + subPath, new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_body_4)), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return sb; } @@ -74,12 +68,14 @@ public class BackupUtils try { return Integer.parseInt(rawValue); - } catch (NumberFormatException e) + } + catch (NumberFormatException e) { - Logger.e(TAG, "Failed to parse max backups count, raw value: " + rawValue + " set to default: " + MAX_BACKUPS_DEFAULT_COUNT, e); - prefs.edit() - .putString(MAX_BACKUPS_KEY, String.valueOf(MAX_BACKUPS_DEFAULT_COUNT)) - .apply(); + Logger.e( + TAG, + "Failed to parse max backups count, raw value: " + rawValue + " set to default: " + MAX_BACKUPS_DEFAULT_COUNT, + e); + prefs.edit().putString(MAX_BACKUPS_KEY, String.valueOf(MAX_BACKUPS_DEFAULT_COUNT)).apply(); return MAX_BACKUPS_DEFAULT_COUNT; } } diff --git a/android/app/src/main/java/app/organicmaps/backup/LocalBackupManager.java b/android/app/src/main/java/app/organicmaps/backup/LocalBackupManager.java index 628b951a7..f1a8cad85 100644 --- a/android/app/src/main/java/app/organicmaps/backup/LocalBackupManager.java +++ b/android/app/src/main/java/app/organicmaps/backup/LocalBackupManager.java @@ -1,30 +1,27 @@ package app.organicmaps.backup; -import static app.organicmaps.backup.BackupUtils.getBackupName; import static app.organicmaps.backup.BackupUtils.getBackupFolders; -import static app.organicmaps.util.StorageUtils.copyFileToDocumentFile; -import static app.organicmaps.util.StorageUtils.deleteDirectoryRecursive; +import static app.organicmaps.backup.BackupUtils.getBackupName; +import static app.organicmaps.sdk.util.StorageUtils.copyFileToDocumentFile; +import static app.organicmaps.sdk.util.StorageUtils.deleteDirectoryRecursive; import android.app.Activity; import android.net.Uri; - import androidx.annotation.NonNull; import androidx.documentfile.provider.DocumentFile; - +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.BookmarkSharingResult; +import app.organicmaps.sdk.bookmarks.data.KmlFileType; +import app.organicmaps.sdk.util.concurrency.ThreadPool; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.sdk.util.log.Logger; import java.io.File; import java.time.LocalDateTime; import java.util.Arrays; import java.util.Comparator; import java.util.List; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.BookmarkSharingResult; -import app.organicmaps.bookmarks.data.KmlFileType; -import app.organicmaps.util.concurrency.ThreadPool; -import app.organicmaps.util.concurrency.UiThread; -import app.organicmaps.util.log.Logger; - public class LocalBackupManager implements BookmarkManager.BookmarksSharingListener { public static final String TAG = LocalBackupManager.class.getSimpleName(); @@ -65,39 +62,39 @@ public class LocalBackupManager implements BookmarkManager.BookmarksSharingListe ErrorCode errorCode = null; switch (result.getCode()) { - case BookmarkSharingResult.SUCCESS -> - { - if (!saveBackup(result)) + case BookmarkSharingResult.SUCCESS -> + { + if (!saveBackup(result)) + { + Logger.e(TAG, "Failed to save backup. See system log above"); + errorCode = ErrorCode.FILE_ERROR; + } + else + { + Logger.i(TAG, "Backup was created and saved successfully"); + } + } + case BookmarkSharingResult.EMPTY_CATEGORY -> + { + errorCode = ErrorCode.EMPTY_CATEGORY; + Logger.e(TAG, "Failed to create backup. Category is empty"); + } + case BookmarkSharingResult.ARCHIVE_ERROR -> + { + errorCode = ErrorCode.ARCHIVE_ERROR; + Logger.e(TAG, "Failed to create archive of bookmarks"); + } + case BookmarkSharingResult.FILE_ERROR -> { - Logger.e(TAG, "Failed to save backup. See system log above"); errorCode = ErrorCode.FILE_ERROR; + Logger.e(TAG, "Failed create file for archive"); } - else + default -> { - Logger.i(TAG, "Backup was created and saved successfully"); + errorCode = ErrorCode.UNSUPPORTED; + Logger.e(TAG, "Failed to create backup. Unknown error"); } } - case BookmarkSharingResult.EMPTY_CATEGORY -> - { - errorCode = ErrorCode.EMPTY_CATEGORY; - Logger.e(TAG, "Failed to create backup. Category is empty"); - } - case BookmarkSharingResult.ARCHIVE_ERROR -> - { - errorCode = ErrorCode.ARCHIVE_ERROR; - Logger.e(TAG, "Failed to create archive of bookmarks"); - } - case BookmarkSharingResult.FILE_ERROR -> - { - errorCode = ErrorCode.FILE_ERROR; - Logger.e(TAG, "Failed create file for archive"); - } - default -> - { - errorCode = ErrorCode.UNSUPPORTED; - Logger.e(TAG, "Failed to create backup. Unknown error"); - } - } ErrorCode finalErrorCode = errorCode; UiThread.run(() -> { @@ -139,8 +136,8 @@ public class LocalBackupManager implements BookmarkManager.BookmarksSharingListe } } cleanOldBackups(parentFolder); - - } catch (Exception e) + } + catch (Exception e) { Logger.e(TAG, "Failed to save backup", e); } diff --git a/android/app/src/main/java/app/organicmaps/backup/PeriodicBackupRunner.java b/android/app/src/main/java/app/organicmaps/backup/PeriodicBackupRunner.java index a2d95198f..05a73c0ba 100644 --- a/android/app/src/main/java/app/organicmaps/backup/PeriodicBackupRunner.java +++ b/android/app/src/main/java/app/organicmaps/backup/PeriodicBackupRunner.java @@ -5,14 +5,11 @@ import static app.organicmaps.backup.BackupUtils.isBackupFolderAvailable; import static app.organicmaps.settings.BackupSettingsFragment.BACKUP_FOLDER_PATH_KEY; import static app.organicmaps.settings.BackupSettingsFragment.BACKUP_INTERVAL_KEY; import static app.organicmaps.settings.BackupSettingsFragment.LAST_BACKUP_TIME_KEY; -import static app.organicmaps.util.StorageUtils.isFolderWritable; import android.app.Activity; import android.content.SharedPreferences; - import androidx.preference.PreferenceManager; - -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.util.log.Logger; public class PeriodicBackupRunner { @@ -68,7 +65,8 @@ public class PeriodicBackupRunner try { return Long.parseLong(prefs.getString(BACKUP_INTERVAL_KEY, defaultValue)); - } catch (NumberFormatException e) + } + catch (NumberFormatException e) { return 0; } @@ -77,8 +75,7 @@ public class PeriodicBackupRunner private void performBackup(String backupFolderPath, int maxBackups) { LocalBackupManager backupManager = new LocalBackupManager(activity, backupFolderPath, maxBackups); - backupManager.setListener(new LocalBackupManager.Listener() - { + backupManager.setListener(new LocalBackupManager.Listener() { @Override public void onBackupStarted() { diff --git a/android/app/src/main/java/app/organicmaps/base/BaseMwmDialogFragment.java b/android/app/src/main/java/app/organicmaps/base/BaseMwmDialogFragment.java index dd6a9f577..0cd943754 100644 --- a/android/app/src/main/java/app/organicmaps/base/BaseMwmDialogFragment.java +++ b/android/app/src/main/java/app/organicmaps/base/BaseMwmDialogFragment.java @@ -3,12 +3,10 @@ package app.organicmaps.base; import android.app.Application; import android.content.Context; import android.os.Bundle; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StyleRes; import androidx.fragment.app.DialogFragment; - import app.organicmaps.R; import app.organicmaps.util.ThemeUtils; @@ -38,7 +36,7 @@ public class BaseMwmDialogFragment extends DialogFragment int style = getStyle(); int theme = getCustomTheme(); if (style != STYLE_NORMAL || theme != 0) - //noinspection WrongConstant + // noinspection WrongConstant setStyle(style, theme); } @@ -62,5 +60,4 @@ public class BaseMwmDialogFragment extends DialogFragment throw new IllegalStateException("Before call this method make sure that the context exists"); return (Application) context.getApplicationContext(); } - } diff --git a/android/app/src/main/java/app/organicmaps/base/BaseMwmFragment.java b/android/app/src/main/java/app/organicmaps/base/BaseMwmFragment.java index 611a2b808..01fec6a08 100644 --- a/android/app/src/main/java/app/organicmaps/base/BaseMwmFragment.java +++ b/android/app/src/main/java/app/organicmaps/base/BaseMwmFragment.java @@ -1,9 +1,7 @@ package app.organicmaps.base; import android.content.Context; - import androidx.fragment.app.Fragment; - import app.organicmaps.util.Utils; public class BaseMwmFragment extends Fragment implements OnBackPressListener @@ -20,5 +18,4 @@ public class BaseMwmFragment extends Fragment implements OnBackPressListener { return false; } - } diff --git a/android/app/src/main/java/app/organicmaps/base/BaseMwmFragmentActivity.java b/android/app/src/main/java/app/organicmaps/base/BaseMwmFragmentActivity.java index 8073bf27f..4b72a84f0 100644 --- a/android/app/src/main/java/app/organicmaps/base/BaseMwmFragmentActivity.java +++ b/android/app/src/main/java/app/organicmaps/base/BaseMwmFragmentActivity.java @@ -7,7 +7,6 @@ import android.graphics.Color; import android.media.AudioManager; import android.os.Bundle; import android.view.MenuItem; - import androidx.activity.EdgeToEdge; import androidx.activity.SystemBarStyle; import androidx.annotation.CallSuper; @@ -18,18 +17,15 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentFactory; import androidx.fragment.app.FragmentManager; - -import com.google.android.material.appbar.MaterialToolbar; - import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.SplashActivity; -import app.organicmaps.util.Config; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.util.RtlUtils; import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.concurrency.UiThread; -import app.organicmaps.util.log.Logger; - +import com.google.android.material.appbar.MaterialToolbar; import java.util.Objects; public abstract class BaseMwmFragmentActivity extends AppCompatActivity @@ -47,7 +43,7 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity Context context = getApplicationContext(); if (ThemeUtils.isDefaultTheme(context, theme)) - return R.style.MwmTheme; + return R.style.MwmTheme; if (ThemeUtils.isNightTheme(context, theme)) return R.style.MwmTheme_Night; @@ -216,11 +212,13 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity /** * Replace attached fragment with the new one. */ - public void replaceFragment(@NonNull Class fragmentClass, @Nullable Bundle args, @Nullable Runnable completionListener) + public void replaceFragment(@NonNull Class fragmentClass, @Nullable Bundle args, + @Nullable Runnable completionListener) { final int resId = getFragmentContentResId(); if (resId <= 0 || findViewById(resId) == null) - throw new IllegalStateException("Fragment can't be added, since getFragmentContentResId() isn't implemented or returns wrong resourceId."); + throw new IllegalStateException( + "Fragment can't be added, since getFragmentContentResId() isn't implemented or returns wrong resourceId."); String name = fragmentClass.getName(); Fragment potentialInstance = getSupportFragmentManager().findFragmentByTag(name); @@ -230,9 +228,7 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity final FragmentFactory factory = manager.getFragmentFactory(); final Fragment fragment = factory.instantiate(getClassLoader(), name); fragment.setArguments(args); - manager.beginTransaction() - .replace(resId, fragment, name) - .commitAllowingStateLoss(); + manager.beginTransaction().replace(resId, fragment, name).commitAllowingStateLoss(); manager.executePendingTransactions(); if (completionListener != null) completionListener.run(); @@ -240,8 +236,8 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity } /** - * Override to automatically attach fragment in onCreate. Tag applied to fragment in back stack is set to fragment name, too. - * WARNING : if custom layout for activity is set, getFragmentContentResId() must be implemented, too. + * Override to automatically attach fragment in onCreate. Tag applied to fragment in back stack is set to fragment + * name, too. WARNING : if custom layout for activity is set, getFragmentContentResId() must be implemented, too. * @return class of the fragment, eg FragmentClass.getClass() */ protected Class getFragmentClass() diff --git a/android/app/src/main/java/app/organicmaps/base/BaseMwmRecyclerFragment.java b/android/app/src/main/java/app/organicmaps/base/BaseMwmRecyclerFragment.java index 1de268d25..18d821455 100644 --- a/android/app/src/main/java/app/organicmaps/base/BaseMwmRecyclerFragment.java +++ b/android/app/src/main/java/app/organicmaps/base/BaseMwmRecyclerFragment.java @@ -5,7 +5,6 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.CallSuper; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; @@ -14,14 +13,12 @@ import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.MaterialToolbar; - import app.organicmaps.R; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Utils; import app.organicmaps.util.WindowInsetUtils.ScrollableContentInsetsListener; import app.organicmaps.widget.PlaceholderView; +import com.google.android.material.appbar.MaterialToolbar; public abstract class BaseMwmRecyclerFragment extends Fragment { @@ -39,8 +36,7 @@ public abstract class BaseMwmRecyclerFragment ex private T mAdapter; @NonNull - private final View.OnClickListener mNavigationClickListener - = view -> Utils.navigateToParent(requireActivity()); + private final View.OnClickListener mNavigationClickListener = view -> Utils.navigateToParent(requireActivity()); @NonNull protected abstract T createAdapter(); diff --git a/android/app/src/main/java/app/organicmaps/base/BaseMwmToolbarFragment.java b/android/app/src/main/java/app/organicmaps/base/BaseMwmToolbarFragment.java index cca372358..0fb70cc66 100644 --- a/android/app/src/main/java/app/organicmaps/base/BaseMwmToolbarFragment.java +++ b/android/app/src/main/java/app/organicmaps/base/BaseMwmToolbarFragment.java @@ -2,10 +2,8 @@ package app.organicmaps.base; import android.os.Bundle; import android.view.View; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.widget.ToolbarController; public class BaseMwmToolbarFragment extends BaseMwmFragment diff --git a/android/app/src/main/java/app/organicmaps/base/BaseToolbarActivity.java b/android/app/src/main/java/app/organicmaps/base/BaseToolbarActivity.java index 320690b13..11d56fe76 100644 --- a/android/app/src/main/java/app/organicmaps/base/BaseToolbarActivity.java +++ b/android/app/src/main/java/app/organicmaps/base/BaseToolbarActivity.java @@ -1,7 +1,6 @@ package app.organicmaps.base; import android.os.Bundle; - import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -10,12 +9,10 @@ import androidx.core.view.ViewCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentFactory; import androidx.fragment.app.FragmentManager; - -import com.google.android.material.appbar.MaterialToolbar; - import app.organicmaps.R; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener; +import com.google.android.material.appbar.MaterialToolbar; public abstract class BaseToolbarActivity extends BaseMwmFragmentActivity { @@ -73,23 +70,20 @@ public abstract class BaseToolbarActivity extends BaseMwmFragmentActivity return R.id.fragment_container; } - public Fragment stackFragment(@NonNull Class fragmentClass, - @Nullable String title, @Nullable Bundle args) + public Fragment stackFragment(@NonNull Class fragmentClass, @Nullable String title, + @Nullable Bundle args) { final int resId = getFragmentContentResId(); if (resId <= 0 || findViewById(resId) == null) - throw new IllegalStateException("Fragment can't be added, since getFragmentContentResId() " + - "isn't implemented or returns wrong resourceId."); + throw new IllegalStateException("Fragment can't be added, since getFragmentContentResId() " + + "isn't implemented or returns wrong resourceId."); String name = fragmentClass.getName(); final FragmentManager manager = getSupportFragmentManager(); final FragmentFactory factory = manager.getFragmentFactory(); final Fragment fragment = factory.instantiate(getClassLoader(), name); fragment.setArguments(args); - manager.beginTransaction() - .replace(resId, fragment, name) - .addToBackStack(null) - .commitAllowingStateLoss(); + manager.beginTransaction().replace(resId, fragment, name).addToBackStack(null).commitAllowingStateLoss(); manager.executePendingTransactions(); if (title != null) diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/BaseBookmarkCategoryAdapter.java b/android/app/src/main/java/app/organicmaps/bookmarks/BaseBookmarkCategoryAdapter.java index 2b45a429f..0018fe3df 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/BaseBookmarkCategoryAdapter.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/BaseBookmarkCategoryAdapter.java @@ -1,16 +1,12 @@ package app.organicmaps.bookmarks; import android.content.Context; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - -import app.organicmaps.bookmarks.data.BookmarkCategory; - +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; import java.util.List; -public abstract class BaseBookmarkCategoryAdapter - extends RecyclerView.Adapter +public abstract class BaseBookmarkCategoryAdapter extends RecyclerView.Adapter { @NonNull private final Context mContext; @@ -54,6 +50,5 @@ public abstract class BaseBookmarkCategoryAdapter categories.size() - 1) throw new ArrayIndexOutOfBoundsException(position); return categories.get(position); - } } diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategoriesActivity.java b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategoriesActivity.java index a15a30f1b..ea54ae664 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategoriesActivity.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategoriesActivity.java @@ -3,17 +3,15 @@ package app.organicmaps.bookmarks; import android.app.Activity; import android.content.Intent; import android.os.Bundle; - import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StyleRes; import androidx.fragment.app.Fragment; - import app.organicmaps.R; import app.organicmaps.base.BaseToolbarActivity; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; import app.organicmaps.util.ThemeUtils; public class BookmarkCategoriesActivity extends BaseToolbarActivity diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategoriesAdapter.java b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategoriesAdapter.java index 2495b9ed6..cd9fa68db 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategoriesAdapter.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategoriesAdapter.java @@ -7,16 +7,13 @@ import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; - import app.organicmaps.R; import app.organicmaps.adapter.OnItemClickListener; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkManager; - +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; import java.util.List; public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter @@ -122,8 +119,7 @@ public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter { HeaderViewHolder headerViewHolder = (HeaderViewHolder) holder; - headerViewHolder.setAction(mMassOperationAction, - BookmarkManager.INSTANCE.areAllCategoriesInvisible()); + headerViewHolder.setAction(mMassOperationAction, BookmarkManager.INSTANCE.areAllCategoriesInvisible()); headerViewHolder.getText().setText(R.string.bookmark_lists); } case TYPE_CATEGORY_ITEM -> @@ -191,7 +187,6 @@ public class BookmarkCategoriesAdapter extends BaseBookmarkCategoryAdapter - implements BookmarkManager.BookmarksLoadingListener, - CategoryListCallback, - OnItemClickListener, - OnItemMoreClickListener, - OnItemLongClickListener, - BookmarkManager.BookmarksSharingListener, - MenuBottomSheetFragment.MenuBottomSheetInterface + implements BookmarkManager.BookmarksLoadingListener, CategoryListCallback, OnItemClickListener, + OnItemMoreClickListener, OnItemLongClickListener, + BookmarkManager.BookmarksSharingListener, MenuBottomSheetFragment.MenuBottomSheetInterface { private static final String TAG = BookmarkCategoriesFragment.class.getSimpleName(); @@ -75,21 +68,24 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment startBookmarkListForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { - if( activityResult.getResultCode() == Activity.RESULT_OK) - onDeleteActionSelected(getSelectedCategory()); - }); + private final ActivityResultLauncher startBookmarkListForResult = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { + if (activityResult.getResultCode() == Activity.RESULT_OK) + onDeleteActionSelected(getSelectedCategory()); + }); - private final ActivityResultLauncher startImportDirectoryForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> - { - if( activityResult.getResultCode() == Activity.RESULT_OK) - onImportDirectoryResult(activityResult.getData()); - }); - - private final ActivityResultLauncher startBookmarkSettingsForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { - // not handled at the moment - }); + private final ActivityResultLauncher startImportDirectoryForResult = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { + if (activityResult.getResultCode() == Activity.RESULT_OK) + onImportDirectoryResult(activityResult.getData()); + }); + private final ActivityResultLauncher startBookmarkSettingsForResult = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), + activityResult + -> { + // not handled at the moment + }); @Override @LayoutRes @@ -119,7 +115,8 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment items = new ArrayList<>(); if (mSelectedCategory != null) { - items.add(new MenuBottomSheetItem( - R.string.edit, - R.drawable.ic_settings, - () -> onSettingsActionSelected(mSelectedCategory))); - items.add(new MenuBottomSheetItem( - mSelectedCategory.isVisible() ? R.string.hide : R.string.show, - mSelectedCategory.isVisible() ? R.drawable.ic_hide : R.drawable.ic_show, - () -> onShowActionSelected(mSelectedCategory))); - items.add(new MenuBottomSheetItem( - R.string.export_file, - R.drawable.ic_file_kmz, - () -> onShareActionSelected(mSelectedCategory, KmlFileType.Text))); - items.add(new MenuBottomSheetItem( - R.string.export_file_gpx, - R.drawable.ic_file_gpx, - () -> onShareActionSelected(mSelectedCategory, KmlFileType.Gpx))); + items.add(new MenuBottomSheetItem(R.string.edit, R.drawable.ic_settings, + () -> onSettingsActionSelected(mSelectedCategory))); + items.add(new MenuBottomSheetItem(mSelectedCategory.isVisible() ? R.string.hide : R.string.show, + mSelectedCategory.isVisible() ? R.drawable.ic_hide : R.drawable.ic_show, + () -> onShowActionSelected(mSelectedCategory))); + items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz, + () -> onShareActionSelected(mSelectedCategory, KmlFileType.Text))); + items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx, + () -> onShareActionSelected(mSelectedCategory, KmlFileType.Gpx))); // Disallow deleting the last category if (getAdapter().getBookmarkCategories().size() > 1) - items.add(new MenuBottomSheetItem( - R.string.delete, - R.drawable.ic_delete, - () -> onDeleteActionSelected(mSelectedCategory))); + items.add(new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete, + () -> onDeleteActionSelected(mSelectedCategory))); } return items; } @@ -245,15 +233,10 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment dialog.dismiss()) @@ -341,17 +325,16 @@ public class BookmarkCategoriesFragment extends BaseMwmRecyclerFragment { AtomicInteger found = new AtomicInteger(0); - StorageUtils.listContentProviderFilesRecursively( - resolver, rootUri, uri -> { - if (BookmarkManager.INSTANCE.importBookmarksFile(resolver, uri, tempDir)) - found.incrementAndGet(); - }); + StorageUtils.listContentProviderFilesRecursively(resolver, rootUri, uri -> { + if (BookmarkManager.INSTANCE.importBookmarksFile(resolver, uri, tempDir)) + found.incrementAndGet(); + }); UiThread.run(() -> { if (dialog.isShowing()) dialog.dismiss(); int found_val = found.get(); - String message = context.getResources().getQuantityString( - R.plurals.bookmarks_detect_message, found_val, found_val); + String message = + context.getResources().getQuantityString(R.plurals.bookmarks_detect_message, found_val, found_val); Toast.makeText(requireContext(), message, Toast.LENGTH_LONG).show(); }); }); diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategorySettingsActivity.java b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategorySettingsActivity.java index e96c65bdc..e5c4c2774 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategorySettingsActivity.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategorySettingsActivity.java @@ -1,14 +1,12 @@ package app.organicmaps.bookmarks; import android.content.Intent; - import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmFragmentActivity; -import app.organicmaps.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; public class BookmarkCategorySettingsActivity extends BaseMwmFragmentActivity { @@ -32,11 +30,12 @@ public class BookmarkCategorySettingsActivity extends BaseMwmFragmentActivity return BookmarkCategorySettingsFragment.class; } - public static void startForResult(@NonNull Fragment fragment, ActivityResultLauncher startBookmarkSettingsForResult, - @NonNull BookmarkCategory category) + public static void startForResult(@NonNull Fragment fragment, + ActivityResultLauncher startBookmarkSettingsForResult, + @NonNull BookmarkCategory category) { android.content.Intent intent = new Intent(fragment.requireActivity(), BookmarkCategorySettingsActivity.class) - .putExtra(EXTRA_BOOKMARK_CATEGORY, category); + .putExtra(EXTRA_BOOKMARK_CATEGORY, category); startBookmarkSettingsForResult.launch(intent); } } diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategorySettingsFragment.java b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategorySettingsFragment.java index 65fd18b25..cc5476b3e 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategorySettingsFragment.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCategorySettingsFragment.java @@ -11,21 +11,17 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmToolbarFragment; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.util.Utils; - +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; import app.organicmaps.util.InputUtils; +import app.organicmaps.util.Utils; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputLayout; - import java.util.Objects; public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment @@ -49,14 +45,13 @@ public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment { super.onCreate(savedInstanceState); final Bundle args = requireArguments(); - mCategory = Objects.requireNonNull(Utils.getParcelable(args, - BookmarkCategorySettingsActivity.EXTRA_BOOKMARK_CATEGORY, BookmarkCategory.class)); + mCategory = Objects.requireNonNull( + Utils.getParcelable(args, BookmarkCategorySettingsActivity.EXTRA_BOOKMARK_CATEGORY, BookmarkCategory.class)); } @Nullable @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_bookmark_category_settings, container, false); setHasOptionsMenu(true); @@ -70,13 +65,13 @@ public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment TextInputLayout clearNameBtn = root.findViewById(R.id.edit_list_name_input); clearNameBtn.setEndIconOnClickListener(v -> clearAndFocus(mEditCategoryNameView)); mEditCategoryNameView.setText(mCategory.getName()); - InputFilter[] f = { new InputFilter.LengthFilter(TEXT_LENGTH_LIMIT) }; + InputFilter[] f = {new InputFilter.LengthFilter(TEXT_LENGTH_LIMIT)}; mEditCategoryNameView.setFilters(f); mEditCategoryNameView.requestFocus(); - mEditCategoryNameView.addTextChangedListener(new TextWatcher() - { + mEditCategoryNameView.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) + {} @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) @@ -85,7 +80,8 @@ public class BookmarkCategorySettingsFragment extends BaseMwmToolbarFragment } @Override - public void afterTextChanged(Editable editable) {} + public void afterTextChanged(Editable editable) + {} }); mEditDescView = root.findViewById(R.id.edit_description); mEditDescView.setText(mCategory.getDescription()); diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCollectionAdapter.java b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCollectionAdapter.java index 3d3749939..f33d48898 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCollectionAdapter.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkCollectionAdapter.java @@ -3,18 +3,15 @@ package app.organicmaps.bookmarks; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; - import app.organicmaps.R; import app.organicmaps.adapter.OnItemClickListener; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.util.UiUtils; - +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.util.UiUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; @@ -22,8 +19,9 @@ import java.util.List; public class BookmarkCollectionAdapter extends RecyclerView.Adapter { @Retention(RetentionPolicy.SOURCE) - @IntDef({ TYPE_HEADER_ITEM, TYPE_CATEGORY_ITEM }) - public @interface SectionType { } + @IntDef({TYPE_HEADER_ITEM, TYPE_CATEGORY_ITEM}) + public @interface SectionType + {} private final static int TYPE_CATEGORY_ITEM = BookmarkManager.CATEGORY; private final static int TYPE_HEADER_ITEM = 3; @@ -63,11 +61,10 @@ public class BookmarkCollectionAdapter extends RecyclerView.Adapter itemsCategories) + BookmarkCollectionAdapter(@NonNull BookmarkCategory bookmarkCategory, @NonNull List itemsCategories) { mBookmarkCategory = bookmarkCategory; - //noinspection AssignmentOrReturnOfFieldWithMutableType + // noinspection AssignmentOrReturnOfFieldWithMutableType mItemsCategory = itemsCategories; mSectionCount = 0; @@ -93,7 +90,7 @@ public class BookmarkCollectionAdapter extends RecyclerView.Adapter getItemsListByType(@SectionType int type) { - return mItemsCategory; + return mItemsCategory; } @NonNull @@ -129,18 +126,15 @@ public class BookmarkCollectionAdapter extends RecyclerView.Adapter startBookmarkListForResult, @NonNull BookmarkCategory category) + static void startForResult(@NonNull Fragment fragment, ActivityResultLauncher startBookmarkListForResult, + @NonNull BookmarkCategory category) { Bundle args = new Bundle(); Intent intent = new Intent(fragment.requireActivity(), BookmarkListActivity.class); diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkListAdapter.java b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkListAdapter.java index 0fa81c1f3..76a73c529 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkListAdapter.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarkListAdapter.java @@ -4,23 +4,19 @@ import android.content.res.Resources; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.textview.MaterialTextView; - import app.organicmaps.R; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkInfo; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.IconClickListener; -import app.organicmaps.bookmarks.data.SortedBlock; -import app.organicmaps.content.DataSource; +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkInfo; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.IconClickListener; +import app.organicmaps.sdk.bookmarks.data.SortedBlock; +import app.organicmaps.sdk.content.DataSource; import app.organicmaps.widget.recycler.RecyclerClickListener; import app.organicmaps.widget.recycler.RecyclerLongClickListener; - +import com.google.android.material.textview.MaterialTextView; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -62,12 +58,14 @@ public class BookmarkListAdapter extends RecyclerView.Adapter mSearchResults; - SearchResultsSectionsDataSource(@NonNull DataSource dataSource, - @NonNull List searchResults) + SearchResultsSectionsDataSource(@NonNull DataSource dataSource, @NonNull List searchResults) { super(dataSource); mSearchResults = searchResults; } @Override - public int getSectionsCount() { return 1; } + public int getSectionsCount() + { + return 1; + } @Override - public boolean isEditable(int sectionIndex) { return true; } + public boolean isEditable(int sectionIndex) + { + return true; + } @Override - public boolean hasTitle(int sectionIndex) { return false; } + public boolean hasTitle(int sectionIndex) + { + return false; + } @Nullable - public String getTitle(int sectionIndex, @NonNull Resources rs) { return null; } + public String getTitle(int sectionIndex, @NonNull Resources rs) + { + return null; + } @Override - public int getItemsCount(int sectionIndex) { return mSearchResults.size(); } + public int getItemsCount(int sectionIndex) + { + return mSearchResults.size(); + } @Override - public int getItemsType(int sectionIndex) { return TYPE_BOOKMARK; } + public int getItemsType(int sectionIndex) + { + return TYPE_BOOKMARK; + } @Override public void onDelete(@NonNull SectionPosition pos) @@ -238,8 +257,7 @@ public class BookmarkListAdapter extends RecyclerView.Adapter mSortedBlocks; - SortedSectionsDataSource(@NonNull DataSource dataSource, - @NonNull List sortedBlocks) + SortedSectionsDataSource(@NonNull DataSource dataSource, @NonNull List sortedBlocks) { super(dataSource); mSortedBlocks = sortedBlocks; @@ -272,7 +290,10 @@ public class BookmarkListAdapter extends RecyclerView.Adapter - implements BookmarkManager.BookmarksSharingListener, - BookmarkManager.BookmarksSortingListener, - BookmarkManager.BookmarksLoadingListener, - BookmarkSearchListener, + implements BookmarkManager.BookmarksSharingListener, BookmarkManager.BookmarksSortingListener, + BookmarkManager.BookmarksLoadingListener, BookmarkSearchListener, ChooseBookmarksSortingTypeFragment.ChooseSortingTypeListener, MenuBottomSheetFragment.MenuBottomSheetInterface { @@ -75,15 +71,17 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment shareLauncher; - private final ActivityResultLauncher startBookmarkListForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { - System.out.println("resultCode: " + activityResult.getResultCode()); - handleActivityResult(); - }); + private final ActivityResultLauncher startBookmarkListForResult = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { + System.out.println("resultCode: " + activityResult.getResultCode()); + handleActivityResult(); + }); - private final ActivityResultLauncher startBookmarkSettingsForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { - System.out.println("resultCode: " + activityResult.getResultCode()); - handleActivityResult(); - }); + private final ActivityResultLauncher startBookmarkSettingsForResult = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { + System.out.println("resultCode: " + activityResult.getResultCode()); + handleActivityResult(); + }); @SuppressWarnings("NotNullFieldNotInitialized") @NonNull @@ -104,8 +102,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment mCategoryItems = BookmarkManager.INSTANCE.getChildrenCategories(categoryId); - BookmarkCollectionAdapter adapter = new BookmarkCollectionAdapter(getCategoryOrThrow(), - mCategoryItems); - adapter.setOnClickListener((v, item) -> { - BookmarkListActivity.startForResult(this, startBookmarkListForResult, item); - }); + BookmarkCollectionAdapter adapter = new BookmarkCollectionAdapter(getCategoryOrThrow(), mCategoryItems); + adapter.setOnClickListener( + (v, item) -> BookmarkListActivity.startForResult(this, startBookmarkListForResult, item)); return adapter; } @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_bookmark_list, container, false); } @@ -204,8 +198,7 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment - { + mFabViewOnMap.setOnClickListener(v -> { final Intent i = makeMwmActivityIntent(); i.putExtra(MwmActivity.EXTRA_CATEGORY_ID, mCategoryDataSource.getData().getId()); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); @@ -290,13 +282,11 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment - { - if (movedFromCategory) - resetSearchAndSort(); - else - adapter.notifyDataSetChanged(); - }); + EditBookmarkFragment.editBookmark(info.getCategoryId(), info.getBookmarkId(), requireActivity(), + getChildFragmentManager(), (bookmarkId, movedFromCategory) -> { + if (movedFromCategory) + resetSearchAndSort(); + else + adapter.notifyDataSetChanged(); + }); } private void onTrackEditActionSelected() { Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition); - EditBookmarkFragment.editTrack( - track.getCategoryId(), track.getTrackId(), requireActivity(), getChildFragmentManager(), - (trackId, movedFromCategory) -> - { - if (movedFromCategory) - resetSearchAndSort(); - else - getBookmarkListAdapter().notifyDataSetChanged(); - }); + EditBookmarkFragment.editTrack(track.getCategoryId(), track.getTrackId(), requireActivity(), + getChildFragmentManager(), (trackId, movedFromCategory) -> { + if (movedFromCategory) + resetSearchAndSort(); + else + getBookmarkListAdapter().notifyDataSetChanged(); + }); } private void onDeleteActionSelected() @@ -756,8 +735,8 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment getOptionsMenuItems() { - @BookmarkManager.SortingType int[] types = getAvailableSortingTypes(); + @BookmarkManager.SortingType + int[] types = getAvailableSortingTypes(); ArrayList items = new ArrayList<>(); if (!isEmpty()) { if (types.length > 0) items.add(new MenuBottomSheetItem(R.string.sort, R.drawable.ic_sort, this::onSortOptionSelected)); - items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz, () -> onShareOptionSelected(KmlFileType.Text))); - items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx, () -> onShareOptionSelected(KmlFileType.Gpx))); + items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz, + () -> onShareOptionSelected(KmlFileType.Text))); + items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx, + () -> onShareOptionSelected(KmlFileType.Gpx))); } items.add(new MenuBottomSheetItem(R.string.edit, R.drawable.ic_settings, this::onSettingsOptionSelected)); if (!isLastOwnedCategory()) @@ -807,9 +790,12 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment items = new ArrayList<>(); items.add(new MenuBottomSheetItem(R.string.edit, R.drawable.ic_edit, this::onTrackEditActionSelected)); - items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz, () -> onShareTrackSelected(track.getTrackId(), KmlFileType.Text))); - items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx, () -> onShareTrackSelected(track.getTrackId(), KmlFileType.Gpx))); - items.add(new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete, () -> onDeleteTrackSelected(track.getTrackId()))); + items.add(new MenuBottomSheetItem(R.string.export_file, R.drawable.ic_file_kmz, + () -> onShareTrackSelected(track.getTrackId(), KmlFileType.Text))); + items.add(new MenuBottomSheetItem(R.string.export_file_gpx, R.drawable.ic_file_gpx, + () -> onShareTrackSelected(track.getTrackId(), KmlFileType.Gpx))); + items.add(new MenuBottomSheetItem(R.string.delete, R.drawable.ic_delete, + () -> onDeleteTrackSelected(track.getTrackId()))); return items; } @@ -855,15 +841,22 @@ public class BookmarksListFragment extends BaseMwmRecyclerFragment getMenuBottomSheetItems(String id) { - if (id.equals(BOOKMARKS_MENU_ID)) - return getBookmarkMenuItems(); - if (id.equals(TRACK_MENU_ID)) + switch (id) { - final Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition); - return getTrackMenuItems(track); + case BOOKMARKS_MENU_ID -> + { + return getBookmarkMenuItems(); + } + case TRACK_MENU_ID -> + { + final Track track = (Track) getBookmarkListAdapter().getItem(mSelectedPosition); + return getTrackMenuItems(track); + } + case OPTIONS_MENU_ID -> + { + return getOptionsMenuItems(); + } } - if (id.equals(OPTIONS_MENU_ID)) - return getOptionsMenuItems(); return null; } } diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarksSharingHelper.java b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarksSharingHelper.java index 26e9b0341..33ae76970 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarksSharingHelper.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarksSharingHelper.java @@ -2,25 +2,21 @@ package app.organicmaps.bookmarks; import android.app.Activity; import android.app.ProgressDialog; - import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; - import app.organicmaps.R; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.BookmarkSharingResult; -import app.organicmaps.bookmarks.data.KmlFileType; +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.BookmarkSharingResult; +import app.organicmaps.sdk.bookmarks.data.KmlFileType; +import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.util.SharingUtils; -import app.organicmaps.util.log.Logger; import com.google.android.material.dialog.MaterialAlertDialogBuilder; - import java.util.ArrayList; import java.util.List; - public enum BookmarksSharingHelper { INSTANCE; @@ -33,7 +29,7 @@ public enum BookmarksSharingHelper public void prepareBookmarkCategoryForSharing(@NonNull Activity context, long catId, KmlFileType kmlFileType) { showProgressDialog(context); - BookmarkManager.INSTANCE.prepareCategoriesForSharing(new long[]{catId}, kmlFileType); + BookmarkManager.INSTANCE.prepareCategoriesForSharing(new long[] {catId}, kmlFileType); } public void prepareTrackForSharing(@NonNull Activity context, long trackId, KmlFileType kmlFileType) @@ -62,13 +58,13 @@ public enum BookmarksSharingHelper switch (result.getCode()) { case BookmarkSharingResult.SUCCESS -> - SharingUtils.shareBookmarkFile(context, launcher, result.getSharingPath(), result.getMimeType()); + SharingUtils.shareBookmarkFile(context, launcher, result.getSharingPath(), result.getMimeType()); case BookmarkSharingResult.EMPTY_CATEGORY -> - new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.bookmarks_error_title_share_empty) - .setMessage(R.string.bookmarks_error_message_share_empty) - .setPositiveButton(R.string.ok, null) - .show(); + new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog) + .setTitle(R.string.bookmarks_error_title_share_empty) + .setMessage(R.string.bookmarks_error_message_share_empty) + .setPositiveButton(R.string.ok, null) + .show(); case BookmarkSharingResult.ARCHIVE_ERROR, BookmarkSharingResult.FILE_ERROR -> { new MaterialAlertDialogBuilder(context, R.style.MwmTheme_AlertDialog) diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarksToolbarController.java b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarksToolbarController.java index 4f54551a0..f8d99eae0 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/BookmarksToolbarController.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/BookmarksToolbarController.java @@ -2,9 +2,7 @@ package app.organicmaps.bookmarks; import android.app.Activity; import android.view.View; - import androidx.annotation.NonNull; - import app.organicmaps.widget.SearchToolbarController; public class BookmarksToolbarController extends SearchToolbarController @@ -12,8 +10,7 @@ public class BookmarksToolbarController extends SearchToolbarController @NonNull private final BookmarksListFragment mFragment; - BookmarksToolbarController(@NonNull View root, @NonNull Activity activity, - @NonNull BookmarksListFragment fragment) + BookmarksToolbarController(@NonNull View root, @NonNull Activity activity, @NonNull BookmarksListFragment fragment) { super(root, activity); mFragment = fragment; diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/CategoryValidator.java b/android/app/src/main/java/app/organicmaps/bookmarks/CategoryValidator.java index 37c1ec598..311bf4b8a 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/CategoryValidator.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/CategoryValidator.java @@ -2,13 +2,11 @@ package app.organicmaps.bookmarks; import android.app.Activity; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.R; -import app.organicmaps.bookmarks.data.BookmarkManager; import app.organicmaps.dialog.EditTextDialogFragment; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; class CategoryValidator implements EditTextDialogFragment.Validator { diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarkCategoryAdapter.java b/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarkCategoryAdapter.java index 5266c7dae..1e05a1b76 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarkCategoryAdapter.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarkCategoryAdapter.java @@ -4,19 +4,16 @@ import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - +import app.organicmaps.R; +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; import com.google.android.material.radiobutton.MaterialRadioButton; import com.google.android.material.textview.MaterialTextView; - -import app.organicmaps.R; -import app.organicmaps.bookmarks.data.BookmarkCategory; - import java.util.List; -public class ChooseBookmarkCategoryAdapter extends BaseBookmarkCategoryAdapter +public class ChooseBookmarkCategoryAdapter + extends BaseBookmarkCategoryAdapter { public static final int VIEW_TYPE_CATEGORY = 0; public static final int VIEW_TYPE_ADD_NEW = 1; @@ -32,8 +29,7 @@ public class ChooseBookmarkCategoryAdapter extends BaseBookmarkCategoryAdapter categories) + public ChooseBookmarkCategoryAdapter(Context context, int pos, @NonNull List categories) { super(context, categories); mCheckedPosition = pos; diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarkCategoryFragment.java b/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarkCategoryFragment.java index 6b7d40d3a..4f421d90d 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarkCategoryFragment.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarkCategoryFragment.java @@ -5,23 +5,20 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmDialogFragment; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkManager; import app.organicmaps.dialog.EditTextDialogFragment; - +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; import java.util.List; -public class ChooseBookmarkCategoryFragment extends BaseMwmDialogFragment - implements ChooseBookmarkCategoryAdapter.CategoryListener +public class ChooseBookmarkCategoryFragment + extends BaseMwmDialogFragment implements ChooseBookmarkCategoryAdapter.CategoryListener { public static final String CATEGORY_POSITION = "ExtraCategoryPosition"; @@ -126,13 +123,8 @@ public class ChooseBookmarkCategoryFragment extends BaseMwmDialogFragment @Override public void onCategoryCreate() { - EditTextDialogFragment dialogFragment = - EditTextDialogFragment.show(getString(R.string.bookmark_set_name), - null, - getString(R.string.ok), - null, - this, - new CategoryValidator()); + EditTextDialogFragment dialogFragment = EditTextDialogFragment.show( + getString(R.string.bookmark_set_name), null, getString(R.string.ok), null, this, new CategoryValidator()); dialogFragment.setTextSaveListener(this::createCategory); } } diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarksSortingTypeFragment.java b/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarksSortingTypeFragment.java index 2a74f80ae..16c520d59 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarksSortingTypeFragment.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/ChooseBookmarksSortingTypeFragment.java @@ -6,19 +6,17 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RadioGroup; - import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.FragmentManager; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmDialogFragment; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.util.UiUtils; -public class ChooseBookmarksSortingTypeFragment extends BaseMwmDialogFragment - implements RadioGroup.OnCheckedChangeListener +public class ChooseBookmarksSortingTypeFragment + extends BaseMwmDialogFragment implements RadioGroup.OnCheckedChangeListener { private static final String EXTRA_SORTING_TYPES = "sorting_types"; private static final String EXTRA_CURRENT_SORT_TYPE = "current_sort_type"; @@ -32,17 +30,15 @@ public class ChooseBookmarksSortingTypeFragment extends BaseMwmDialogFragment void onSort(@BookmarkManager.SortingType int sortingType); } - public static void chooseSortingType(@NonNull @BookmarkManager.SortingType int[] availableTypes, - int currentType, @NonNull Context context, - @NonNull FragmentManager manager) + public static void chooseSortingType(@NonNull @BookmarkManager.SortingType int[] availableTypes, int currentType, + @NonNull Context context, @NonNull FragmentManager manager) { Bundle args = new Bundle(); args.putIntArray(EXTRA_SORTING_TYPES, availableTypes); args.putInt(EXTRA_CURRENT_SORT_TYPE, currentType); String name = ChooseBookmarksSortingTypeFragment.class.getName(); - final ChooseBookmarksSortingTypeFragment fragment = (ChooseBookmarksSortingTypeFragment) manager - .getFragmentFactory() - .instantiate(context.getClassLoader(), name); + final ChooseBookmarksSortingTypeFragment fragment = + (ChooseBookmarksSortingTypeFragment) manager.getFragmentFactory().instantiate(context.getClassLoader(), name); fragment.setArguments(args); fragment.show(manager, name); } @@ -68,14 +64,10 @@ public class ChooseBookmarksSortingTypeFragment extends BaseMwmDialogFragment { switch (sortingType) { - case BookmarkManager.SORT_BY_TYPE: - return R.id.sort_by_type; - case BookmarkManager.SORT_BY_DISTANCE: - return R.id.sort_by_distance; - case BookmarkManager.SORT_BY_TIME: - return R.id.sort_by_time; - case BookmarkManager.SORT_BY_NAME: - return R.id.sort_by_name; + case BookmarkManager.SORT_BY_TYPE: return R.id.sort_by_type; + case BookmarkManager.SORT_BY_DISTANCE: return R.id.sort_by_distance; + case BookmarkManager.SORT_BY_TIME: return R.id.sort_by_time; + case BookmarkManager.SORT_BY_NAME: return R.id.sort_by_name; } } return R.id.sort_by_default; @@ -117,8 +109,7 @@ public class ChooseBookmarksSortingTypeFragment extends BaseMwmDialogFragment private void onAttachInternal() { - mListener = (ChooseSortingTypeListener) (getParentFragment() == null ? getTargetFragment() - : getParentFragment()); + mListener = (ChooseSortingTypeListener) (getParentFragment() == null ? getTargetFragment() : getParentFragment()); } @Override diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/Holders.java b/android/app/src/main/java/app/organicmaps/bookmarks/Holders.java index aef4e3fd7..16b494b1a 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/Holders.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/Holders.java @@ -6,29 +6,26 @@ import android.location.Location; import android.text.Spanned; import android.text.TextUtils; import android.view.View; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.PluralsRes; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.imageview.ShapeableImageView; -import com.google.android.material.textview.MaterialTextView; -import com.google.android.material.checkbox.MaterialCheckBox; - +import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.adapter.OnItemClickListener; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkInfo; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.IconClickListener; -import app.organicmaps.bookmarks.data.Track; -import app.organicmaps.location.LocationHelper; +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkInfo; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.IconClickListener; +import app.organicmaps.sdk.bookmarks.data.Track; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.util.Graphics; import app.organicmaps.util.Utils; import app.organicmaps.widget.recycler.RecyclerClickListener; import app.organicmaps.widget.recycler.RecyclerLongClickListener; -import app.organicmaps.util.Graphics; -import app.organicmaps.util.UiUtils; +import com.google.android.material.checkbox.MaterialCheckBox; +import com.google.android.material.imageview.ShapeableImageView; +import com.google.android.material.textview.MaterialTextView; public class Holders { @@ -66,7 +63,6 @@ public class Holders @NonNull private final MaterialTextView mText; - HeaderViewHolder(@NonNull View itemView) { super(itemView); @@ -86,23 +82,16 @@ public class Holders return mButton; } - void setAction(@NonNull HeaderAction action, - final boolean showAll) + void setAction(@NonNull HeaderAction action, final boolean showAll) { - mButton.setText(showAll - ? R.string.bookmark_lists_show_all - : R.string.bookmark_lists_hide_all); + mButton.setText(showAll ? R.string.bookmark_lists_show_all : R.string.bookmark_lists_hide_all); mButton.setOnClickListener(new ToggleShowAllClickListener(action, showAll)); } - void setAction(@NonNull HeaderActionChildCategories action, - final boolean showAll) + void setAction(@NonNull HeaderActionChildCategories action, final boolean showAll) { - mButton.setText(showAll - ? R.string.bookmark_lists_show_all - : R.string.bookmark_lists_hide_all); - mButton.setOnClickListener(new ToggleShowAllChildCategoryClickListener( - action, showAll)); + mButton.setText(showAll ? R.string.bookmark_lists_show_all : R.string.bookmark_lists_hide_all); + mButton.setOnClickListener(new ToggleShowAllChildCategoryClickListener(action, showAll)); } public interface HeaderAction @@ -124,8 +113,7 @@ public class Holders private final HeaderActionChildCategories mAction; private final boolean mShowAll; - ToggleShowAllChildCategoryClickListener(@NonNull HeaderActionChildCategories action, - boolean showAll) + ToggleShowAllChildCategoryClickListener(@NonNull HeaderActionChildCategories action, boolean showAll) { mAction = action; mShowAll = showAll; @@ -223,7 +211,6 @@ public class Holders { return resources.getQuantityString(plural, size, size); } - } static class CollectionViewHolder extends CategoryViewHolderBase { @@ -354,17 +341,17 @@ public class Holders } @Override - void bind(@NonNull SectionPosition position, - @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource) + void bind(@NonNull SectionPosition position, @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource) { final long bookmarkId = sectionsDataSource.getBookmarkId(position); - BookmarkInfo bookmark = new BookmarkInfo(sectionsDataSource.getCategory().getId(), - bookmarkId); + BookmarkInfo bookmark = new BookmarkInfo(sectionsDataSource.getCategory().getId(), bookmarkId); mName.setText(bookmark.getName()); - final Location loc = LocationHelper.from(mIcon.getContext()).getSavedLocation(); + final Location loc = MwmApplication.from(mIcon.getContext()).getLocationHelper().getSavedLocation(); - String distanceValue = loc == null ? "" : bookmark.getDistance(loc.getLatitude(), - loc.getLongitude(), 0.0).toString(mDistance.getContext()); + String distanceValue = + loc == null + ? "" + : bookmark.getDistance(loc.getLatitude(), loc.getLongitude(), 0.0).toString(mDistance.getContext()); String separator = ""; if (!distanceValue.isEmpty() && !bookmark.getFeatureType().isEmpty()) separator = " • "; @@ -373,11 +360,9 @@ public class Holders UiUtils.hideIf(TextUtils.isEmpty(subtitleValue), mDistance); mIcon.setImageResource(bookmark.getIcon().getResId()); - Drawable circle = Graphics.drawCircleAndImage(bookmark.getIcon().argb(), - R.dimen.track_circle_size, - bookmark.getIcon().getResId(), - R.dimen.bookmark_icon_size, - mIcon.getContext()); + Drawable circle = + Graphics.drawCircleAndImage(bookmark.getIcon().argb(), R.dimen.track_circle_size, + bookmark.getIcon().getResId(), R.dimen.bookmark_icon_size, mIcon.getContext()); mIcon.setImageDrawable(circle); } } @@ -402,19 +387,18 @@ public class Holders } @Override - void bind(@NonNull SectionPosition position, - @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource) + void bind(@NonNull SectionPosition position, @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource) { final long trackId = sectionsDataSource.getTrackId(position); Track track = BookmarkManager.INSTANCE.getTrack(trackId); mName.setText(track.getName()); - mDistance.setText(new StringBuilder().append(mDistance.getContext() - .getString(R.string.length)) - .append(" ") - .append(track.getLength().toString(mDistance.getContext())) - .toString()); - Drawable circle = Graphics.drawCircle(track.getColor(), R.dimen.track_circle_size, - mIcon.getContext().getResources()); + mDistance.setText(new StringBuilder() + .append(mDistance.getContext().getString(R.string.length)) + .append(" ") + .append(track.getLength().toString(mDistance.getContext())) + .toString()); + Drawable circle = + Graphics.drawCircle(track.getColor(), R.dimen.track_circle_size, mIcon.getContext().getResources()); mIcon.setImageDrawable(circle); } @@ -441,8 +425,7 @@ public class Holders } @Override - void bind(@NonNull SectionPosition position, - @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource) + void bind(@NonNull SectionPosition position, @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource) { mView.setText(sectionsDataSource.getTitle(position.getSectionIndex(), mView.getResources())); } @@ -465,8 +448,7 @@ public class Holders } @Override - void bind(@NonNull SectionPosition position, - @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource) + void bind(@NonNull SectionPosition position, @NonNull BookmarkListAdapter.SectionsDataSource sectionsDataSource) { mTitle.setText(sectionsDataSource.getCategory().getName()); bindDescription(sectionsDataSource.getCategory()); @@ -474,9 +456,7 @@ public class Holders private void bindDescription(@NonNull BookmarkCategory category) { - String desc = TextUtils.isEmpty(category.getAnnotation()) - ? category.getDescription() - : category.getAnnotation(); + String desc = TextUtils.isEmpty(category.getAnnotation()) ? category.getDescription() : category.getAnnotation(); String formattedDesc = desc.replace("\n", "
"); Spanned spannedDesc = Utils.fromHtml(formattedDesc); diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/IconsAdapter.java b/android/app/src/main/java/app/organicmaps/bookmarks/IconsAdapter.java index cecb9b03f..58c16343a 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/IconsAdapter.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/IconsAdapter.java @@ -6,13 +6,10 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; - -import com.google.android.material.imageview.ShapeableImageView; - import app.organicmaps.R; -import app.organicmaps.bookmarks.data.Icon; +import app.organicmaps.sdk.bookmarks.data.Icon; import app.organicmaps.util.Graphics; - +import com.google.android.material.imageview.ShapeableImageView; import java.util.List; public class IconsAdapter extends ArrayAdapter @@ -43,18 +40,14 @@ public class IconsAdapter extends ArrayAdapter Drawable circle; if (icon.getColor() == mCheckedIconColor) { - circle = Graphics.drawCircleAndImage(getItem(position).argb(), - R.dimen.track_circle_size, - R.drawable.ic_bookmark_none, - R.dimen.bookmark_icon_size, + circle = Graphics.drawCircleAndImage(getItem(position).argb(), R.dimen.track_circle_size, + app.organicmaps.sdk.R.drawable.ic_bookmark_none, R.dimen.bookmark_icon_size, getContext()); - } else { - circle = Graphics.drawCircle(getItem(position).argb(), - R.dimen.select_color_circle_size, - getContext().getResources()); + circle = + Graphics.drawCircle(getItem(position).argb(), R.dimen.select_color_circle_size, getContext().getResources()); } holder.icon.setImageDrawable(circle); return convertView; diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/OnItemLongClickListener.java b/android/app/src/main/java/app/organicmaps/bookmarks/OnItemLongClickListener.java index 9f5edebc5..6f609fe60 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/OnItemLongClickListener.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/OnItemLongClickListener.java @@ -1,7 +1,6 @@ package app.organicmaps.bookmarks; import android.view.View; - import androidx.annotation.NonNull; public interface OnItemLongClickListener diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/OnItemMoreClickListener.java b/android/app/src/main/java/app/organicmaps/bookmarks/OnItemMoreClickListener.java index 9e8970202..f6293eee4 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/OnItemMoreClickListener.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/OnItemMoreClickListener.java @@ -1,7 +1,6 @@ package app.organicmaps.bookmarks; import android.view.View; - import androidx.annotation.NonNull; public interface OnItemMoreClickListener diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/OperationStatus.java b/android/app/src/main/java/app/organicmaps/bookmarks/OperationStatus.java index bebb7d728..71dee496c 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/OperationStatus.java +++ b/android/app/src/main/java/app/organicmaps/bookmarks/OperationStatus.java @@ -2,12 +2,10 @@ package app.organicmaps.bookmarks; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.Nullable; import androidx.core.os.ParcelCompat; - -import app.organicmaps.bookmarks.data.Error; -import app.organicmaps.bookmarks.data.Result; +import app.organicmaps.sdk.bookmarks.data.Error; +import app.organicmaps.sdk.bookmarks.data.Result; public class OperationStatus implements Parcelable { @@ -28,8 +26,7 @@ public class OperationStatus implements Parcelable mError = ParcelCompat.readParcelable(in, Error.class.getClassLoader(), Error.class); } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public OperationStatus createFromParcel(Parcel in) { @@ -59,9 +56,7 @@ public class OperationStatus implements Parcelable @Override public String toString() { - return "OperationStatus{" + - "mResult=" + mResult + - ", mError=" + mError + - '}'; + return "OperationStatus{" + + "mResult=" + mResult + ", mError=" + mError + '}'; } } diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/Icon.java b/android/app/src/main/java/app/organicmaps/bookmarks/data/Icon.java deleted file mode 100644 index bbb3f356e..000000000 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/Icon.java +++ /dev/null @@ -1,196 +0,0 @@ -package app.organicmaps.bookmarks.data; - -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.annotation.DrawableRes; -import androidx.annotation.IntDef; - -import com.google.common.base.Objects; - -import app.organicmaps.R; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -public class Icon implements Parcelable -{ - @Retention(RetentionPolicy.SOURCE) - @IntDef({ PREDEFINED_COLOR_NONE, PREDEFINED_COLOR_RED, PREDEFINED_COLOR_BLUE, - PREDEFINED_COLOR_PURPLE, PREDEFINED_COLOR_YELLOW, PREDEFINED_COLOR_PINK, - PREDEFINED_COLOR_BROWN, PREDEFINED_COLOR_GREEN, PREDEFINED_COLOR_ORANGE, - PREDEFINED_COLOR_DEEPPURPLE, PREDEFINED_COLOR_LIGHTBLUE, PREDEFINED_COLOR_CYAN, - PREDEFINED_COLOR_TEAL, PREDEFINED_COLOR_LIME, PREDEFINED_COLOR_DEEPORANGE, - PREDEFINED_COLOR_GRAY, PREDEFINED_COLOR_BLUEGRAY}) - @interface PredefinedColor {} - - static final int PREDEFINED_COLOR_NONE = 0; - static final int PREDEFINED_COLOR_RED = 1; - static final int PREDEFINED_COLOR_BLUE = 2; - static final int PREDEFINED_COLOR_PURPLE = 3; - static final int PREDEFINED_COLOR_YELLOW = 4; - static final int PREDEFINED_COLOR_PINK = 5; - static final int PREDEFINED_COLOR_BROWN = 6; - static final int PREDEFINED_COLOR_GREEN = 7; - static final int PREDEFINED_COLOR_ORANGE = 8; - static final int PREDEFINED_COLOR_DEEPPURPLE = 9; - static final int PREDEFINED_COLOR_LIGHTBLUE = 10; - static final int PREDEFINED_COLOR_CYAN = 11; - static final int PREDEFINED_COLOR_TEAL = 12; - static final int PREDEFINED_COLOR_LIME = 13; - static final int PREDEFINED_COLOR_DEEPORANGE = 14; - static final int PREDEFINED_COLOR_GRAY = 15; - static final int PREDEFINED_COLOR_BLUEGRAY = 16; - - private static int shift(int v, int bitCount) { return v << bitCount; } - private static int toARGB(int r, int g, int b) - { - return shift(255, 24) + shift(r, 16) + shift(g, 8) + b; - } - - /// @note Important! Should be synced with kml/types.hpp/PredefinedColor - /// @todo Values can be taken from Core. - private static final int[] ARGB_COLORS = { toARGB(229, 27, 35), // none - toARGB(229, 27, 35), // red - toARGB(0, 110, 199), // blue - toARGB(156, 39, 176), // purple - toARGB(255, 200, 0), // yellow - toARGB(255, 65, 130), // pink - toARGB(121, 85, 72), // brown - toARGB(56, 142, 60), // green - toARGB(255, 160, 0), // orange - toARGB(102, 57, 191), // deeppurple - toARGB(36, 156, 242), // lightblue - toARGB(20, 190, 205), // cyan - toARGB(0, 165, 140), // teal - toARGB(147, 191, 57), // lime - toARGB(240, 100, 50), // deeporange - toARGB(115, 115, 115), // gray - toARGB(89, 115, 128) }; // bluegray - - static final int BOOKMARK_ICON_TYPE_NONE = 0; - - /// @note Important! Should be synced with kml/types.hpp/BookmarkIcon - /// @todo Can make better: take name-by-type from Core and make a concat: "R.drawable.ic_bookmark_" + name. - // First icon should be "none" <-> BOOKMARK_ICON_TYPE_NONE. - @DrawableRes - private static final int[] TYPE_ICONS = { R.drawable.ic_bookmark_none, - R.drawable.ic_bookmark_hotel, - R.drawable.ic_bookmark_animals, - R.drawable.ic_bookmark_buddhism, - R.drawable.ic_bookmark_building, - R.drawable.ic_bookmark_christianity, - R.drawable.ic_bookmark_entertainment, - R.drawable.ic_bookmark_money, - R.drawable.ic_bookmark_food, - R.drawable.ic_bookmark_gas, - R.drawable.ic_bookmark_judaism, - R.drawable.ic_bookmark_medicine, - R.drawable.ic_bookmark_mountain, - R.drawable.ic_bookmark_museum, - R.drawable.ic_bookmark_islam, - R.drawable.ic_bookmark_park, - R.drawable.ic_bookmark_parking, - R.drawable.ic_bookmark_shop, - R.drawable.ic_bookmark_sights, - R.drawable.ic_bookmark_swim, - R.drawable.ic_bookmark_water, - R.drawable.ic_bookmark_bar, - R.drawable.ic_bookmark_transport, - R.drawable.ic_bookmark_viewpoint, - R.drawable.ic_bookmark_sport, - R.drawable.ic_bookmark_none, // pub - R.drawable.ic_bookmark_none, // art - R.drawable.ic_bookmark_none, // bank - R.drawable.ic_bookmark_none, // cafe - R.drawable.ic_bookmark_none, // pharmacy - R.drawable.ic_bookmark_none, // stadium - R.drawable.ic_bookmark_none, // theatre - R.drawable.ic_bookmark_none // information - }; - - @PredefinedColor - private final int mColor; - private final int mType; - - public Icon(@PredefinedColor int color, int type) - { - mColor = color; - mType = type; - } - - @Override - public int describeContents() - { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) - { - dest.writeInt(mColor); - dest.writeInt(mType); - } - - private Icon(Parcel in) - { - mColor = in.readInt(); - mType = in.readInt(); - } - - @PredefinedColor - public int getColor() - { - return mColor; - } - - public int argb() - { - return ARGB_COLORS[mColor]; - } - - public static int getColorPosition(int color) - { - for (int index = 1; index < ARGB_COLORS.length; index++) - { - if (ARGB_COLORS[index] == color) - return index; - } - return -1; - } - - @DrawableRes - public int getResId() - { - return TYPE_ICONS[mType]; - } - - @Override - public boolean equals(Object o) - { - if (this == o) - return true; - if (o instanceof Icon comparedIcon) - return mColor == comparedIcon.mColor && mType == comparedIcon.mType; - return false; - } - - @Override - public int hashCode() - { - return Objects.hashCode(mColor, mType); - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator<>() - { - public Icon createFromParcel(Parcel in) - { - return new Icon(in); - } - - public Icon[] newArray(int size) - { - return new Icon[size]; - } - }; -} diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/KmlFileType.java b/android/app/src/main/java/app/organicmaps/bookmarks/data/KmlFileType.java deleted file mode 100644 index 61e7ff31c..000000000 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/KmlFileType.java +++ /dev/null @@ -1,8 +0,0 @@ -package app.organicmaps.bookmarks.data; - -// Need to be in sync with KmlFileType (map/bookmark_helpers.hpp) -public enum KmlFileType { - Text, - Binary, - Gpx -} diff --git a/android/app/src/main/java/app/organicmaps/car/CarAppService.java b/android/app/src/main/java/app/organicmaps/car/CarAppService.java index 49823f0a8..3d37eafab 100644 --- a/android/app/src/main/java/app/organicmaps/car/CarAppService.java +++ b/android/app/src/main/java/app/organicmaps/car/CarAppService.java @@ -3,8 +3,6 @@ package app.organicmaps.car; import android.content.ComponentName; import android.content.Intent; import android.net.Uri; -import android.os.Build; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.car.app.CarContext; @@ -16,9 +14,6 @@ import androidx.car.app.validation.HostValidator; import androidx.core.app.NotificationChannelCompat; import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; -import androidx.lifecycle.DefaultLifecycleObserver; -import androidx.lifecycle.LifecycleOwner; - import app.organicmaps.BuildConfig; import app.organicmaps.R; import app.organicmaps.api.Const; @@ -68,12 +63,13 @@ public final class CarAppService extends androidx.car.app.CarAppService return mCarNotificationExtender; final Intent intent = new Intent(Intent.ACTION_VIEW) - .setComponent(new ComponentName(context, CarAppService.class)) - .setData(Uri.fromParts(Const.API_SCHEME, CarAppService.API_CAR_HOST, CarAppService.ACTION_SHOW_NAVIGATION_SCREEN)); + .setComponent(new ComponentName(context, CarAppService.class)) + .setData(Uri.fromParts(Const.API_SCHEME, CarAppService.API_CAR_HOST, + CarAppService.ACTION_SHOW_NAVIGATION_SCREEN)); mCarNotificationExtender = new CarAppExtender.Builder() - .setImportance(NotificationManagerCompat.IMPORTANCE_MIN) - .setContentIntent(CarPendingIntent.getCarApp(context, intent.hashCode(), intent, 0)) - .build(); + .setImportance(NotificationManagerCompat.IMPORTANCE_MIN) + .setContentIntent(CarPendingIntent.getCarApp(context, intent.hashCode(), intent, 0)) + .build(); return mCarNotificationExtender; } @@ -82,9 +78,10 @@ public final class CarAppService extends androidx.car.app.CarAppService { final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); final NotificationChannelCompat notificationChannel = - new NotificationChannelCompat.Builder(ANDROID_AUTO_NOTIFICATION_CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_MIN) + new NotificationChannelCompat + .Builder(ANDROID_AUTO_NOTIFICATION_CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_MIN) .setName(getString(R.string.car_notification_channel_name)) - .setLightsEnabled(false) // less annoying + .setLightsEnabled(false) // less annoying .setVibrationEnabled(false) // less annoying .build(); notificationManager.createNotificationChannel(notificationChannel); diff --git a/android/app/src/main/java/app/organicmaps/car/CarAppSession.java b/android/app/src/main/java/app/organicmaps/car/CarAppSession.java index 7a0f72a0a..e4eb30450 100644 --- a/android/app/src/main/java/app/organicmaps/car/CarAppSession.java +++ b/android/app/src/main/java/app/organicmaps/car/CarAppSession.java @@ -2,7 +2,6 @@ package app.organicmaps.car; import android.content.Intent; import android.content.res.Configuration; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.car.app.Screen; @@ -11,11 +10,8 @@ import androidx.car.app.Session; import androidx.car.app.SessionInfo; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; - -import app.organicmaps.Framework; import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.MapObject; import app.organicmaps.car.screens.ErrorScreen; import app.organicmaps.car.screens.MapPlaceholderScreen; import app.organicmaps.car.screens.MapScreen; @@ -30,23 +26,24 @@ import app.organicmaps.car.util.CurrentCountryChangedListener; import app.organicmaps.car.util.IntentUtils; import app.organicmaps.car.util.ThemeUtils; import app.organicmaps.car.util.UserActionRequired; -import app.organicmaps.display.DisplayChangedListener; -import app.organicmaps.display.DisplayManager; -import app.organicmaps.display.DisplayType; -import app.organicmaps.location.LocationState; import app.organicmaps.routing.RoutingController; +import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.PlacePageActivationListener; -import app.organicmaps.util.Config; -import app.organicmaps.util.LocationUtils; -import app.organicmaps.util.log.Logger; -import app.organicmaps.widget.placepage.PlacePageData; - +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.display.DisplayChangedListener; +import app.organicmaps.sdk.display.DisplayManager; +import app.organicmaps.sdk.display.DisplayType; +import app.organicmaps.sdk.location.LocationState; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.log.Logger; +import app.organicmaps.sdk.widget.placepage.PlacePageData; import java.io.IOException; import java.util.ArrayList; import java.util.List; -public final class CarAppSession extends Session implements DefaultLifecycleObserver, - LocationState.ModeChangeListener, DisplayChangedListener, PlacePageActivationListener +public final class CarAppSession extends Session implements DefaultLifecycleObserver, LocationState.ModeChangeListener, + DisplayChangedListener, PlacePageActivationListener { private static final String TAG = CarAppSession.class.getSimpleName(); @@ -115,7 +112,7 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse { Logger.d(TAG); mSensorsManager = new CarSensorsManager(getCarContext()); - mDisplayManager = DisplayManager.from(getCarContext()); + mDisplayManager = MwmApplication.from(getCarContext()).getDisplayManager(); mDisplayManager.addListener(DisplayType.Car, this); init(); } @@ -167,9 +164,12 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse MwmApplication.from(getCarContext()).initOrganicMaps(() -> { Config.setFirstStartDialogSeen(getCarContext()); if (DownloaderHelpers.isWorldMapsDownloadNeeded()) - mScreenManager.push(new DownloadMapsScreenBuilder(getCarContext()).setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.FirstLaunch).build()); + mScreenManager.push(new DownloadMapsScreenBuilder(getCarContext()) + .setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.FirstLaunch) + .build()); }); - } catch (IOException e) + } + catch (IOException e) { mInitFailed = true; Logger.e(TAG, "Failed to initialize the app."); @@ -254,7 +254,8 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse Framework.nativeDeactivatePopup(); return; } - final PlaceScreen placeScreen = new PlaceScreen.Builder(getCarContext(), mSurfaceRenderer).setMapObject(mapObject).build(); + final PlaceScreen placeScreen = + new PlaceScreen.Builder(getCarContext(), mSurfaceRenderer).setMapObject(mapObject).build(); mScreenManager.popToRoot(); mScreenManager.push(placeScreen); } @@ -282,7 +283,9 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse final RoutingController routingController = RoutingController.get(); if (routingController.isPlanning() || routingController.isNavigating() || routingController.hasSavedRoute()) { - final PlaceScreen placeScreen = new PlaceScreen.Builder(getCarContext(), mSurfaceRenderer).setMapObject(routingController.getEndPoint()).build(); + final PlaceScreen placeScreen = new PlaceScreen.Builder(getCarContext(), mSurfaceRenderer) + .setMapObject(routingController.getEndPoint()) + .build(); mScreenManager.popToRoot(); mScreenManager.push(placeScreen); } diff --git a/android/app/src/main/java/app/organicmaps/car/SurfaceRenderer.java b/android/app/src/main/java/app/organicmaps/car/SurfaceRenderer.java index 6bc98a8ca..9cb01e40d 100644 --- a/android/app/src/main/java/app/organicmaps/car/SurfaceRenderer.java +++ b/android/app/src/main/java/app/organicmaps/car/SurfaceRenderer.java @@ -1,10 +1,9 @@ package app.organicmaps.car; -import static app.organicmaps.display.DisplayType.Car; +import static app.organicmaps.sdk.display.DisplayType.Car; import android.graphics.Rect; import android.view.Surface; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.car.app.AppManager; @@ -15,15 +14,14 @@ import androidx.car.app.SurfaceContainer; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleOwner; - -import app.organicmaps.Framework; -import app.organicmaps.Map; -import app.organicmaps.MapRenderingListener; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.display.DisplayManager; -import app.organicmaps.settings.UnitLocale; -import app.organicmaps.util.concurrency.UiThread; -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.Map; +import app.organicmaps.sdk.MapRenderingListener; +import app.organicmaps.sdk.settings.UnitLocale; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.sdk.util.log.Logger; public class SurfaceRenderer implements DefaultLifecycleObserver, SurfaceCallback, MapRenderingListener { @@ -58,12 +56,9 @@ public class SurfaceRenderer implements DefaultLifecycleObserver, SurfaceCallbac mSurface.release(); mSurface = surfaceContainer.getSurface(); - mMap.onSurfaceCreated( - mCarContext, - mSurface, - new Rect(0, 0, surfaceContainer.getWidth(), surfaceContainer.getHeight()), - surfaceContainer.getDpi() - ); + mMap.onSurfaceCreated(mCarContext, mSurface, + new Rect(0, 0, surfaceContainer.getWidth(), surfaceContainer.getHeight()), + surfaceContainer.getDpi()); mMap.updateBottomWidgetsOffset(mCarContext, -1, -1); } @@ -121,7 +116,7 @@ public class SurfaceRenderer implements DefaultLifecycleObserver, SurfaceCallbac { Logger.d(TAG); mMap.onResume(); - if (DisplayManager.from(mCarContext).isCarDisplayUsed()) + if (MwmApplication.from(mCarContext).getDisplayManager().isCarDisplayUsed()) UiThread.runLater(() -> mMap.updateMyPositionRoutingOffset(0)); } diff --git a/android/app/src/main/java/app/organicmaps/car/screens/CategoriesScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/CategoriesScreen.java index 7598bfbf0..9d46d4033 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/CategoriesScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/CategoriesScreen.java @@ -14,22 +14,18 @@ import androidx.car.app.model.ItemList; import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; import androidx.core.graphics.drawable.IconCompat; - import app.organicmaps.R; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; import app.organicmaps.car.screens.search.SearchOnMapScreen; import app.organicmaps.car.util.ThemeUtils; import app.organicmaps.car.util.UiHelpers; - import java.util.Arrays; import java.util.List; public class CategoriesScreen extends BaseMapScreen { - private record CategoryData(@StringRes int nameResId, @DrawableRes int iconResId, @DrawableRes int iconNightResId) - { - } + private record CategoryData(@StringRes int nameResId, @DrawableRes int iconResId, @DrawableRes int iconNightResId) {} private static final List CATEGORIES = Arrays.asList( new CategoryData(R.string.category_fuel, R.drawable.ic_category_fuel, R.drawable.ic_category_fuel_night), @@ -38,8 +34,7 @@ public class CategoriesScreen extends BaseMapScreen new CategoryData(R.string.category_food, R.drawable.ic_category_food, R.drawable.ic_category_food_night), new CategoryData(R.string.category_hotel, R.drawable.ic_category_hotel, R.drawable.ic_category_hotel_night), new CategoryData(R.string.category_toilet, R.drawable.ic_category_toilet, R.drawable.ic_category_toilet_night), - new CategoryData(R.string.category_rv, R.drawable.ic_category_rv, R.drawable.ic_category_rv_night) - ); + new CategoryData(R.string.category_rv, R.drawable.ic_category_rv, R.drawable.ic_category_rv_night)); private final int MAX_CATEGORIES_SIZE; @@ -79,11 +74,15 @@ public class CategoriesScreen extends BaseMapScreen { final GridItem.Builder itemBuilder = new GridItem.Builder(); final String title = getCarContext().getString(CATEGORIES.get(i).nameResId); - @DrawableRes final int iconResId = isNightMode ? CATEGORIES.get(i).iconNightResId : CATEGORIES.get(i).iconResId; + @DrawableRes + final int iconResId = isNightMode ? CATEGORIES.get(i).iconNightResId : CATEGORIES.get(i).iconResId; itemBuilder.setTitle(title); itemBuilder.setImage(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), iconResId)).build()); - itemBuilder.setOnClickListener(() -> getScreenManager().push(new SearchOnMapScreen.Builder(getCarContext(), getSurfaceRenderer()).setCategory(title).build())); + itemBuilder.setOnClickListener( + () + -> getScreenManager().push( + new SearchOnMapScreen.Builder(getCarContext(), getSurfaceRenderer()).setCategory(title).build())); builder.addItem(itemBuilder.build()); } return new GridTemplate.Builder().setHeader(createHeader()).setSingleList(builder.build()).build(); diff --git a/android/app/src/main/java/app/organicmaps/car/screens/ErrorScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/ErrorScreen.java index cb070c8f9..b6b71f053 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/ErrorScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/ErrorScreen.java @@ -8,7 +8,6 @@ import androidx.car.app.model.Action; import androidx.car.app.model.Header; import androidx.car.app.model.MessageTemplate; import androidx.car.app.model.Template; - import app.organicmaps.R; import app.organicmaps.car.screens.base.BaseScreen; import app.organicmaps.car.util.Colors; @@ -56,17 +55,17 @@ public class ErrorScreen extends BaseScreen implements UserActionRequired if (mPositiveButtonText != -1) { builder.addAction(new Action.Builder() - .setBackgroundColor(Colors.BUTTON_ACCEPT) - .setTitle(getCarContext().getString(mPositiveButtonText)) - .setOnClickListener(this::onPositiveButton).build() - ); + .setBackgroundColor(Colors.BUTTON_ACCEPT) + .setTitle(getCarContext().getString(mPositiveButtonText)) + .setOnClickListener(this::onPositiveButton) + .build()); } if (mNegativeButtonText != -1) { builder.addAction(new Action.Builder() - .setTitle(getCarContext().getString(mNegativeButtonText)) - .setOnClickListener(this::onNegativeButton).build() - ); + .setTitle(getCarContext().getString(mNegativeButtonText)) + .setOnClickListener(this::onNegativeButton) + .build()); } return builder.build(); diff --git a/android/app/src/main/java/app/organicmaps/car/screens/FreeDriveScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/FreeDriveScreen.java index 50549831b..7772ce041 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/FreeDriveScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/FreeDriveScreen.java @@ -8,7 +8,6 @@ import androidx.car.app.model.CarIcon; import androidx.car.app.model.Template; import androidx.car.app.navigation.model.NavigationTemplate; import androidx.core.graphics.drawable.IconCompat; - import app.organicmaps.R; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; @@ -36,7 +35,8 @@ public class FreeDriveScreen extends BaseMapScreen private ActionStrip createActionStrip() { final Action.Builder finishActionBuilder = new Action.Builder(); - finishActionBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_close)).build()); + finishActionBuilder.setIcon( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_close)).build()); finishActionBuilder.setOnClickListener(this::finish); final ActionStrip.Builder builder = new ActionStrip.Builder(); diff --git a/android/app/src/main/java/app/organicmaps/car/screens/MapPlaceholderScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/MapPlaceholderScreen.java index a58e1cd5b..467ddb0af 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/MapPlaceholderScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/MapPlaceholderScreen.java @@ -8,11 +8,10 @@ import androidx.car.app.model.Header; import androidx.car.app.model.MessageTemplate; import androidx.car.app.model.Template; import androidx.core.graphics.drawable.IconCompat; - +import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.car.screens.base.BaseScreen; -import app.organicmaps.display.DisplayManager; -import app.organicmaps.display.DisplayType; +import app.organicmaps.sdk.display.DisplayType; public class MapPlaceholderScreen extends BaseScreen { @@ -25,15 +24,21 @@ public class MapPlaceholderScreen extends BaseScreen @Override public Template onGetTemplate() { - final MessageTemplate.Builder builder = new MessageTemplate.Builder(getCarContext().getString(R.string.car_used_on_the_phone_screen)); + final MessageTemplate.Builder builder = + new MessageTemplate.Builder(getCarContext().getString(R.string.car_used_on_the_phone_screen)); final Header.Builder headerBuilder = new Header.Builder(); headerBuilder.setStartHeaderAction(Action.APP_ICON); headerBuilder.setTitle(getCarContext().getString(R.string.app_name)); builder.setHeader(headerBuilder.build()); - builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_phone_android)).build()); - builder.addAction(new Action.Builder().setTitle(getCarContext().getString(R.string.car_continue_in_the_car)) - .setOnClickListener(() -> DisplayManager.from(getCarContext()).changeDisplay(DisplayType.Car)).build()); + builder.setIcon( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_phone_android)).build()); + builder.addAction( + new Action.Builder() + .setTitle(getCarContext().getString(R.string.car_continue_in_the_car)) + .setOnClickListener( + () -> MwmApplication.from(getCarContext()).getDisplayManager().changeDisplay(DisplayType.Car)) + .build()); return builder.build(); } diff --git a/android/app/src/main/java/app/organicmaps/car/screens/MapScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/MapScreen.java index fb5687fa9..e27ef4beb 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/MapScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/MapScreen.java @@ -13,7 +13,6 @@ import androidx.car.app.model.ItemList; import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; import androidx.core.graphics.drawable.IconCompat; - import app.organicmaps.R; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; @@ -56,8 +55,10 @@ public class MapScreen extends BaseMapScreen private ActionStrip createActionStrip() { final Action.Builder freeDriveScreenBuilder = new Action.Builder(); - freeDriveScreenBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_steering_wheel)).build()); - freeDriveScreenBuilder.setOnClickListener(() -> getScreenManager().push(new FreeDriveScreen(getCarContext(), getSurfaceRenderer()))); + freeDriveScreenBuilder.setIcon( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_steering_wheel)).build()); + freeDriveScreenBuilder.setOnClickListener( + () -> getScreenManager().push(new FreeDriveScreen(getCarContext(), getSurfaceRenderer()))); final ActionStrip.Builder builder = new ActionStrip.Builder(); builder.addAction(freeDriveScreenBuilder.build()); @@ -83,7 +84,8 @@ public class MapScreen extends BaseMapScreen @NonNull private Item createSearchItem() { - final CarIcon iconSearch = new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build(); + final CarIcon iconSearch = + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build(); final GridItem.Builder builder = new GridItem.Builder(); builder.setTitle(getCarContext().getString(R.string.search)); @@ -95,7 +97,8 @@ public class MapScreen extends BaseMapScreen @NonNull private Item createCategoriesItem() { - final CarIcon iconCategories = new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_address)).build(); + final CarIcon iconCategories = + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_address)).build(); final GridItem.Builder builder = new GridItem.Builder(); builder.setImage(iconCategories); @@ -107,7 +110,8 @@ public class MapScreen extends BaseMapScreen @NonNull private Item createBookmarksItem() { - final CarIcon iconBookmarks = new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_bookmarks)).build(); + final CarIcon iconBookmarks = + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_bookmarks)).build(); final GridItem.Builder builder = new GridItem.Builder(); builder.setImage(iconBookmarks); @@ -119,7 +123,8 @@ public class MapScreen extends BaseMapScreen @NonNull private Item createSettingsItem() { - final CarIcon iconSettings = new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_settings)).build(); + final CarIcon iconSettings = + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_settings)).build(); final GridItem.Builder builder = new GridItem.Builder(); builder.setImage(iconSettings); diff --git a/android/app/src/main/java/app/organicmaps/car/screens/NavigationScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/NavigationScreen.java index b43b9fc86..0430a77b8 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/NavigationScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/NavigationScreen.java @@ -17,8 +17,7 @@ import androidx.car.app.navigation.model.TravelEstimate; import androidx.car.app.navigation.model.Trip; import androidx.core.graphics.drawable.IconCompat; import androidx.lifecycle.LifecycleOwner; - -import app.organicmaps.Framework; +import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.car.CarAppService; import app.organicmaps.car.SurfaceRenderer; @@ -28,16 +27,16 @@ import app.organicmaps.car.util.Colors; import app.organicmaps.car.util.RoutingUtils; import app.organicmaps.car.util.ThemeUtils; import app.organicmaps.car.util.UiHelpers; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.LocationListener; -import app.organicmaps.sdk.routing.JunctionInfo; import app.organicmaps.routing.NavigationService; import app.organicmaps.routing.RoutingController; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.location.LocationHelper; +import app.organicmaps.sdk.location.LocationListener; +import app.organicmaps.sdk.routing.JunctionInfo; import app.organicmaps.sdk.routing.RoutingInfo; -import app.organicmaps.sound.TtsPlayer; -import app.organicmaps.util.LocationUtils; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.sound.TtsPlayer; +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.log.Logger; import java.util.List; import java.util.Objects; @@ -74,7 +73,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController public Template onGetTemplate() { final NavigationTemplate.Builder builder = new NavigationTemplate.Builder(); - builder.setBackgroundColor(ThemeUtils.isNightMode(getCarContext()) ? Colors.NAVIGATION_TEMPLATE_BACKGROUND_NIGHT : Colors.NAVIGATION_TEMPLATE_BACKGROUND_DAY); + builder.setBackgroundColor(ThemeUtils.isNightMode(getCarContext()) ? Colors.NAVIGATION_TEMPLATE_BACKGROUND_NIGHT + : Colors.NAVIGATION_TEMPLATE_BACKGROUND_DAY); builder.setActionStrip(createActionStrip()); builder.setMapActionStrip(UiHelpers.createMapActionStrip(getCarContext(), getSurfaceRenderer())); @@ -89,7 +89,7 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController @Override public void onStopNavigation() { - LocationHelper.from(getCarContext()).removeListener(mLocationListener); + MwmApplication.from(getCarContext()).getLocationHelper().removeListener(mLocationListener); mNavigationCancelled = true; mRoutingController.cancel(); } @@ -112,7 +112,7 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController return; } - final LocationHelper locationHelper = LocationHelper.from(getCarContext()); + final LocationHelper locationHelper = MwmApplication.from(getCarContext()).getLocationHelper(); locationHelper.startNavigationSimulation(points); } @@ -120,7 +120,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController public void onNavigationCancelled() { if (!mNavigationCancelled) - CarToast.makeText(getCarContext(), getCarContext().getString(R.string.trip_finished), CarToast.LENGTH_LONG).show(); + CarToast.makeText(getCarContext(), getCarContext().getString(R.string.trip_finished), CarToast.LENGTH_LONG) + .show(); finish(); getScreenManager().popToRoot(); } @@ -134,9 +135,10 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController mNavigationManager.setNavigationManagerCallback(this); mNavigationManager.navigationStarted(); - LocationHelper.from(getCarContext()).addListener(mLocationListener); + MwmApplication.from(getCarContext()).getLocationHelper().addListener(mLocationListener); if (LocationUtils.checkFineLocationPermission(getCarContext())) - NavigationService.startForegroundService(getCarContext(), CarAppService.getCarNotificationExtender(getCarContext())); + NavigationService.startForegroundService(getCarContext(), + CarAppService.getCarNotificationExtender(getCarContext())); updateTrip(); } @@ -151,7 +153,7 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController public void onDestroy(@NonNull LifecycleOwner owner) { NavigationService.stopService(getCarContext()); - LocationHelper.from(getCarContext()).removeListener(mLocationListener); + MwmApplication.from(getCarContext()).getLocationHelper().removeListener(mLocationListener); if (mRoutingController.isNavigating()) mRoutingController.onSaveState(); @@ -165,7 +167,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController private ActionStrip createActionStrip() { final Action.Builder stopActionBuilder = new Action.Builder(); - stopActionBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_close)).build()); + stopActionBuilder.setIcon( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_close)).build()); stopActionBuilder.setOnClickListener(() -> { mNavigationCancelled = true; mRoutingController.cancel(); @@ -194,7 +197,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController @NonNull private NavigationTemplate.NavigationInfo getNavigationInfo() { - final androidx.car.app.navigation.model.RoutingInfo.Builder builder = new androidx.car.app.navigation.model.RoutingInfo.Builder(); + final androidx.car.app.navigation.model.RoutingInfo.Builder builder = + new androidx.car.app.navigation.model.RoutingInfo.Builder(); if (mTrip.isLoading()) { @@ -227,7 +231,8 @@ public class NavigationScreen extends BaseMapScreen implements RoutingController private Action createTtsAction() { final Action.Builder ttsActionBuilder = new Action.Builder(); - @DrawableRes final int imgRes = TtsPlayer.isEnabled() ? R.drawable.ic_voice_on : R.drawable.ic_voice_off; + @DrawableRes + final int imgRes = TtsPlayer.isEnabled() ? R.drawable.ic_voice_on : R.drawable.ic_voice_off; ttsActionBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), imgRes)).build()); ttsActionBuilder.setOnClickListener(() -> { TtsPlayer.setEnabled(!TtsPlayer.isEnabled()); diff --git a/android/app/src/main/java/app/organicmaps/car/screens/PlaceScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/PlaceScreen.java index 7f0312453..ee04d535e 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/PlaceScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/PlaceScreen.java @@ -7,7 +7,6 @@ import android.content.Intent; import android.net.Uri; import android.text.SpannableString; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.car.app.CarContext; @@ -25,11 +24,8 @@ import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; import androidx.core.graphics.drawable.IconCompat; import androidx.lifecycle.LifecycleOwner; - -import app.organicmaps.Framework; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.bookmarks.data.Metadata; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder; @@ -38,13 +34,14 @@ import app.organicmaps.car.util.Colors; import app.organicmaps.car.util.OnBackPressedCallback; import app.organicmaps.car.util.RoutingHelpers; import app.organicmaps.car.util.UiHelpers; -import app.organicmaps.location.LocationHelper; import app.organicmaps.routing.ResultCodesHelper; import app.organicmaps.routing.RoutingController; -import app.organicmaps.sdk.routing.RoutingInfo; +import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Router; -import app.organicmaps.util.Config; - +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.bookmarks.data.Metadata; +import app.organicmaps.sdk.routing.RoutingInfo; +import app.organicmaps.sdk.util.Config; import java.util.Objects; public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback.Callback, RoutingController.Container @@ -95,7 +92,8 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback. mRoutingController.restoreRoute(); else { - final boolean hasIncorrectEndPoint = mRoutingController.isPlanning() && (!MapObject.same(mMapObject, mRoutingController.getEndPoint())); + final boolean hasIncorrectEndPoint = + mRoutingController.isPlanning() && (!MapObject.same(mMapObject, mRoutingController.getEndPoint())); final boolean hasIncorrectRouterType = mRoutingController.getLastRouterType() != ROUTER; final boolean isNotPlanningMode = !mRoutingController.isPlanning(); if (hasIncorrectRouterType) @@ -105,7 +103,8 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback. } else if (hasIncorrectEndPoint || isNotPlanningMode) { - mRoutingController.prepare(LocationHelper.from(getCarContext()).getMyPosition(), mMapObject); + mRoutingController.prepare(MwmApplication.from(getCarContext()).getLocationHelper().getMyPosition(), + mMapObject); } } } @@ -159,7 +158,8 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback. if (routingInfo != null) builder.addRow(getPlaceRouteInfo(routingInfo)); - final Row placeOpeningHours = UiHelpers.getPlaceOpeningHoursRow(Objects.requireNonNull(mMapObject), getCarContext()); + final Row placeOpeningHours = + UiHelpers.getPlaceOpeningHoursRow(Objects.requireNonNull(mMapObject), getCarContext()); if (placeOpeningHours != null) builder.addRow(placeOpeningHours); @@ -195,7 +195,8 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback. builder.setTitle(time); final SpannableString distance = new SpannableString(" "); - distance.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(routingInfo.distToTarget)), 0, 1, SPAN_INCLUSIVE_INCLUSIVE); + distance.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(routingInfo.distToTarget)), 0, 1, + SPAN_INCLUSIVE_INCLUSIVE); distance.setSpan(ForegroundCarColorSpan.create(Colors.DISTANCE), 0, 1, SPAN_EXCLUSIVE_EXCLUSIVE); builder.addText(distance); @@ -211,8 +212,10 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback. { final String phoneNumber = phones.split(";", 1)[0]; final Action.Builder openDialBuilder = new Action.Builder(); - openDialBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_phone)).build()); - openDialBuilder.setOnClickListener(() -> getCarContext().startCarApp(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)))); + openDialBuilder.setIcon( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_phone)).build()); + openDialBuilder.setOnClickListener( + () -> getCarContext().startCarApp(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)))); builder.addAction(openDialBuilder.build()); } @@ -224,7 +227,8 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback. startRouteBuilder.setBackgroundColor(Colors.START_NAVIGATION); startRouteBuilder.setFlags(Action.FLAG_DEFAULT); startRouteBuilder.setTitle(getCarContext().getString(R.string.p2p_start)); - startRouteBuilder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_follow_and_rotate)).build()); + startRouteBuilder.setIcon( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_follow_and_rotate)).build()); startRouteBuilder.setOnClickListener(() -> { Config.acceptRoutingDisclaimer(); mRoutingController.start(); @@ -238,7 +242,10 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback. { return new Action.Builder() .setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_settings)).build()) - .setOnClickListener(() -> getScreenManager().pushForResult(new DrivingOptionsScreen(getCarContext(), getSurfaceRenderer()), this::onDrivingOptionsResult)) + .setOnClickListener( + () + -> getScreenManager().pushForResult(new DrivingOptionsScreen(getCarContext(), getSurfaceRenderer()), + this::onDrivingOptionsResult)) .build(); } @@ -280,7 +287,7 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback. @Override public void onBuiltRoute() { - Framework.nativeDeactivateMapSelectionCircle(); + Framework.nativeDeactivateMapSelectionCircle(true); mMapObject = mRoutingController.getEndPoint(); invalidate(); } @@ -288,7 +295,7 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback. @Override public void onPlanningCancelled() { - Framework.nativeDeactivateMapSelectionCircle(); + Framework.nativeDeactivateMapSelectionCircle(true); } @Override @@ -310,8 +317,7 @@ public class PlaceScreen extends BaseMapScreen implements OnBackPressedCallback. else mRoutingController.checkAndBuildRoute(); invalidate(); - } - ); + }); else { CarToast.makeText(getCarContext(), R.string.unable_to_calc_alert_title, CarToast.LENGTH_LONG).show(); diff --git a/android/app/src/main/java/app/organicmaps/car/screens/base/BaseMapScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/base/BaseMapScreen.java index f97f5cb8b..f502074df 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/base/BaseMapScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/base/BaseMapScreen.java @@ -2,7 +2,6 @@ package app.organicmaps.car.screens.base; import androidx.annotation.NonNull; import androidx.car.app.CarContext; - import app.organicmaps.car.SurfaceRenderer; public abstract class BaseMapScreen extends BaseScreen diff --git a/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarkCategoriesScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarkCategoriesScreen.java index 168bd1838..52c8e722a 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarkCategoriesScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarkCategoriesScreen.java @@ -10,14 +10,12 @@ import androidx.car.app.model.ListTemplate; import androidx.car.app.model.Row; import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; - import app.organicmaps.R; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkManager; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; import app.organicmaps.car.util.UiHelpers; - +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; import java.util.ArrayList; import java.util.List; @@ -65,7 +63,8 @@ public class BookmarkCategoriesScreen extends BaseMapScreen Row.Builder itemBuilder = new Row.Builder(); itemBuilder.setTitle(bookmarkCategory.getName()); itemBuilder.addText(bookmarkCategory.getDescription()); - itemBuilder.setOnClickListener(() -> getScreenManager().push(new BookmarksScreen(getCarContext(), getSurfaceRenderer(), bookmarkCategory))); + itemBuilder.setOnClickListener( + () -> getScreenManager().push(new BookmarksScreen(getCarContext(), getSurfaceRenderer(), bookmarkCategory))); itemBuilder.setBrowsable(true); builder.addItem(itemBuilder.build()); } diff --git a/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarksLoader.java b/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarksLoader.java index c5440cd97..7990ad543 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarksLoader.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarksLoader.java @@ -4,7 +4,6 @@ import android.graphics.drawable.Drawable; import android.location.Location; import android.text.SpannableStringBuilder; import android.text.Spanned; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.car.app.CarContext; @@ -15,21 +14,19 @@ import androidx.car.app.model.ForegroundCarColorSpan; import androidx.car.app.model.ItemList; import androidx.car.app.model.Row; import androidx.core.graphics.drawable.IconCompat; - +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkInfo; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.Icon; -import app.organicmaps.bookmarks.data.SortedBlock; import app.organicmaps.car.util.Colors; import app.organicmaps.car.util.RoutingHelpers; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.util.Distance; +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkInfo; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.Icon; +import app.organicmaps.sdk.bookmarks.data.SortedBlock; +import app.organicmaps.sdk.util.Distance; +import app.organicmaps.sdk.util.concurrency.ThreadPool; +import app.organicmaps.sdk.util.concurrency.UiThread; import app.organicmaps.util.Graphics; -import app.organicmaps.util.concurrency.ThreadPool; -import app.organicmaps.util.concurrency.UiThread; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -63,7 +60,8 @@ class BookmarksLoader implements BookmarkManager.BookmarksSortingListener private final long mBookmarkCategoryId; private final int mBookmarksListSize; - public BookmarksLoader(@NonNull CarContext carContext, @NonNull BookmarkCategory bookmarkCategory, @NonNull OnBookmarksLoaded onBookmarksLoaded) + public BookmarksLoader(@NonNull CarContext carContext, @NonNull BookmarkCategory bookmarkCategory, + @NonNull OnBookmarksLoaded onBookmarksLoaded) { final ConstraintManager constraintManager = carContext.getCarService(ConstraintManager.class); final int maxCategoriesSize = constraintManager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_LIST); @@ -71,7 +69,8 @@ class BookmarksLoader implements BookmarkManager.BookmarksSortingListener mCarContext = carContext; mOnBookmarksLoaded = onBookmarksLoaded; mBookmarkCategoryId = bookmarkCategory.getId(); - mBookmarksListSize = Math.min(bookmarkCategory.getBookmarksCount(), Math.min(maxCategoriesSize, MAX_BOOKMARKS_SIZE)); + mBookmarksListSize = + Math.min(bookmarkCategory.getBookmarksCount(), Math.min(maxCategoriesSize, MAX_BOOKMARKS_SIZE)); } public void load() @@ -112,7 +111,7 @@ class BookmarksLoader implements BookmarkManager.BookmarksSortingListener if (sortingType < 0) return false; - final Location loc = LocationHelper.from(mCarContext).getSavedLocation(); + final Location loc = MwmApplication.from(mCarContext).getLocationHelper().getSavedLocation(); final boolean hasMyPosition = loc != null; if (!hasMyPosition && sortingType == BookmarkManager.SORT_BY_DISTANCE) return false; @@ -146,7 +145,7 @@ class BookmarksLoader implements BookmarkManager.BookmarksSortingListener @NonNull private ItemList createBookmarksList(@NonNull BookmarkInfo[] bookmarks) { - final Location location = LocationHelper.from(mCarContext).getSavedLocation(); + final Location location = MwmApplication.from(mCarContext).getLocationHelper().getSavedLocation(); final ItemList.Builder builder = new ItemList.Builder(); final Map iconsCache = new HashMap<>(); for (final BookmarkInfo bookmarkInfo : bookmarks) @@ -161,12 +160,10 @@ class BookmarksLoader implements BookmarkManager.BookmarksSortingListener final Icon icon = bookmarkInfo.getIcon(); if (!iconsCache.containsKey(icon)) { - final Drawable drawable = Graphics.drawCircleAndImage(icon.argb(), - R.dimen.track_circle_size, - icon.getResId(), - R.dimen.bookmark_icon_size, - mCarContext); - final CarIcon carIcon = new CarIcon.Builder(IconCompat.createWithBitmap(Graphics.drawableToBitmap(drawable))).build(); + final Drawable drawable = Graphics.drawCircleAndImage(icon.argb(), R.dimen.track_circle_size, icon.getResId(), + R.dimen.bookmark_icon_size, mCarContext); + final CarIcon carIcon = + new CarIcon.Builder(IconCompat.createWithBitmap(Graphics.drawableToBitmap(drawable))).build(); iconsCache.put(icon, carIcon); } itemBuilder.setImage(Objects.requireNonNull(iconsCache.get(icon))); @@ -184,7 +181,8 @@ class BookmarksLoader implements BookmarkManager.BookmarksSortingListener { result.append(" "); final Distance distance = bookmark.getDistance(location.getLatitude(), location.getLongitude(), 0.0); - result.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(distance)), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + result.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(distance)), 0, 1, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); result.setSpan(ForegroundCarColorSpan.create(Colors.DISTANCE), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } diff --git a/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarksScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarksScreen.java index 126359678..218483c48 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarksScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/BookmarksScreen.java @@ -12,12 +12,11 @@ import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; import androidx.core.graphics.drawable.IconCompat; import androidx.lifecycle.LifecycleOwner; - import app.organicmaps.R; -import app.organicmaps.bookmarks.data.BookmarkCategory; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; import app.organicmaps.car.util.UiHelpers; +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; public class BookmarksScreen extends BaseMapScreen { @@ -32,7 +31,8 @@ public class BookmarksScreen extends BaseMapScreen private boolean mIsOnSortingScreen = false; - public BookmarksScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, @NonNull BookmarkCategory bookmarkCategory) + public BookmarksScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, + @NonNull BookmarkCategory bookmarkCategory) { super(carContext, surfaceRenderer); mBookmarkCategory = bookmarkCategory; @@ -90,7 +90,8 @@ public class BookmarksScreen extends BaseMapScreen builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_sort)).build()); builder.setOnClickListener(() -> { mIsOnSortingScreen = true; - getScreenManager().pushForResult(new SortingScreen(getCarContext(), getSurfaceRenderer(), mBookmarkCategory), this::onSortingResult); + getScreenManager().pushForResult(new SortingScreen(getCarContext(), getSurfaceRenderer(), mBookmarkCategory), + this::onSortingResult); }); return builder.build(); } diff --git a/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/SortingScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/SortingScreen.java index 0771c0937..44eb459bc 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/SortingScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/bookmarks/SortingScreen.java @@ -1,7 +1,6 @@ package app.organicmaps.car.screens.bookmarks; import android.location.Location; - import androidx.annotation.NonNull; import androidx.annotation.StringRes; import androidx.car.app.CarContext; @@ -15,15 +14,13 @@ import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; import androidx.core.graphics.drawable.IconCompat; import androidx.lifecycle.LifecycleOwner; - +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkManager; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; import app.organicmaps.car.util.UiHelpers; -import app.organicmaps.location.LocationHelper; - +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; import java.util.Arrays; import java.util.stream.IntStream; @@ -41,11 +38,14 @@ class SortingScreen extends BaseMapScreen private @BookmarkManager.SortingType int mNewSortingType; - public SortingScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, @NonNull BookmarkCategory bookmarkCategory) + public SortingScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, + @NonNull BookmarkCategory bookmarkCategory) { super(carContext, surfaceRenderer); - mRadioButtonIcon = new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_unchecked)).build(); - mRadioButtonSelectedIcon = new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_checked)).build(); + mRadioButtonIcon = + new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_unchecked)).build(); + mRadioButtonSelectedIcon = + new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_checked)).build(); mBookmarkCategoryId = bookmarkCategory.getId(); mLastSortingType = mNewSortingType = getLastSortingType(); @@ -90,10 +90,12 @@ class SortingScreen extends BaseMapScreen } @NonNull - private ItemList createSortingTypesList(@NonNull final @BookmarkManager.SortingType int[] availableSortingTypes, final int lastSortingType) + private ItemList createSortingTypesList(@NonNull final @BookmarkManager.SortingType int[] availableSortingTypes, + final int lastSortingType) { final ItemList.Builder builder = new ItemList.Builder(); - for (int type : IntStream.concat(IntStream.of(DEFAULT_SORTING_TYPE), Arrays.stream(availableSortingTypes)).toArray()) + for (int type : + IntStream.concat(IntStream.of(DEFAULT_SORTING_TYPE), Arrays.stream(availableSortingTypes)).toArray()) { final Row.Builder rowBuilder = new Row.Builder(); rowBuilder.setTitle(getCarContext().getString(sortingTypeToStringRes(type))); @@ -133,7 +135,7 @@ class SortingScreen extends BaseMapScreen @BookmarkManager.SortingType private int[] getAvailableSortingTypes() { - final Location loc = LocationHelper.from(getCarContext()).getSavedLocation(); + final Location loc = MwmApplication.from(getCarContext()).getLocationHelper().getSavedLocation(); final boolean hasMyPosition = loc != null; return BookmarkManager.INSTANCE.getAvailableSortingTypes(mBookmarkCategoryId, hasMyPosition); } @@ -148,7 +150,8 @@ class SortingScreen extends BaseMapScreen private int getLastAvailableSortingType() { int currentType = getLastSortingType(); - @BookmarkManager.SortingType int[] types = getAvailableSortingTypes(); + @BookmarkManager.SortingType + int[] types = getAvailableSortingTypes(); for (@BookmarkManager.SortingType int type : types) { if (type == currentType) diff --git a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForFirstLaunchScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForFirstLaunchScreen.java index 6085838cb..9e423f3e7 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForFirstLaunchScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForFirstLaunchScreen.java @@ -2,15 +2,13 @@ package app.organicmaps.car.screens.download; import android.location.Location; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.car.app.model.Action; import androidx.lifecycle.LifecycleOwner; - +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.downloader.CountryItem; -import app.organicmaps.downloader.MapManager; -import app.organicmaps.location.LocationHelper; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; class DownloadMapsForFirstLaunchScreen extends DownloadMapsScreen { @@ -25,8 +23,9 @@ class DownloadMapsForFirstLaunchScreen extends DownloadMapsScreen @Override public void onResume(@NonNull LifecycleOwner owner) { - // Attempting to streamline initial download by including the current country in the list of missing maps for simultaneous retrieval. - final Location location = LocationHelper.from(getCarContext()).getSavedLocation(); + // Attempting to streamline initial download by including the current country in the list of missing maps for + // simultaneous retrieval. + final Location location = MwmApplication.from(getCarContext()).getLocationHelper().getSavedLocation(); if (location == null) return; final String countryId = MapManager.nativeFindCountry(location.getLatitude(), location.getLongitude()); diff --git a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForRouteScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForRouteScreen.java index a350d327d..269250752 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForRouteScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForRouteScreen.java @@ -2,10 +2,8 @@ package app.organicmaps.car.screens.download; import androidx.annotation.NonNull; import androidx.car.app.model.Action; - import app.organicmaps.R; import app.organicmaps.routing.ResultCodesHelper; - import java.util.Objects; class DownloadMapsForRouteScreen extends DownloadMapsScreen @@ -17,8 +15,11 @@ class DownloadMapsForRouteScreen extends DownloadMapsScreen { super(builder); - mTitle = ResultCodesHelper.getDialogTitleSubtitle(builder.mCarContext, builder.mResultCode, Objects.requireNonNull(builder.mMissingMaps).length) - .getTitleMessage().first; + mTitle = ResultCodesHelper + .getDialogTitleSubtitle(builder.mCarContext, builder.mResultCode, + Objects.requireNonNull(builder.mMissingMaps).length) + .getTitleMessage() + .first; } @NonNull @@ -35,7 +36,8 @@ class DownloadMapsForRouteScreen extends DownloadMapsScreen final int mapsCount = getMissingMaps().size(); if (mapsCount == 1) return DownloaderHelpers.getCountryName(getMissingMaps().get(0)) + "\n" + mapsSize; - return getCarContext().getString(R.string.downloader_status_maps) + " (" + getMissingMaps().size() + "): " + mapsSize; + return getCarContext().getString(R.string.downloader_status_maps) + " (" + getMissingMaps().size() + + "): " + mapsSize; } @NonNull diff --git a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForViewScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForViewScreen.java index b9bb7123a..94c135f9e 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForViewScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsForViewScreen.java @@ -2,7 +2,6 @@ package app.organicmaps.car.screens.download; import androidx.annotation.NonNull; import androidx.car.app.model.Action; - import app.organicmaps.R; class DownloadMapsForViewScreen extends DownloadMapsScreen diff --git a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsScreen.java index 75afad4d3..13572b934 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsScreen.java @@ -7,13 +7,11 @@ import androidx.car.app.model.Header; import androidx.car.app.model.MessageTemplate; import androidx.car.app.model.Template; import androidx.core.graphics.drawable.IconCompat; - import app.organicmaps.R; import app.organicmaps.car.screens.base.BaseScreen; import app.organicmaps.car.util.Colors; -import app.organicmaps.downloader.CountryItem; -import app.organicmaps.util.StringUtils; - +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.util.StringUtils; import java.util.List; public abstract class DownloadMapsScreen extends BaseScreen @@ -100,10 +98,11 @@ public abstract class DownloadMapsScreen extends BaseScreen private void onDownload() { - getScreenManager().pushForResult(new DownloaderScreen(getCarContext(), mMissingMaps, mIsCancelActionDisabled), result -> { - setResult(result); - finish(); - }); + getScreenManager().pushForResult(new DownloaderScreen(getCarContext(), mMissingMaps, mIsCancelActionDisabled), + result -> { + setResult(result); + finish(); + }); } @NonNull diff --git a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsScreenBuilder.java b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsScreenBuilder.java index b91f9c768..67fa721da 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsScreenBuilder.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloadMapsScreenBuilder.java @@ -3,9 +3,7 @@ package app.organicmaps.car.screens.download; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.car.app.CarContext; - import app.organicmaps.routing.ResultCodesHelper; - import java.util.Objects; public class DownloadMapsScreenBuilder diff --git a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloaderHelpers.java b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloaderHelpers.java index 7c899f88f..28a6c1b9a 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloaderHelpers.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloaderHelpers.java @@ -1,20 +1,17 @@ package app.organicmaps.car.screens.download; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.BuildConfig; -import app.organicmaps.downloader.CountryItem; - +import app.organicmaps.sdk.downloader.CountryItem; import java.util.ArrayList; import java.util.Collection; import java.util.List; public final class DownloaderHelpers { - static final String[] WORLD_MAPS = new String[]{"World", "WorldCoasts"}; + static final String[] WORLD_MAPS = new String[] {"World", "WorldCoasts"}; // World maps may be missing only in the F-Droid build. @SuppressWarnings("ConstantConditions") diff --git a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloaderScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloaderScreen.java index 1eabac471..deed7766a 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/download/DownloaderScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/download/DownloaderScreen.java @@ -1,7 +1,6 @@ package app.organicmaps.car.screens.download; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.car.app.CarContext; import androidx.car.app.constraints.ConstraintManager; @@ -10,15 +9,13 @@ import androidx.car.app.model.Header; import androidx.car.app.model.MessageTemplate; import androidx.car.app.model.Template; import androidx.lifecycle.LifecycleOwner; - import app.organicmaps.R; import app.organicmaps.car.screens.ErrorScreen; import app.organicmaps.car.screens.base.BaseScreen; -import app.organicmaps.downloader.CountryItem; -import app.organicmaps.downloader.MapManager; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.concurrency.UiThread; - +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.concurrency.UiThread; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -36,8 +33,7 @@ class DownloaderScreen extends BaseScreen private boolean mIsDownloadFailed = false; @NonNull - private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback() - { + private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback() { @Override public void onStatusChanged(@NonNull final List data) { @@ -85,7 +81,8 @@ class DownloaderScreen extends BaseScreen } }; - DownloaderScreen(@NonNull final CarContext carContext, @NonNull final List missingMaps, final boolean isCancelActionDisabled) + DownloaderScreen(@NonNull final CarContext carContext, @NonNull final List missingMaps, + final boolean isCancelActionDisabled) { super(carContext); setMarker(DownloadMapsScreen.MARKER); @@ -171,9 +168,9 @@ class DownloaderScreen extends BaseScreen { mIsDownloadFailed = true; final ErrorScreen.Builder builder = new ErrorScreen.Builder(getCarContext()) - .setTitle(R.string.country_status_download_failed) - .setErrorMessage(MapManager.getErrorCodeStrRes(data.errorCode)) - .setPositiveButton(R.string.downloader_retry, null); + .setTitle(R.string.country_status_download_failed) + .setErrorMessage(MapManager.getErrorCodeStrRes(data.errorCode)) + .setPositiveButton(R.string.downloader_retry, null); if (!mIsCancelActionDisabled) builder.setNegativeButton(R.string.cancel, this::finish); getScreenManager().push(builder.build()); diff --git a/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsActivity.java b/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsActivity.java index c8e934d03..c1f72a4b8 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsActivity.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsActivity.java @@ -7,21 +7,18 @@ import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.provider.Settings; - import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.Nullable; import androidx.core.app.NotificationManagerCompat; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmFragmentActivity; -import app.organicmaps.util.LocationUtils; - +import app.organicmaps.sdk.util.LocationUtils; import java.util.Objects; public class RequestPermissionsActivity extends BaseMwmFragmentActivity { - private static final String[] LOCATION_PERMISSIONS = new String[]{ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}; + private static final String[] LOCATION_PERMISSIONS = new String[] {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}; @Nullable private ActivityResultLauncher mPermissionsRequest; @@ -34,7 +31,7 @@ public class RequestPermissionsActivity extends BaseMwmFragmentActivity findViewById(R.id.btn_grant_permissions).setOnClickListener(unused -> openAppPermissionSettings()); mPermissionsRequest = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), - (grantedPermissions) -> closeIfPermissionsGranted()); + (grantedPermissions) -> closeIfPermissionsGranted()); mPermissionsRequest.launch(LOCATION_PERMISSIONS); } diff --git a/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenBuilder.java b/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenBuilder.java index 3b90a793b..cb7d09929 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenBuilder.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenBuilder.java @@ -4,13 +4,11 @@ import static android.Manifest.permission.POST_NOTIFICATIONS; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import android.os.Build; - import androidx.annotation.NonNull; import androidx.car.app.CarContext; import androidx.car.app.Screen; import androidx.core.content.ContextCompat; - -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.util.log.Logger; public class RequestPermissionsScreenBuilder { @@ -18,8 +16,8 @@ public class RequestPermissionsScreenBuilder public static Screen build(@NonNull CarContext carContext, @NonNull Runnable permissionsGrantedCallback) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && - ContextCompat.checkSelfPermission(carContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && ContextCompat.checkSelfPermission(carContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED) { Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, using API-based permissions request"); return new RequestPermissionsScreenWithApi(carContext, permissionsGrantedCallback); diff --git a/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenWithApi.java b/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenWithApi.java index 8cd3a641e..1f1c950c5 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenWithApi.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenWithApi.java @@ -13,14 +13,12 @@ import androidx.car.app.model.ParkedOnlyOnClickListener; import androidx.car.app.model.Template; import androidx.core.graphics.drawable.IconCompat; import androidx.lifecycle.LifecycleOwner; - import app.organicmaps.R; import app.organicmaps.car.screens.ErrorScreen; import app.organicmaps.car.screens.base.BaseScreen; import app.organicmaps.car.util.Colors; import app.organicmaps.car.util.UserActionRequired; -import app.organicmaps.util.LocationUtils; - +import app.organicmaps.sdk.util.LocationUtils; import java.util.Arrays; import java.util.List; @@ -41,19 +39,23 @@ public class RequestPermissionsScreenWithApi extends BaseScreen implements UserA @Override public Template onGetTemplate() { - final MessageTemplate.Builder builder = new MessageTemplate.Builder(getCarContext().getString(R.string.aa_request_permission_activity_text)); - final Action grantPermissions = new Action.Builder() - .setTitle(getCarContext().getString(R.string.aa_grant_permissions)) - .setBackgroundColor(Colors.BUTTON_ACCEPT) - .setOnClickListener(ParkedOnlyOnClickListener.create(() -> getCarContext().requestPermissions(LOCATION_PERMISSIONS, this::onRequestPermissionsResult))) - .build(); + final MessageTemplate.Builder builder = + new MessageTemplate.Builder(getCarContext().getString(R.string.aa_request_permission_activity_text)); + final Action grantPermissions = + new Action.Builder() + .setTitle(getCarContext().getString(R.string.aa_grant_permissions)) + .setBackgroundColor(Colors.BUTTON_ACCEPT) + .setOnClickListener(ParkedOnlyOnClickListener.create( + () -> getCarContext().requestPermissions(LOCATION_PERMISSIONS, this::onRequestPermissionsResult))) + .build(); final Header.Builder headerBuilder = new Header.Builder(); headerBuilder.setStartHeaderAction(Action.APP_ICON); headerBuilder.setTitle(getCarContext().getString(R.string.app_name)); builder.setHeader(headerBuilder.build()); - builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_location_off)).build()); + builder.setIcon( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_location_off)).build()); builder.addAction(grantPermissions); return builder.build(); } @@ -70,19 +72,19 @@ public class RequestPermissionsScreenWithApi extends BaseScreen implements UserA } } - private void onRequestPermissionsResult(@NonNull List grantedPermissions, @NonNull List rejectedPermissions) + private void onRequestPermissionsResult(@NonNull List grantedPermissions, + @NonNull List rejectedPermissions) { if (grantedPermissions.isEmpty()) { getScreenManager().push(new ErrorScreen.Builder(getCarContext()) - .setErrorMessage(R.string.location_is_disabled_long_text) - .setNegativeButton(R.string.close, null) - .build() - ); + .setErrorMessage(R.string.location_is_disabled_long_text) + .setNegativeButton(R.string.close, null) + .build()); return; } mPermissionsGrantedCallback.run(); finish(); } -} \ No newline at end of file +} diff --git a/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenWithNotification.java b/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenWithNotification.java index b916deaa7..50f8dac53 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenWithNotification.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/permissions/RequestPermissionsScreenWithNotification.java @@ -5,7 +5,6 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent; import android.os.Build; - import androidx.annotation.NonNull; import androidx.annotation.RequiresPermission; import androidx.car.app.CarContext; @@ -19,15 +18,13 @@ import androidx.core.app.NotificationManagerCompat; import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.IconCompat; import androidx.lifecycle.LifecycleOwner; - import app.organicmaps.R; import app.organicmaps.car.CarAppService; import app.organicmaps.car.screens.base.BaseScreen; import app.organicmaps.car.util.UserActionRequired; -import app.organicmaps.util.LocationUtils; -import app.organicmaps.util.concurrency.ThreadPool; -import app.organicmaps.util.concurrency.UiThread; - +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.concurrency.ThreadPool; +import app.organicmaps.sdk.util.concurrency.UiThread; import java.util.concurrent.ExecutorService; public class RequestPermissionsScreenWithNotification extends BaseScreen implements UserActionRequired @@ -40,7 +37,8 @@ public class RequestPermissionsScreenWithNotification extends BaseScreen impleme @NonNull private final Runnable mPermissionsGrantedCallback; - public RequestPermissionsScreenWithNotification(@NonNull CarContext carContext, @NonNull Runnable permissionsGrantedCallback) + public RequestPermissionsScreenWithNotification(@NonNull CarContext carContext, + @NonNull Runnable permissionsGrantedCallback) { super(carContext); mBackgroundExecutor = ThreadPool.getWorker(); @@ -51,14 +49,16 @@ public class RequestPermissionsScreenWithNotification extends BaseScreen impleme @Override public Template onGetTemplate() { - final MessageTemplate.Builder builder = new MessageTemplate.Builder(getCarContext().getString(R.string.aa_location_permissions_request)); + final MessageTemplate.Builder builder = + new MessageTemplate.Builder(getCarContext().getString(R.string.aa_location_permissions_request)); final Header.Builder headerBuilder = new Header.Builder(); headerBuilder.setStartHeaderAction(Action.APP_ICON); headerBuilder.setTitle(getCarContext().getString(R.string.aa_grant_permissions)); builder.setHeader(headerBuilder.build()); - builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_location_off)).build()); + builder.setIcon( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_location_off)).build()); return builder.build(); } @@ -105,9 +105,10 @@ public class RequestPermissionsScreenWithNotification extends BaseScreen impleme final int FLAG_IMMUTABLE = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? 0 : PendingIntent.FLAG_IMMUTABLE; final Intent contentIntent = new Intent(getCarContext(), RequestPermissionsActivity.class); final PendingIntent pendingIntent = PendingIntent.getActivity(getCarContext(), 0, contentIntent, - PendingIntent.FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE); + PendingIntent.FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE); - final NotificationCompat.Builder builder = new NotificationCompat.Builder(getCarContext(), CarAppService.ANDROID_AUTO_NOTIFICATION_CHANNEL_ID); + final NotificationCompat.Builder builder = + new NotificationCompat.Builder(getCarContext(), CarAppService.ANDROID_AUTO_NOTIFICATION_CHANNEL_ID); builder.setCategory(NotificationCompat.CATEGORY_NAVIGATION) .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) .setOngoing(true) diff --git a/android/app/src/main/java/app/organicmaps/car/screens/search/SearchOnMapScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/search/SearchOnMapScreen.java index 92710669b..481604af8 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/search/SearchOnMapScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/search/SearchOnMapScreen.java @@ -1,7 +1,6 @@ package app.organicmaps.car.screens.search; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.car.app.CarContext; @@ -16,18 +15,18 @@ import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; import androidx.core.graphics.drawable.IconCompat; import androidx.lifecycle.LifecycleOwner; - +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.MapObject; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; import app.organicmaps.car.util.UiHelpers; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.sdk.search.SearchListener; +import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.search.SearchEngine; +import app.organicmaps.sdk.search.SearchListener; import app.organicmaps.sdk.search.SearchRecents; import app.organicmaps.sdk.search.SearchResult; -import app.organicmaps.util.Language; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.Language; public class SearchOnMapScreen extends BaseMapScreen implements SearchListener { @@ -114,7 +113,8 @@ public class SearchOnMapScreen extends BaseMapScreen implements SearchListener } builder.setOnClickListener(() -> { - SearchRecents.add(title, getCarContext()); + if (Config.isSearchHistoryEnabled()) + SearchRecents.add(title, getCarContext()); SearchEngine.INSTANCE.cancel(); SearchEngine.INSTANCE.showResult(resultIndex); }); @@ -123,8 +123,12 @@ public class SearchOnMapScreen extends BaseMapScreen implements SearchListener { builder.setBrowsable(true); builder.setTitle(result.suggestion); - builder.setImage(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build()); - builder.setOnClickListener(() -> getScreenManager().push(new Builder(getCarContext(), getSurfaceRenderer()).setQuery(result.suggestion).build())); + builder.setImage( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build()); + builder.setOnClickListener( + () + -> getScreenManager().push( + new Builder(getCarContext(), getSurfaceRenderer()).setQuery(result.suggestion).build())); } return builder.build(); } @@ -140,12 +144,13 @@ public class SearchOnMapScreen extends BaseMapScreen implements SearchListener { SearchEngine.INSTANCE.cancel(); - final MapObject location = LocationHelper.from(getCarContext()).getMyPosition(); + final MapObject location = MwmApplication.from(getCarContext()).getLocationHelper().getMyPosition(); final boolean hasLocation = location != null; final double lat = hasLocation ? location.getLat() : 0; final double lon = hasLocation ? location.getLon() : 0; - SearchEngine.INSTANCE.searchInteractive(mQuery, mIsCategory, mLocale, System.nanoTime(), true /* isMapAndTable */, hasLocation, lat, lon); + SearchEngine.INSTANCE.searchInteractive(mQuery, mIsCategory, mLocale, System.nanoTime(), true /* isMapAndTable */, + hasLocation, lat, lon); } @Override diff --git a/android/app/src/main/java/app/organicmaps/car/screens/search/SearchScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/search/SearchScreen.java index e4dc95dac..2b7661e03 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/search/SearchScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/search/SearchScreen.java @@ -1,7 +1,6 @@ package app.organicmaps.car.screens.search; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.car.app.CarContext; @@ -15,17 +14,17 @@ import androidx.car.app.model.SearchTemplate; import androidx.car.app.model.Template; import androidx.core.graphics.drawable.IconCompat; import androidx.lifecycle.LifecycleOwner; - +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.MapObject; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.sdk.search.SearchListener; +import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.search.SearchEngine; +import app.organicmaps.sdk.search.SearchListener; import app.organicmaps.sdk.search.SearchRecents; import app.organicmaps.sdk.search.SearchResult; -import app.organicmaps.util.Language; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.Language; public class SearchScreen extends BaseMapScreen implements SearchTemplate.SearchCallback, SearchListener { @@ -89,7 +88,7 @@ public class SearchScreen extends BaseMapScreen implements SearchTemplate.Search return; } - final MapObject location = LocationHelper.from(getCarContext()).getMyPosition(); + final MapObject location = MwmApplication.from(getCarContext()).getLocationHelper().getMyPosition(); final boolean hasLocation = location != null; final double lat = hasLocation ? location.getLat() : 0; final double lon = hasLocation ? location.getLon() : 0; @@ -136,10 +135,9 @@ public class SearchScreen extends BaseMapScreen implements SearchTemplate.Search if (result.type == SearchResult.TYPE_RESULT) { final String title = result.getTitle(getCarContext()); - final CharSequence description = SearchUiHelpers.concatenateStrings( - SearchUiHelpers.getDistanceText(result), - result.description.description, - SearchUiHelpers.getOpeningHoursText(getCarContext(), result)); + final CharSequence description = + SearchUiHelpers.concatenateStrings(SearchUiHelpers.getDistanceText(result), result.description.description, + SearchUiHelpers.getOpeningHoursText(getCarContext(), result)); final String region = result.description.region; builder.setTitle(title); if (!TextUtils.isEmpty(description)) @@ -147,7 +145,8 @@ public class SearchScreen extends BaseMapScreen implements SearchTemplate.Search if (!TextUtils.isEmpty(region)) builder.addText(region); builder.setOnClickListener(() -> { - SearchRecents.add(title, getCarContext()); + if (Config.isSearchHistoryEnabled()) + SearchRecents.add(title, getCarContext()); SearchEngine.INSTANCE.cancel(); SearchEngine.INSTANCE.showResult(resultIndex); }); @@ -156,7 +155,8 @@ public class SearchScreen extends BaseMapScreen implements SearchTemplate.Search { builder.setBrowsable(true); builder.setTitle(result.suggestion); - builder.setImage(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build()); + builder.setImage( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search)).build()); builder.setOnClickListener(() -> onSearchSubmitted(result.suggestion)); } return builder.build(); @@ -164,7 +164,8 @@ public class SearchScreen extends BaseMapScreen implements SearchTemplate.Search private boolean loadRecents() { - final CarIcon iconRecent = new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search_recent)).build(); + final CarIcon iconRecent = + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_search_recent)).build(); final ItemList.Builder builder = new ItemList.Builder(); builder.setNoItemsMessage(getCarContext().getString(R.string.search_history_text)); @@ -188,9 +189,14 @@ public class SearchScreen extends BaseMapScreen implements SearchTemplate.Search private ActionStrip createActionStrip() { final Action.Builder builder = new Action.Builder(); - builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_show_on_map)).build()); - builder.setOnClickListener(() -> - getScreenManager().push(new SearchOnMapScreen.Builder(getCarContext(), getSurfaceRenderer()).setQuery(mQuery).setLocale(mLocale).build())); + builder.setIcon( + new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_show_on_map)).build()); + builder.setOnClickListener( + () + -> getScreenManager().push(new SearchOnMapScreen.Builder(getCarContext(), getSurfaceRenderer()) + .setQuery(mQuery) + .setLocale(mLocale) + .build())); return new ActionStrip.Builder().addAction(builder.build()).build(); } diff --git a/android/app/src/main/java/app/organicmaps/car/screens/search/SearchUiHelpers.java b/android/app/src/main/java/app/organicmaps/car/screens/search/SearchUiHelpers.java index b44fdecdc..d673c84ed 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/search/SearchUiHelpers.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/search/SearchUiHelpers.java @@ -3,18 +3,15 @@ package app.organicmaps.car.screens.search; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.car.app.CarContext; import androidx.car.app.model.CarColor; import androidx.car.app.model.DistanceSpan; import androidx.car.app.model.ForegroundCarColorSpan; - import app.organicmaps.R; import app.organicmaps.car.util.Colors; import app.organicmaps.car.util.RoutingHelpers; import app.organicmaps.sdk.search.SearchResult; - import java.util.ArrayList; import java.util.List; @@ -50,7 +47,8 @@ public final class SearchUiHelpers return ""; final SpannableStringBuilder distance = new SpannableStringBuilder(" "); - distance.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(searchResult.description.distance)), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + distance.setSpan(DistanceSpan.create(RoutingHelpers.createDistance(searchResult.description.distance)), 0, 1, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); distance.setSpan(ForegroundCarColorSpan.create(Colors.DISTANCE), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return distance; } @@ -64,31 +62,29 @@ public final class SearchUiHelpers CarColor color = Colors.DEFAULT; switch (searchResult.description.openNow) { - case SearchResult.OPEN_NOW_YES: - if (searchResult.description.minutesUntilClosed < 60) // less than 1 hour - { - final String time = searchResult.description.minutesUntilClosed + " " + - carContext.getString(R.string.minute); - text = carContext.getString(R.string.closes_in, time); - color = Colors.OPENING_HOURS_CLOSES_SOON; - } - else - { - text = carContext.getString(R.string.editor_time_open); - color = Colors.OPENING_HOURS_OPEN; - } - break; - case SearchResult.OPEN_NOW_NO: - if (searchResult.description.minutesUntilOpen < 60) // less than 1 hour - { - final String time = searchResult.description.minutesUntilOpen + " " + - carContext.getString(R.string.minute); - text = carContext.getString(R.string.opens_in, time); - } - else - text = carContext.getString(R.string.closed); - color = Colors.OPENING_HOURS_CLOSED; - break; + case SearchResult.OPEN_NOW_YES: + if (searchResult.description.minutesUntilClosed < 60) // less than 1 hour + { + final String time = searchResult.description.minutesUntilClosed + " " + carContext.getString(R.string.minute); + text = carContext.getString(R.string.closes_in, time); + color = Colors.OPENING_HOURS_CLOSES_SOON; + } + else + { + text = carContext.getString(R.string.editor_time_open); + color = Colors.OPENING_HOURS_OPEN; + } + break; + case SearchResult.OPEN_NOW_NO: + if (searchResult.description.minutesUntilOpen < 60) // less than 1 hour + { + final String time = searchResult.description.minutesUntilOpen + " " + carContext.getString(R.string.minute); + text = carContext.getString(R.string.opens_in, time); + } + else + text = carContext.getString(R.string.closed); + color = Colors.OPENING_HOURS_CLOSED; + break; } result.append(text); diff --git a/android/app/src/main/java/app/organicmaps/car/screens/settings/DrivingOptionsScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/settings/DrivingOptionsScreen.java index 0143983da..1567cc715 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/settings/DrivingOptionsScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/settings/DrivingOptionsScreen.java @@ -12,15 +12,13 @@ import androidx.car.app.model.Row; import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; import androidx.lifecycle.LifecycleOwner; - import app.organicmaps.R; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; import app.organicmaps.car.util.Toggle; import app.organicmaps.car.util.UiHelpers; import app.organicmaps.sdk.routing.RoutingOptions; -import app.organicmaps.settings.RoadType; - +import app.organicmaps.sdk.settings.RoadType; import java.util.HashMap; import java.util.Map; @@ -28,16 +26,12 @@ public class DrivingOptionsScreen extends BaseMapScreen { public static final Object DRIVING_OPTIONS_RESULT_CHANGED = 0x1; - private record DrivingOption(RoadType roadType, @StringRes int text) - { - } + private record DrivingOption(RoadType roadType, @StringRes int text) {} - private final DrivingOption[] mDrivingOptions = { - new DrivingOption(RoadType.Toll, R.string.avoid_tolls), - new DrivingOption(RoadType.Dirty, R.string.avoid_unpaved), - new DrivingOption(RoadType.Ferry, R.string.avoid_ferry), - new DrivingOption(RoadType.Motorway, R.string.avoid_motorways) - }; + private final DrivingOption[] mDrivingOptions = {new DrivingOption(RoadType.Toll, R.string.avoid_tolls), + new DrivingOption(RoadType.Dirty, R.string.avoid_unpaved), + new DrivingOption(RoadType.Ferry, R.string.avoid_ferry), + new DrivingOption(RoadType.Motorway, R.string.avoid_motorways)}; @NonNull private final Map mInitialDrivingOptionsState = new HashMap<>(); @@ -64,7 +58,8 @@ public class DrivingOptionsScreen extends BaseMapScreen { for (final DrivingOption drivingOption : mDrivingOptions) { - if (Boolean.TRUE.equals(mInitialDrivingOptionsState.get(drivingOption.roadType)) != RoutingOptions.hasOption(drivingOption.roadType)) + if (Boolean.TRUE.equals(mInitialDrivingOptionsState.get(drivingOption.roadType)) + != RoutingOptions.hasOption(drivingOption.roadType)) { setResult(DRIVING_OPTIONS_RESULT_CHANGED); return; @@ -93,7 +88,8 @@ public class DrivingOptionsScreen extends BaseMapScreen @NonNull private Row createDrivingOptionsToggle(RoadType roadType, @StringRes int title) { - final OnClickListener listener = () -> { + final OnClickListener listener = () -> + { if (RoutingOptions.hasOption(roadType)) RoutingOptions.removeOption(roadType); else diff --git a/android/app/src/main/java/app/organicmaps/car/screens/settings/HelpScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/settings/HelpScreen.java index 2079f3e03..e1b8430de 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/settings/HelpScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/settings/HelpScreen.java @@ -10,14 +10,13 @@ import androidx.car.app.model.ListTemplate; import androidx.car.app.model.Row; import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; - import app.organicmaps.BuildConfig; -import app.organicmaps.Framework; import app.organicmaps.R; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; import app.organicmaps.car.util.UiHelpers; -import app.organicmaps.util.DateUtils; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.util.DateUtils; public class HelpScreen extends BaseMapScreen { diff --git a/android/app/src/main/java/app/organicmaps/car/screens/settings/SettingsScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/settings/SettingsScreen.java index 2749d1ce9..1cb2ed8ef 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/settings/SettingsScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/settings/SettingsScreen.java @@ -12,15 +12,14 @@ import androidx.car.app.model.OnClickListener; import androidx.car.app.model.Row; import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; - -import app.organicmaps.Framework; import app.organicmaps.R; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; import app.organicmaps.car.util.ThemeUtils; import app.organicmaps.car.util.Toggle; import app.organicmaps.car.util.UiHelpers; -import app.organicmaps.util.Config; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.util.Config; public class SettingsScreen extends BaseMapScreen { @@ -66,7 +65,8 @@ public class SettingsScreen extends BaseMapScreen builder.addItem(createRoutingOptionsItem()); builder.addItem(create3dBuildingsItem()); builder.addItem(createSharedPrefsToggle(R.string.big_font, Config::isLargeFontsSize, Config::setLargeFontsSize)); - builder.addItem(createSharedPrefsToggle(R.string.transliteration_title, Config::isTransliteration, Config::setTransliteration)); + builder.addItem( + createSharedPrefsToggle(R.string.transliteration_title, Config::isTransliteration, Config::setTransliteration)); builder.addItem(createHelpItem()); return new ListTemplate.Builder().setHeader(createHeader()).setSingleList(builder.build()).build(); } @@ -87,7 +87,10 @@ public class SettingsScreen extends BaseMapScreen { final Row.Builder builder = new Row.Builder(); builder.setTitle(getCarContext().getString(R.string.driving_options_title)); - builder.setOnClickListener(() -> getScreenManager().pushForResult(new DrivingOptionsScreen(getCarContext(), getSurfaceRenderer()), this::setResult)); + builder.setOnClickListener( + () + -> getScreenManager().pushForResult(new DrivingOptionsScreen(getCarContext(), getSurfaceRenderer()), + this::setResult)); builder.setBrowsable(true); return builder.build(); } @@ -98,7 +101,8 @@ public class SettingsScreen extends BaseMapScreen final Framework.Params3dMode _3d = new Framework.Params3dMode(); Framework.nativeGet3dMode(_3d); - final OnClickListener listener = () -> { + final OnClickListener listener = () -> + { Framework.nativeSet3dMode(_3d.enabled, !_3d.buildings); invalidate(); }; @@ -119,7 +123,8 @@ public class SettingsScreen extends BaseMapScreen private Row createSharedPrefsToggle(@StringRes int titleRes, @NonNull PrefsGetter getter, @NonNull PrefsSetter setter) { final boolean enabled = getter.get(); - final OnClickListener listener = () -> { + final OnClickListener listener = () -> + { setter.set(!enabled); invalidate(); }; diff --git a/android/app/src/main/java/app/organicmaps/car/screens/settings/ThemeScreen.java b/android/app/src/main/java/app/organicmaps/car/screens/settings/ThemeScreen.java index 530a3259b..25e66e368 100644 --- a/android/app/src/main/java/app/organicmaps/car/screens/settings/ThemeScreen.java +++ b/android/app/src/main/java/app/organicmaps/car/screens/settings/ThemeScreen.java @@ -11,7 +11,6 @@ import androidx.car.app.model.Row; import androidx.car.app.model.Template; import androidx.car.app.navigation.model.MapWithContentTemplate; import androidx.core.graphics.drawable.IconCompat; - import app.organicmaps.R; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; @@ -28,8 +27,10 @@ public class ThemeScreen extends BaseMapScreen public ThemeScreen(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer) { super(carContext, surfaceRenderer); - mRadioButtonIcon = new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_unchecked)).build(); - mRadioButtonSelectedIcon = new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_checked)).build(); + mRadioButtonIcon = + new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_unchecked)).build(); + mRadioButtonSelectedIcon = + new CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_radio_button_checked)).build(); } @NonNull diff --git a/android/app/src/main/java/app/organicmaps/car/util/CarSensorsManager.java b/android/app/src/main/java/app/organicmaps/car/util/CarSensorsManager.java index b8c9a68c3..3f3ce32ac 100644 --- a/android/app/src/main/java/app/organicmaps/car/util/CarSensorsManager.java +++ b/android/app/src/main/java/app/organicmaps/car/util/CarSensorsManager.java @@ -3,7 +3,6 @@ package app.organicmaps.car.util; import static android.Manifest.permission.ACCESS_FINE_LOCATION; import android.location.Location; - import androidx.annotation.NonNull; import androidx.annotation.RequiresPermission; import androidx.car.app.CarContext; @@ -13,12 +12,9 @@ import androidx.car.app.hardware.info.CarHardwareLocation; import androidx.car.app.hardware.info.CarSensors; import androidx.car.app.hardware.info.Compass; import androidx.core.content.ContextCompat; - -import app.organicmaps.Map; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.SensorHelper; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.MwmApplication; +import app.organicmaps.sdk.Map; +import app.organicmaps.sdk.util.log.Logger; import java.util.List; import java.util.concurrent.Executor; @@ -48,13 +44,14 @@ public class CarSensorsManager if (mIsCarCompassUsed) mCarSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, executor, this::onCarCompassDataAvailable); else - SensorHelper.from(mCarContext).addListener(this::onCompassUpdated); + MwmApplication.from(mCarContext).getSensorHelper().addListener(this::onCompassUpdated); - if (!LocationHelper.from(mCarContext).isActive()) - LocationHelper.from(mCarContext).start(); + if (!MwmApplication.from(mCarContext).getLocationHelper().isActive()) + MwmApplication.from(mCarContext).getLocationHelper().start(); if (mIsCarLocationUsed) - mCarSensors.addCarHardwareLocationListener(CarSensors.UPDATE_RATE_FASTEST, executor, this::onCarLocationDataAvailable); + mCarSensors.addCarHardwareLocationListener(CarSensors.UPDATE_RATE_FASTEST, executor, + this::onCarLocationDataAvailable); } public void onStop() @@ -62,7 +59,7 @@ public class CarSensorsManager if (mIsCarCompassUsed) mCarSensors.removeCompassListener(this::onCarCompassDataAvailable); else - SensorHelper.from(mCarContext).removeListener(this::onCompassUpdated); + MwmApplication.from(mCarContext).getSensorHelper().removeListener(this::onCompassUpdated); if (mIsCarLocationUsed) mCarSensors.removeCarHardwareLocationListener(this::onCarLocationDataAvailable); @@ -97,7 +94,7 @@ public class CarSensorsManager { final Location loc = location.getValue(); if (loc != null) - LocationHelper.from(mCarContext).onLocationChanged(loc); + MwmApplication.from(mCarContext).getLocationHelper().onLocationChanged(loc); } } @@ -113,6 +110,6 @@ public class CarSensorsManager Logger.d(TAG); mIsCarCompassUsed = false; mCarSensors.removeCompassListener(this::onCarCompassDataAvailable); - SensorHelper.from(mCarContext).addListener(this::onCompassUpdated); + MwmApplication.from(mCarContext).getSensorHelper().addListener(this::onCompassUpdated); } } diff --git a/android/app/src/main/java/app/organicmaps/car/util/CurrentCountryChangedListener.java b/android/app/src/main/java/app/organicmaps/car/util/CurrentCountryChangedListener.java index 86ec576ba..802bbf8bc 100644 --- a/android/app/src/main/java/app/organicmaps/car/util/CurrentCountryChangedListener.java +++ b/android/app/src/main/java/app/organicmaps/car/util/CurrentCountryChangedListener.java @@ -1,17 +1,15 @@ package app.organicmaps.car.util; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.car.app.CarContext; import androidx.car.app.ScreenManager; - import app.organicmaps.car.screens.download.DownloadMapsScreen; import app.organicmaps.car.screens.download.DownloadMapsScreenBuilder; -import app.organicmaps.downloader.CountryItem; -import app.organicmaps.downloader.MapManager; import app.organicmaps.routing.RoutingController; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; public class CurrentCountryChangedListener implements MapManager.CurrentCountryChangedListener { @@ -45,12 +43,10 @@ public class CurrentCountryChangedListener implements MapManager.CurrentCountryC return; mPreviousCountryId = countryId; - screenManager.push( - new DownloadMapsScreenBuilder(mCarContext) - .setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.View) - .setMissingMaps(new String[]{countryId}) - .build() - ); + screenManager.push(new DownloadMapsScreenBuilder(mCarContext) + .setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.View) + .setMissingMaps(new String[] {countryId}) + .build()); } public void onStart(@NonNull final CarContext carContext) diff --git a/android/app/src/main/java/app/organicmaps/car/util/IntentUtils.java b/android/app/src/main/java/app/organicmaps/car/util/IntentUtils.java index 93e4a87da..776e95e63 100644 --- a/android/app/src/main/java/app/organicmaps/car/util/IntentUtils.java +++ b/android/app/src/main/java/app/organicmaps/car/util/IntentUtils.java @@ -4,26 +4,25 @@ import android.app.PendingIntent; import android.content.ComponentName; import android.content.Intent; import android.net.Uri; - import androidx.annotation.NonNull; import androidx.car.app.CarContext; import androidx.car.app.Screen; import androidx.car.app.ScreenManager; import androidx.car.app.notification.CarPendingIntent; - -import app.organicmaps.Framework; -import app.organicmaps.Map; +import app.organicmaps.MwmApplication; import app.organicmaps.api.Const; -import app.organicmaps.api.ParsedSearchRequest; -import app.organicmaps.api.RequestType; import app.organicmaps.car.CarAppService; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.NavigationScreen; import app.organicmaps.car.screens.search.SearchScreen; -import app.organicmaps.display.DisplayManager; -import app.organicmaps.display.DisplayType; import app.organicmaps.routing.RoutingController; -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.Map; +import app.organicmaps.sdk.api.ParsedSearchRequest; +import app.organicmaps.sdk.api.RequestType; +import app.organicmaps.sdk.display.DisplayManager; +import app.organicmaps.sdk.display.DisplayType; +import app.organicmaps.sdk.util.log.Logger; public final class IntentUtils { @@ -31,7 +30,8 @@ public final class IntentUtils private static final int SEARCH_IN_VIEWPORT_ZOOM = 16; - public static void processIntent(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, @NonNull Intent intent) + public static void processIntent(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, + @NonNull Intent intent) { final String action = intent.getAction(); if (CarContext.ACTION_NAVIGATE.equals(action)) @@ -50,10 +50,11 @@ public final class IntentUtils } // https://developer.android.com/reference/androidx/car/app/CarContext#startCarApp(android.content.Intent) - private static void processNavigationIntent(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, @NonNull Intent intent) + private static void processNavigationIntent(@NonNull CarContext carContext, @NonNull SurfaceRenderer surfaceRenderer, + @NonNull Intent intent) { - // TODO (AndrewShkrob): This logic will need to be revised when we introduce support for adding stops during navigation or route planning. - // Skip navigation intents during navigation + // TODO (AndrewShkrob): This logic will need to be revised when we introduce support for adding stops during + // navigation or route planning. Skip navigation intents during navigation if (RoutingController.get().isNavigating()) return; @@ -64,58 +65,49 @@ public final class IntentUtils final ScreenManager screenManager = carContext.getCarService(ScreenManager.class); switch (Framework.nativeParseAndSetApiUrl(uri.toString())) { - case RequestType.INCORRECT: - return; - case RequestType.MAP: - screenManager.popToRoot(); - Map.executeMapApiRequest(); - return; - case RequestType.SEARCH: - screenManager.popToRoot(); - final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest(); - final double[] latlon = Framework.nativeGetParsedCenterLatLon(); - if (latlon != null) - { - Framework.nativeStopLocationFollow(); - Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM); - // We need to update viewport for search api manually because of drape engine - // will not notify subscribers when search activity is shown. - if (!request.mIsSearchOnMap) - Framework.nativeSetSearchViewport(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM); - } - final SearchScreen.Builder builder = new SearchScreen.Builder(carContext, surfaceRenderer); - builder.setQuery(request.mQuery); - if (request.mLocale != null) - builder.setLocale(request.mLocale); + case RequestType.INCORRECT: return; + case RequestType.MAP: + screenManager.popToRoot(); + Map.executeMapApiRequest(); + return; + case RequestType.SEARCH: + screenManager.popToRoot(); + final ParsedSearchRequest request = Framework.nativeGetParsedSearchRequest(); + final double[] latlon = Framework.nativeGetParsedCenterLatLon(); + if (latlon != null) + { + Framework.nativeStopLocationFollow(); + Framework.nativeSetViewportCenter(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM); + // We need to update viewport for search api manually because of drape engine + // will not notify subscribers when search activity is shown. + if (!request.mIsSearchOnMap) + Framework.nativeSetSearchViewport(latlon[0], latlon[1], SEARCH_IN_VIEWPORT_ZOOM); + } + final SearchScreen.Builder builder = new SearchScreen.Builder(carContext, surfaceRenderer); + builder.setQuery(request.mQuery); + if (request.mLocale != null) + builder.setLocale(request.mLocale); - screenManager.popToRoot(); - screenManager.push(builder.build()); - return; - case RequestType.ROUTE: - Logger.e(TAG, "Route API is not supported by Android Auto: " + uri); - return; - case RequestType.CROSSHAIR: - Logger.e(TAG, "Crosshair API is not supported by Android Auto: " + uri); - return; - case RequestType.MENU: - Logger.e(TAG, "Menu API is not supported by Android Auto: " + uri); - return; - case RequestType.SETTINGS: - Logger.e(TAG, "Settings API is not supported by Android Auto: " + uri); + screenManager.popToRoot(); + screenManager.push(builder.build()); + return; + case RequestType.ROUTE: Logger.e(TAG, "Route API is not supported by Android Auto: " + uri); return; + case RequestType.CROSSHAIR: Logger.e(TAG, "Crosshair API is not supported by Android Auto: " + uri); return; + case RequestType.MENU: Logger.e(TAG, "Menu API is not supported by Android Auto: " + uri); return; + case RequestType.SETTINGS: Logger.e(TAG, "Settings API is not supported by Android Auto: " + uri); } } private static void processViewIntent(@NonNull CarContext carContext, @NonNull Intent intent) { final Uri uri = intent.getData(); - if (uri != null - && Const.API_SCHEME.equals(uri.getScheme()) + if (uri != null && Const.API_SCHEME.equals(uri.getScheme()) && CarAppService.API_CAR_HOST.equals(uri.getSchemeSpecificPart()) && CarAppService.ACTION_SHOW_NAVIGATION_SCREEN.equals(uri.getFragment())) { final ScreenManager screenManager = carContext.getCarService(ScreenManager.class); final Screen top = screenManager.getTop(); - final DisplayManager displayManager = DisplayManager.from(carContext); + final DisplayManager displayManager = MwmApplication.from(carContext).getDisplayManager(); if (!displayManager.isCarDisplayUsed()) displayManager.changeDisplay(DisplayType.Car); if (!(top instanceof NavigationScreen)) diff --git a/android/app/src/main/java/app/organicmaps/car/util/RoutingHelpers.java b/android/app/src/main/java/app/organicmaps/car/util/RoutingHelpers.java index d6829617c..345f22596 100644 --- a/android/app/src/main/java/app/organicmaps/car/util/RoutingHelpers.java +++ b/android/app/src/main/java/app/organicmaps/car/util/RoutingHelpers.java @@ -7,7 +7,6 @@ import androidx.car.app.model.Distance; import androidx.car.app.navigation.model.LaneDirection; import androidx.car.app.navigation.model.Maneuver; import androidx.core.graphics.drawable.IconCompat; - import app.organicmaps.sdk.routing.CarDirection; import app.organicmaps.sdk.routing.LaneWay; @@ -16,7 +15,7 @@ public final class RoutingHelpers private RoutingHelpers() {} @NonNull - public static Distance createDistance(@NonNull final app.organicmaps.util.Distance distance) + public static Distance createDistance(@NonNull final app.organicmaps.sdk.util.Distance distance) { int displayUnit = switch (distance.mUnits) { @@ -26,48 +25,32 @@ public final class RoutingHelpers default -> Distance.UNIT_METERS; }; - return Distance.create(distance.mDistance, displayUnit); + return Distance.create(distance.mDistance, displayUnit); } @NonNull public static LaneDirection createLaneDirection(@NonNull LaneWay laneWay, boolean isRecommended) { int shape = LaneDirection.SHAPE_UNKNOWN; - switch (laneWay) + shape = switch (laneWay) { - case REVERSE: - shape = LaneDirection.SHAPE_U_TURN_LEFT; - break; - case SHARP_LEFT: - shape = LaneDirection.SHAPE_SHARP_LEFT; - break; - case LEFT: - shape = LaneDirection.SHAPE_NORMAL_LEFT; - break; - case SLIGHT_LEFT: - case MERGE_TO_LEFT: - shape = LaneDirection.SHAPE_SLIGHT_LEFT; - break; - case SLIGHT_RIGHT: - case MERGE_TO_RIGHT: - shape = LaneDirection.SHAPE_SLIGHT_RIGHT; - break; - case THROUGH: - shape = LaneDirection.SHAPE_STRAIGHT; - break; - case RIGHT: - shape = LaneDirection.SHAPE_NORMAL_RIGHT; - break; - case SHARP_RIGHT: - shape = LaneDirection.SHAPE_SHARP_RIGHT; - break; - } + case REVERSE -> LaneDirection.SHAPE_U_TURN_LEFT; + case SHARP_LEFT -> LaneDirection.SHAPE_SHARP_LEFT; + case LEFT -> LaneDirection.SHAPE_NORMAL_LEFT; + case SLIGHT_LEFT, MERGE_TO_LEFT -> LaneDirection.SHAPE_SLIGHT_LEFT; + case SLIGHT_RIGHT, MERGE_TO_RIGHT -> LaneDirection.SHAPE_SLIGHT_RIGHT; + case THROUGH -> LaneDirection.SHAPE_STRAIGHT; + case RIGHT -> LaneDirection.SHAPE_NORMAL_RIGHT; + case SHARP_RIGHT -> LaneDirection.SHAPE_SHARP_RIGHT; + default -> shape; + }; - return LaneDirection.create(shape, isRecommended); + return LaneDirection.create(shape, isRecommended); } @NonNull - public static Maneuver createManeuver(@NonNull final CarContext context, @NonNull CarDirection carDirection, int roundaboutExitNum) + public static Maneuver createManeuver(@NonNull final CarContext context, @NonNull CarDirection carDirection, + int roundaboutExitNum) { int maneuverType = switch (carDirection) { @@ -81,14 +64,13 @@ public final class RoutingHelpers case U_TURN_LEFT -> Maneuver.TYPE_U_TURN_LEFT; case U_TURN_RIGHT -> Maneuver.TYPE_U_TURN_RIGHT; // TODO (AndrewShkrob): add support for CW (clockwise) directions - case ENTER_ROUND_ABOUT, STAY_ON_ROUND_ABOUT, LEAVE_ROUND_ABOUT -> - Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW; + case ENTER_ROUND_ABOUT, STAY_ON_ROUND_ABOUT, LEAVE_ROUND_ABOUT -> Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW; case START_AT_THE_END_OF_STREET -> Maneuver.TYPE_DEPART; case REACHED_YOUR_DESTINATION -> Maneuver.TYPE_DESTINATION; case EXIT_HIGHWAY_TO_LEFT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_LEFT; case EXIT_HIGHWAY_TO_RIGHT -> Maneuver.TYPE_OFF_RAMP_SLIGHT_RIGHT; }; - final Maneuver.Builder builder = new Maneuver.Builder(maneuverType); + final Maneuver.Builder builder = new Maneuver.Builder(maneuverType); if (maneuverType == Maneuver.TYPE_ROUNDABOUT_ENTER_AND_EXIT_CCW) builder.setRoundaboutExitNumber(roundaboutExitNum > 0 ? roundaboutExitNum : 1); builder.setIcon(new CarIcon.Builder(IconCompat.createWithResource(context, carDirection.getTurnRes())).build()); diff --git a/android/app/src/main/java/app/organicmaps/car/util/RoutingUtils.java b/android/app/src/main/java/app/organicmaps/car/util/RoutingUtils.java index ff88b958e..a677c5d4b 100644 --- a/android/app/src/main/java/app/organicmaps/car/util/RoutingUtils.java +++ b/android/app/src/main/java/app/organicmaps/car/util/RoutingUtils.java @@ -2,7 +2,6 @@ package app.organicmaps.car.util; import android.graphics.Bitmap; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.car.app.CarContext; @@ -13,14 +12,13 @@ import androidx.car.app.navigation.model.Step; import androidx.car.app.navigation.model.TravelEstimate; import androidx.car.app.navigation.model.Trip; import androidx.core.graphics.drawable.IconCompat; - -import app.organicmaps.bookmarks.data.MapObject; +import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.routing.LaneWay; import app.organicmaps.sdk.routing.RoutingInfo; import app.organicmaps.sdk.routing.SingleLaneInfo; +import app.organicmaps.sdk.util.Distance; import app.organicmaps.util.Graphics; import app.organicmaps.widget.LanesDrawable; - import java.time.ZonedDateTime; import java.util.Objects; @@ -29,7 +27,8 @@ public final class RoutingUtils private RoutingUtils() {} @NonNull - public static Trip createTrip(@NonNull final CarContext context, @Nullable final RoutingInfo info, @Nullable MapObject endPoint) + public static Trip createTrip(@NonNull final CarContext context, @Nullable final RoutingInfo info, + @Nullable MapObject endPoint) { final Trip.Builder builder = new Trip.Builder(); @@ -51,12 +50,13 @@ public final class RoutingUtils else destinationBuilder.setName(" "); - builder.addDestination(destinationBuilder.build(), createTravelEstimate(info.distToTarget, info.totalTimeInSeconds)); + builder.addDestination(destinationBuilder.build(), + createTravelEstimate(info.distToTarget, info.totalTimeInSeconds)); // TODO (AndrewShkrob): Use real distance and time estimates builder.addStep(createCurrentStep(context, info), createTravelEstimate(info.distToTurn, 0)); if (!TextUtils.isEmpty(info.nextStreet)) - builder.addStep(createNextStep(context, info), createTravelEstimate(app.organicmaps.util.Distance.EMPTY, 0)); + builder.addStep(createNextStep(context, info), createTravelEstimate(Distance.EMPTY, 0)); return builder.build(); } @@ -96,7 +96,7 @@ public final class RoutingUtils @SuppressWarnings("NewApi") // ZonedDateTime is backported for Android versions below 8.0. @NonNull - private static TravelEstimate createTravelEstimate(@NonNull app.organicmaps.util.Distance distance, int time) + private static TravelEstimate createTravelEstimate(@NonNull Distance distance, int time) { return new TravelEstimate.Builder(RoutingHelpers.createDistance(distance), ZonedDateTime.now().plusSeconds(time)) .setRemainingTimeSeconds(time) diff --git a/android/app/src/main/java/app/organicmaps/car/util/SuggestionsHelpers.java b/android/app/src/main/java/app/organicmaps/car/util/SuggestionsHelpers.java index 40a75755c..b576cd277 100644 --- a/android/app/src/main/java/app/organicmaps/car/util/SuggestionsHelpers.java +++ b/android/app/src/main/java/app/organicmaps/car/util/SuggestionsHelpers.java @@ -6,10 +6,8 @@ import androidx.car.app.model.CarIcon; import androidx.car.app.suggestion.SuggestionManager; import androidx.car.app.suggestion.model.Suggestion; import androidx.core.graphics.drawable.IconCompat; - import app.organicmaps.R; import app.organicmaps.sdk.search.SearchRecents; - import java.util.ArrayList; import java.util.List; @@ -22,11 +20,13 @@ public final class SuggestionsHelpers context.getCarService(SuggestionManager.class).updateSuggestions(createSuggestionsList(context)); } - // TODO: Currently utilizing search history entries; potential future addition to include "Home" and "Work" marks once supported. + // TODO: Currently utilizing search history entries; potential future addition to include "Home" and "Work" marks once + // supported. @NonNull private static List createSuggestionsList(@NonNull final CarContext context) { - final CarIcon iconRecent = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_search_recent)).build(); + final CarIcon iconRecent = + new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_search_recent)).build(); final List suggestions = new ArrayList<>(); SearchRecents.refresh(); diff --git a/android/app/src/main/java/app/organicmaps/car/util/ThemeUtils.java b/android/app/src/main/java/app/organicmaps/car/util/ThemeUtils.java index 957c73cd5..20b688d83 100644 --- a/android/app/src/main/java/app/organicmaps/car/util/ThemeUtils.java +++ b/android/app/src/main/java/app/organicmaps/car/util/ThemeUtils.java @@ -3,13 +3,10 @@ package app.organicmaps.car.util; import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; - import androidx.annotation.NonNull; import androidx.annotation.StringRes; import androidx.annotation.UiThread; import androidx.car.app.CarContext; - -import app.organicmaps.Framework; import app.organicmaps.R; import app.organicmaps.routing.RoutingController; import app.organicmaps.sdk.MapStyle; @@ -59,7 +56,8 @@ public final class ThemeUtils @UiThread public static void update(@NonNull CarContext context, @NonNull ThemeMode oldThemeMode) { - final ThemeMode newThemeMode = oldThemeMode == ThemeMode.AUTO ? (context.isDarkMode() ? ThemeMode.NIGHT : ThemeMode.LIGHT) : oldThemeMode; + final ThemeMode newThemeMode = + oldThemeMode == ThemeMode.AUTO ? (context.isDarkMode() ? ThemeMode.NIGHT : ThemeMode.LIGHT) : oldThemeMode; MapStyle newMapStyle; if (newThemeMode == ThemeMode.NIGHT) diff --git a/android/app/src/main/java/app/organicmaps/car/util/Toggle.java b/android/app/src/main/java/app/organicmaps/car/util/Toggle.java index b7365ae31..f00c0937f 100644 --- a/android/app/src/main/java/app/organicmaps/car/util/Toggle.java +++ b/android/app/src/main/java/app/organicmaps/car/util/Toggle.java @@ -9,7 +9,6 @@ import androidx.car.app.model.CarIcon; import androidx.car.app.model.OnClickListener; import androidx.car.app.model.Row; import androidx.core.graphics.drawable.IconCompat; - import app.organicmaps.R; public final class Toggle @@ -20,7 +19,8 @@ public final class Toggle private static final int CHECKBOX_CHECKED_ICON = R.drawable.ic_checkbox_checked; @NonNull - public static Row create(@NonNull final CarContext context, @StringRes int title, @NonNull final OnClickListener onClickListener, boolean checked) + public static Row create(@NonNull final CarContext context, @StringRes int title, + @NonNull final OnClickListener onClickListener, boolean checked) { final Row.Builder row = new Row.Builder(); row.setTitle(context.getString(title)); @@ -34,16 +34,19 @@ public final class Toggle @RequiresCarApi(6) @NonNull - private static androidx.car.app.model.Toggle createToggle(@NonNull final OnClickListener onClickListener, boolean checked) + private static androidx.car.app.model.Toggle createToggle(@NonNull final OnClickListener onClickListener, + boolean checked) { return new androidx.car.app.model.Toggle.Builder((unused) -> onClickListener.onClick()).setChecked(checked).build(); } - private static void createCheckbox( - @NonNull final Row.Builder row, @NonNull final CarContext context, @NonNull final OnClickListener onClickListener, boolean checked) + private static void createCheckbox(@NonNull final Row.Builder row, @NonNull final CarContext context, + @NonNull final OnClickListener onClickListener, boolean checked) { row.setOnClickListener(onClickListener); - row.setImage(new CarIcon.Builder(IconCompat.createWithResource(context, checked ? CHECKBOX_CHECKED_ICON : CHECKBOX_ICON)).build()); + row.setImage( + new CarIcon.Builder(IconCompat.createWithResource(context, checked ? CHECKBOX_CHECKED_ICON : CHECKBOX_ICON)) + .build()); } private Toggle() {} diff --git a/android/app/src/main/java/app/organicmaps/car/util/UiHelpers.java b/android/app/src/main/java/app/organicmaps/car/util/UiHelpers.java index dc63b14b9..063041606 100644 --- a/android/app/src/main/java/app/organicmaps/car/util/UiHelpers.java +++ b/android/app/src/main/java/app/organicmaps/car/util/UiHelpers.java @@ -13,27 +13,27 @@ import androidx.car.app.model.CarIcon; import androidx.car.app.model.Row; import androidx.car.app.navigation.model.MapController; import androidx.core.graphics.drawable.IconCompat; - -import app.organicmaps.Map; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.bookmarks.data.Metadata; import app.organicmaps.car.SurfaceRenderer; import app.organicmaps.car.screens.base.BaseMapScreen; import app.organicmaps.car.screens.settings.SettingsScreen; -import app.organicmaps.editor.OpeningHours; -import app.organicmaps.editor.data.Timetable; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.LocationState; -import app.organicmaps.util.LocationUtils; +import app.organicmaps.sdk.Map; +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.bookmarks.data.Metadata; +import app.organicmaps.sdk.editor.OpeningHours; +import app.organicmaps.sdk.editor.data.Timetable; +import app.organicmaps.sdk.location.LocationHelper; +import app.organicmaps.sdk.location.LocationState; +import app.organicmaps.sdk.util.LocationUtils; import app.organicmaps.util.Utils; - import java.util.Calendar; public final class UiHelpers { @NonNull - public static ActionStrip createSettingsActionStrip(@NonNull BaseMapScreen mapScreen, @NonNull SurfaceRenderer surfaceRenderer) + public static ActionStrip createSettingsActionStrip(@NonNull BaseMapScreen mapScreen, + @NonNull SurfaceRenderer surfaceRenderer) { return new ActionStrip.Builder().addAction(createSettingsAction(mapScreen, surfaceRenderer)).build(); } @@ -47,7 +47,8 @@ public final class UiHelpers final Action panAction = new Action.Builder(Action.PAN).build(); final Action location = createLocationButton(context); final Action zoomIn = new Action.Builder().setIcon(iconPlus).setOnClickListener(surfaceRenderer::onZoomIn).build(); - final Action zoomOut = new Action.Builder().setIcon(iconMinus).setOnClickListener(surfaceRenderer::onZoomOut).build(); + final Action zoomOut = + new Action.Builder().setIcon(iconMinus).setOnClickListener(surfaceRenderer::onZoomOut).build(); return new ActionStrip.Builder() .addAction(panAction) .addAction(zoomIn) @@ -69,35 +70,42 @@ public final class UiHelpers } @NonNull - public static Action createSettingsActionForResult(@NonNull BaseMapScreen mapScreen, @NonNull SurfaceRenderer surfaceRenderer, @NonNull OnScreenResultListener onScreenResultListener) + public static Action createSettingsActionForResult(@NonNull BaseMapScreen mapScreen, + @NonNull SurfaceRenderer surfaceRenderer, + @NonNull OnScreenResultListener onScreenResultListener) { return createSettingsAction(mapScreen, surfaceRenderer, onScreenResultListener); } @NonNull - private static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, @NonNull SurfaceRenderer surfaceRenderer, @Nullable OnScreenResultListener onScreenResultListener) + private static Action createSettingsAction(@NonNull BaseMapScreen mapScreen, @NonNull SurfaceRenderer surfaceRenderer, + @Nullable OnScreenResultListener onScreenResultListener) { final CarContext context = mapScreen.getCarContext(); - final CarIcon iconSettings = new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_settings)).build(); + final CarIcon iconSettings = + new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_settings)).build(); - return new Action.Builder().setIcon(iconSettings).setOnClickListener(() -> { - // Action.onClickListener for the Screen A maybe called even if the Screen B is shown now. - // We need to check it - // This may happen when we use PopToRootHack: - // * ScreenManager.popToRoot() - // * The root screen (A) is shown for a while - // * User clicks on some action - // * ScreenManager.push(new Screen()) - // * New screen (B) is displayed now - // * Action.onClickListener is called for action from root screen (A) - if (mapScreen.getScreenManager().getTop() != mapScreen) - return; - final Screen settingsScreen = new SettingsScreen(context, surfaceRenderer); - if (onScreenResultListener != null) - mapScreen.getScreenManager().pushForResult(settingsScreen, onScreenResultListener); - else - mapScreen.getScreenManager().push(settingsScreen); - }).build(); + return new Action.Builder() + .setIcon(iconSettings) + .setOnClickListener(() -> { + // Action.onClickListener for the Screen A maybe called even if the Screen B is shown now. + // We need to check it + // This may happen when we use PopToRootHack: + // * ScreenManager.popToRoot() + // * The root screen (A) is shown for a while + // * User clicks on some action + // * ScreenManager.push(new Screen()) + // * New screen (B) is displayed now + // * Action.onClickListener is called for action from root screen (A) + if (mapScreen.getScreenManager().getTop() != mapScreen) + return; + final Screen settingsScreen = new SettingsScreen(context, surfaceRenderer); + if (onScreenResultListener != null) + mapScreen.getScreenManager().pushForResult(settingsScreen, onScreenResultListener); + else + mapScreen.getScreenManager().push(settingsScreen); + }) + .build(); } @Nullable @@ -111,7 +119,8 @@ public final class UiHelpers return null; final Row.Builder builder = new Row.Builder(); - builder.setImage(new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_operating_hours)).build()); + builder.setImage( + new CarIcon.Builder(IconCompat.createWithResource(context, R.drawable.ic_operating_hours)).build()); if (isEmptyTT) builder.setTitle(ohStr); @@ -158,29 +167,32 @@ public final class UiHelpers final int locationMode = Map.isEngineCreated() ? LocationState.getMode() : LocationState.NOT_FOLLOW_NO_POSITION; CarColor tintColor = Colors.DEFAULT; - @DrawableRes int drawableRes; + @DrawableRes + int drawableRes; switch (locationMode) { - case LocationState.PENDING_POSITION, LocationState.NOT_FOLLOW_NO_POSITION -> drawableRes = R.drawable.ic_location_off; - case LocationState.NOT_FOLLOW -> drawableRes = R.drawable.ic_not_follow; - case LocationState.FOLLOW -> - { - drawableRes = R.drawable.ic_follow; - tintColor = Colors.LOCATION_TINT; - } - case LocationState.FOLLOW_AND_ROTATE -> - { - drawableRes = R.drawable.ic_follow_and_rotate; - tintColor = Colors.LOCATION_TINT; - } - default -> throw new IllegalArgumentException("Invalid button mode: " + locationMode); + case LocationState.PENDING_POSITION, LocationState.NOT_FOLLOW_NO_POSITION -> + drawableRes = R.drawable.ic_location_off; + case LocationState.NOT_FOLLOW -> drawableRes = R.drawable.ic_not_follow; + case LocationState.FOLLOW -> + { + drawableRes = R.drawable.ic_follow; + tintColor = Colors.LOCATION_TINT; + } + case LocationState.FOLLOW_AND_ROTATE -> + { + drawableRes = R.drawable.ic_follow_and_rotate; + tintColor = Colors.LOCATION_TINT; + } + default -> throw new IllegalArgumentException("Invalid button mode: " + locationMode); } - final CarIcon icon = new CarIcon.Builder(IconCompat.createWithResource(context, drawableRes)).setTint(tintColor).build(); + final CarIcon icon = + new CarIcon.Builder(IconCompat.createWithResource(context, drawableRes)).setTint(tintColor).build(); builder.setIcon(icon); builder.setOnClickListener(() -> { LocationState.nativeSwitchToNextMode(); - final LocationHelper locationHelper = LocationHelper.from(context); + final LocationHelper locationHelper = MwmApplication.from(context).getLocationHelper(); if (!locationHelper.isActive() && LocationUtils.checkFineLocationPermission(context)) locationHelper.start(); }); diff --git a/android/app/src/main/java/app/organicmaps/car/util/UserActionRequired.java b/android/app/src/main/java/app/organicmaps/car/util/UserActionRequired.java index 0c20ecda6..da65b2051 100644 --- a/android/app/src/main/java/app/organicmaps/car/util/UserActionRequired.java +++ b/android/app/src/main/java/app/organicmaps/car/util/UserActionRequired.java @@ -3,5 +3,4 @@ package app.organicmaps.car.util; /// Marker interface for screens that require user action to proceed. /// These screens can't be dropped from AA's screen stack. public interface UserActionRequired -{ -} +{} diff --git a/android/app/src/main/java/app/organicmaps/dialog/EditTextDialogFragment.java b/android/app/src/main/java/app/organicmaps/dialog/EditTextDialogFragment.java index d317e955c..f29d2fc2e 100644 --- a/android/app/src/main/java/app/organicmaps/dialog/EditTextDialogFragment.java +++ b/android/app/src/main/java/app/organicmaps/dialog/EditTextDialogFragment.java @@ -10,21 +10,19 @@ import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; - import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.textfield.TextInputLayout; -import com.google.android.material.textfield.TextInputEditText; import app.organicmaps.R; import app.organicmaps.base.BaseMwmDialogFragment; +import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.util.InputUtils; -import app.organicmaps.util.StringUtils; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; public class EditTextDialogFragment extends BaseMwmDialogFragment { @@ -60,22 +58,22 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment } public static EditTextDialogFragment show(@Nullable String title, @Nullable String initialText, - @Nullable String positiveBtn, @Nullable String negativeBtn, - @NonNull Fragment parent, @Nullable Validator inputValidator) + @Nullable String positiveBtn, @Nullable String negativeBtn, + @NonNull Fragment parent, @Nullable Validator inputValidator) { return show(title, initialText, "", positiveBtn, negativeBtn, NO_LIMITED_TEXT_LENGTH, parent, inputValidator); } public static EditTextDialogFragment show(@Nullable String title, @Nullable String initialText, @Nullable String hint, - @Nullable String positiveBtn, @Nullable String negativeBtn, - @NonNull Fragment parent, @Nullable Validator inputValidator) + @Nullable String positiveBtn, @Nullable String negativeBtn, + @NonNull Fragment parent, @Nullable Validator inputValidator) { return show(title, initialText, hint, positiveBtn, negativeBtn, NO_LIMITED_TEXT_LENGTH, parent, inputValidator); } public static EditTextDialogFragment show(@Nullable String title, @Nullable String initialText, @Nullable String hint, - @Nullable String positiveBtn, @Nullable String negativeBtn, int textLimit, - @NonNull Fragment parent, @Nullable Validator inputValidator) + @Nullable String positiveBtn, @Nullable String negativeBtn, int textLimit, + @NonNull Fragment parent, @Nullable Validator inputValidator) { final Bundle args = new Bundle(); args.putString(ARG_TITLE, title); @@ -85,8 +83,8 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment args.putString(ARG_HINT, hint); args.putInt(ARG_TEXT_LENGTH_LIMIT, textLimit); FragmentManager fragmentManager = parent.getChildFragmentManager(); - final EditTextDialogFragment fragment = (EditTextDialogFragment) fragmentManager.getFragmentFactory() - .instantiate(parent.requireActivity().getClassLoader(), EditTextDialogFragment.class.getName()); + final EditTextDialogFragment fragment = (EditTextDialogFragment) fragmentManager.getFragmentFactory().instantiate( + parent.requireActivity().getClassLoader(), EditTextDialogFragment.class.getName()); fragment.setArguments(args); fragment.show(fragmentManager, EditTextDialogFragment.class.getName()); fragment.mInputValidator = inputValidator; @@ -117,13 +115,15 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment } AlertDialog editTextDialog = new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog) - .setView(buildView()) - .setNegativeButton(negativeButtonText, null) - .setPositiveButton(positiveButtonText, (dialog, which) -> { - final String result = mEtInput.getText().toString(); - processInput(result); - dismiss(); - }).create(); + .setView(buildView()) + .setNegativeButton(negativeButtonText, null) + .setPositiveButton(positiveButtonText, + (dialog, which) -> { + final String result = mEtInput.getText().toString(); + processInput(result); + dismiss(); + }) + .create(); // Wait till alert is shown to get mPositiveButton. editTextDialog.setOnShowListener((dialog) -> { @@ -135,8 +135,7 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment }); // Setup validation on input edit. - mEtInput.addTextChangedListener(new StringUtils.SimpleTextWatcher() - { + mEtInput.addTextChangedListener(new StringUtils.SimpleTextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { @@ -173,7 +172,8 @@ public class EditTextDialogFragment extends BaseMwmDialogFragment private View buildView() { - @SuppressLint("InflateParams") final View root = requireActivity().getLayoutInflater().inflate(R.layout.dialog_edit_text, null); + @SuppressLint("InflateParams") + final View root = requireActivity().getLayoutInflater().inflate(R.layout.dialog_edit_text, null); mEtInputLayout = root.findViewById(R.id.et__input_layout); mEtInput = mEtInputLayout.findViewById(R.id.et__input); mEtInput.setHint(TextUtils.isEmpty(mHint) ? getString(R.string.name) : mHint); diff --git a/android/app/src/main/java/app/organicmaps/downloader/BottomPanel.java b/android/app/src/main/java/app/organicmaps/downloader/BottomPanel.java index c3710c084..90c95e401 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/BottomPanel.java +++ b/android/app/src/main/java/app/organicmaps/downloader/BottomPanel.java @@ -1,14 +1,23 @@ package app.organicmaps.downloader; -import android.view.View; +import static app.organicmaps.sdk.downloader.CountryItem.STATUS_APPLYING; +import static app.organicmaps.sdk.downloader.CountryItem.STATUS_DONE; +import static app.organicmaps.sdk.downloader.CountryItem.STATUS_DOWNLOADABLE; +import static app.organicmaps.sdk.downloader.CountryItem.STATUS_ENQUEUED; +import static app.organicmaps.sdk.downloader.CountryItem.STATUS_FAILED; +import static app.organicmaps.sdk.downloader.CountryItem.STATUS_PARTLY; +import static app.organicmaps.sdk.downloader.CountryItem.STATUS_PROGRESS; +import static app.organicmaps.sdk.downloader.CountryItem.STATUS_UPDATABLE; +import android.view.View; +import app.organicmaps.R; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.downloader.UpdateInfo; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import com.google.android.material.button.MaterialButton; import com.google.android.material.floatingactionbutton.FloatingActionButton; -import app.organicmaps.R; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; - -import static app.organicmaps.downloader.CountryItem.*; class BottomPanel { @@ -16,8 +25,7 @@ class BottomPanel private final FloatingActionButton mFab; private final MaterialButton mButton; - private final View.OnClickListener mDownloadListener = new View.OnClickListener() - { + private final View.OnClickListener mDownloadListener = new View.OnClickListener() { @Override public void onClick(View v) { @@ -25,8 +33,7 @@ class BottomPanel } }; - private final View.OnClickListener mUpdateListener = new View.OnClickListener() - { + private final View.OnClickListener mUpdateListener = new View.OnClickListener() { @Override public void onClick(View v) { @@ -35,8 +42,7 @@ class BottomPanel } }; - private final View.OnClickListener mCancelListener = new View.OnClickListener() - { + private final View.OnClickListener mCancelListener = new View.OnClickListener() { @Override public void onClick(View v) { @@ -45,8 +51,7 @@ class BottomPanel } }; - private final View.OnClickListener mRetryListener = new View.OnClickListener() - { + private final View.OnClickListener mRetryListener = new View.OnClickListener() { @Override public void onClick(View v) { @@ -60,7 +65,7 @@ class BottomPanel mFab = frame.findViewById(R.id.fab); mFab.setOnClickListener(v -> { - if (mFragment.getAdapter() != null ) + if (mFragment.getAdapter() != null) mFragment.getAdapter().setAvailableMapsMode(); update(); }); @@ -70,8 +75,9 @@ class BottomPanel private void setUpdateAllState(UpdateInfo info) { - mButton.setText(StringUtils.formatUsingUsLocale("%s (%s)", mFragment.getString(R.string.downloader_update_all_button), - StringUtils.getFileSizeString(mFragment.requireContext(), info.totalSize))); + mButton.setText( + StringUtils.formatUsingUsLocale("%s (%s)", mFragment.getString(R.string.downloader_update_all_button), + StringUtils.getFileSizeString(mFragment.requireContext(), info.totalSize))); mButton.setOnClickListener(mUpdateListener); } @@ -113,7 +119,7 @@ class BottomPanel { UpdateInfo info = MapManager.nativeGetUpdateInfo(root); setUpdateAllState(info); - } // Special case for "Countries" node when no maps currently downloaded. + } // Special case for "Countries" node when no maps currently downloaded. case STATUS_DOWNLOADABLE, STATUS_DONE, STATUS_PARTLY -> show = false; case STATUS_PROGRESS, STATUS_APPLYING, STATUS_ENQUEUED -> setCancelState(); case STATUS_FAILED -> setRetryFailedStates(); diff --git a/android/app/src/main/java/app/organicmaps/downloader/CountrySuggestFragment.java b/android/app/src/main/java/app/organicmaps/downloader/CountrySuggestFragment.java index ccf8ed8b4..7a9b0155e 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/CountrySuggestFragment.java +++ b/android/app/src/main/java/app/organicmaps/downloader/CountrySuggestFragment.java @@ -7,21 +7,19 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; - import androidx.annotation.Nullable; import androidx.fragment.app.FragmentActivity; - -import com.google.android.material.button.MaterialButton; -import com.google.android.material.textview.MaterialTextView; - +import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.base.BaseMwmFragment; import app.organicmaps.base.BaseMwmFragmentActivity; -import app.organicmaps.location.LocationHelper; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.widget.WheelProgressView; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; - +import com.google.android.material.button.MaterialButton; +import com.google.android.material.textview.MaterialTextView; import java.util.List; public class CountrySuggestFragment extends BaseMwmFragment implements View.OnClickListener @@ -53,8 +51,7 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl super.onViewCreated(view, savedInstanceState); initViews(view); - mListenerSlot = MapManager.nativeSubscribe(new MapManager.StorageCallback() - { + mListenerSlot = MapManager.nativeSubscribe(new MapManager.StorageCallback() { @Override public void onStatusChanged(List data) { @@ -73,13 +70,9 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl switch (item.newStatus) { - case CountryItem.STATUS_FAILED: - updateViews(); - return; + case CountryItem.STATUS_FAILED: updateViews(); return; - case CountryItem.STATUS_DONE: - exitFragment(); - return; + case CountryItem.STATUS_DONE: exitFragment(); return; } break; @@ -115,7 +108,7 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl { super.onResume(); - Location loc = LocationHelper.from(requireContext()).getSavedLocation(); + Location loc = MwmApplication.from(requireContext()).getLocationHelper().getSavedLocation(); if (loc != null) { String id = MapManager.nativeFindCountry(loc.getLatitude(), loc.getLongitude()); @@ -138,9 +131,9 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl if (mCurrentCountry == null || !isAdded()) return; - mBtnDownloadMap.setText(StringUtils.formatUsingUsLocale("%1$s (%2$s)", - getString(R.string.downloader_download_map), - StringUtils.getFileSizeString(requireContext(), mCurrentCountry.totalSize))); + mBtnDownloadMap.setText( + StringUtils.formatUsingUsLocale("%1$s (%2$s)", getString(R.string.downloader_download_map), + StringUtils.getFileSizeString(requireContext(), mCurrentCountry.totalSize))); } private void initViews(View view) @@ -193,7 +186,8 @@ public class CountrySuggestFragment extends BaseMwmFragment implements View.OnCl private void updateProgress() { - String text = getString(R.string.downloader_downloading) + " " + StringUtils.formatPercent(mDownloadingCountry.progress / 100); + String text = getString(R.string.downloader_downloading) + " " + + StringUtils.formatPercent(mDownloadingCountry.progress / 100); mTvProgress.setText(text); mWpvDownloadProgress.setProgress(Math.round(mDownloadingCountry.progress)); } diff --git a/android/app/src/main/java/app/organicmaps/downloader/DownloaderActivity.java b/android/app/src/main/java/app/organicmaps/downloader/DownloaderActivity.java index 0f74beb58..710f66660 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/DownloaderActivity.java +++ b/android/app/src/main/java/app/organicmaps/downloader/DownloaderActivity.java @@ -1,9 +1,7 @@ package app.organicmaps.downloader; import androidx.fragment.app.Fragment; - import app.organicmaps.base.BaseMwmFragmentActivity; -import app.organicmaps.base.OnBackPressListener; public class DownloaderActivity extends BaseMwmFragmentActivity { @@ -14,12 +12,4 @@ public class DownloaderActivity extends BaseMwmFragmentActivity { return DownloaderFragment.class; } - - @Override - public void onBackPressed() - { - OnBackPressListener fragment = (OnBackPressListener)getSupportFragmentManager().findFragmentById(getFragmentContentResId()); - if (!fragment.onBackPressed()) - super.onBackPressed(); - } } diff --git a/android/app/src/main/java/app/organicmaps/downloader/DownloaderAdapter.java b/android/app/src/main/java/app/organicmaps/downloader/DownloaderAdapter.java index f265e91c1..56060f667 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/DownloaderAdapter.java +++ b/android/app/src/main/java/app/organicmaps/downloader/DownloaderAdapter.java @@ -11,24 +11,24 @@ import android.text.style.StyleSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - +import androidx.activity.OnBackPressedCallback; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - import app.organicmaps.MwmActivity; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.location.LocationHelper; import app.organicmaps.routing.RoutingController; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment; import app.organicmaps.util.bottomsheet.MenuBottomSheetItem; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textview.MaterialTextView; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -58,11 +58,21 @@ class DownloaderAdapter extends RecyclerView.Adapter> mCountryIndex = new HashMap<>(); - private final Stack mPath = new Stack<>(); // Holds navigation history. The last element is the current level. + private final Stack mPath = + new Stack<>(); // Holds navigation history. The last element is the current level. private int mListenerSlot; private CountryItem mSelectedItem; + private final OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(false) { + @Override + public void handleOnBackPressed() + { + goUpwards(); + setEnabled(canGoUpwards()); + } + }; + private static class GenericItem { @Nullable @@ -154,20 +164,16 @@ class DownloaderAdapter extends RecyclerView.Adapter lst = mCountryIndex.get(countryId); @@ -224,7 +230,6 @@ class DownloaderAdapter extends RecyclerView.Adapter getMenuItems() @@ -282,9 +287,7 @@ class DownloaderAdapter extends RecyclerView.Adapter items = new ArrayList<>(); switch (mSelectedItem.status) { - case CountryItem.STATUS_DOWNLOADABLE: - items.add(getDownloadMenuItem()); - break; + case CountryItem.STATUS_DOWNLOADABLE: items.add(getDownloadMenuItem()); break; case CountryItem.STATUS_UPDATABLE: items.add(getUpdateMenuItem()); @@ -323,7 +326,6 @@ class DownloaderAdapter extends RecyclerView.Adapter onCancelActionSelected(mSelectedItem)); + return new MenuBottomSheetItem(R.string.cancel, R.drawable.ic_cancel, () -> onCancelActionSelected(mSelectedItem)); } private class ItemViewHolder extends BaseInnerViewHolder @@ -371,8 +372,9 @@ class DownloaderAdapter extends RecyclerView.Adapter - processLongClick(); + case CountryItem.STATUS_DONE, CountryItem.STATUS_PROGRESS, CountryItem.STATUS_APPLYING, + CountryItem.STATUS_ENQUEUED -> + processLongClick(); case CountryItem.STATUS_DOWNLOADABLE, CountryItem.STATUS_PARTLY -> { if (clickOnStatus) @@ -382,7 +384,7 @@ class DownloaderAdapter extends RecyclerView.Adapter MapManager.warn3gAndRetry(mActivity, mItem.id, null); case CountryItem.STATUS_UPDATABLE -> - MapManager.warnOn3gUpdate(mActivity, mItem.id, () -> MapManager.startUpdate(mItem.id)); + MapManager.warnOn3gUpdate(mActivity, mItem.id, () -> MapManager.startUpdate(mItem.id)); default -> throw new IllegalArgumentException("Inappropriate item status: " + mItem.status); } } @@ -394,15 +396,13 @@ class DownloaderAdapter extends RecyclerView.Adapter lst = mCountryIndex.get(ci.id); if (lst != null) lst.add(ci); - else { + else + { lst = new ArrayList<>(); lst.add(ci); mCountryIndex.put(ci.id, lst); @@ -680,7 +680,7 @@ class DownloaderAdapter extends RecyclerView.Adapter - implements OnBackPressListener, - MenuBottomSheetFragment.MenuBottomSheetInterface + implements MenuBottomSheetFragment.MenuBottomSheetInterface { private DownloaderToolbarController mToolbarController; @@ -41,7 +38,9 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment startVoiceRecognitionForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> mToolbarController.onVoiceRecognitionResult(activityResult)); + final ActivityResultLauncher startVoiceRecognitionForResult = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), + activityResult -> mToolbarController.onVoiceRecognitionResult(activityResult)); private final RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() { @Override @@ -52,11 +51,8 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment data) { @@ -143,7 +138,8 @@ public class DownloaderFragment extends BaseMwmRecyclerFragment= Build.VERSION_CODES.TIRAMISU && - ContextCompat.checkSelfPermission(mContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && ContextCompat.checkSelfPermission(mContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED) { Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, skipping notification"); return; @@ -66,37 +65,40 @@ public class DownloaderNotifier var contentPendingIntent = getNotificationPendingIntent(countryId); final Notification notification = new NotificationCompat.Builder(mContext, CHANNEL_ID) - .setAutoCancel(true) - .setCategory(NotificationCompat.CATEGORY_ERROR) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setSmallIcon(R.drawable.ic_logo_small) - .setColor(ContextCompat.getColor(mContext, R.color.notification)) - .setContentTitle(title) - .setContentText(content) - .setShowWhen(true) - .setTicker(getTicker(mContext, title, content)) - .setContentIntent(contentPendingIntent) - .setOnlyAlertOnce(true) - .build(); + .setAutoCancel(true) + .setCategory(NotificationCompat.CATEGORY_ERROR) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setSmallIcon(R.drawable.ic_logo_small) + .setColor(ContextCompat.getColor(mContext, R.color.notification)) + .setContentTitle(title) + .setContentText(content) + .setShowWhen(true) + .setTicker(getTicker(mContext, title, content)) + .setContentIntent(contentPendingIntent) + .setOnlyAlertOnce(true) + .build(); Logger.i(TAG, "Notifying about failed map download"); final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(mContext); notificationManager.notify(NOTIFICATION_ID, notification); } - public void notifyProgress() { + public void notifyProgress() + { notifyProgress(null, 0, 0); } - public void notifyProgress(@Nullable String countryId, int maxProgress, int progress) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && - ContextCompat.checkSelfPermission(mContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED) + public void notifyProgress(@Nullable String countryId, int maxProgress, int progress) + { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && ContextCompat.checkSelfPermission(mContext, POST_NOTIFICATIONS) != PERMISSION_GRANTED) { Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, skipping notification"); return; } - NotificationManagerCompat.from(mContext).notify(NOTIFICATION_ID, buildProgressNotification(countryId, maxProgress, progress)); + NotificationManagerCompat.from(mContext).notify(NOTIFICATION_ID, + buildProgressNotification(countryId, maxProgress, progress)); } @NonNull @@ -122,17 +124,18 @@ public class DownloaderNotifier final String title = mContext.getString(R.string.app_name); return new NotificationCompat.Builder(mContext, CHANNEL_ID) - .setAutoCancel(true) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setSmallIcon(R.drawable.ic_logo_small) - .setColor(ContextCompat.getColor(mContext, R.color.notification)) - .setShowWhen(true) - .setContentTitle(title) - .setContentIntent(getNotificationPendingIntent(countryId)); + .setAutoCancel(true) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setSmallIcon(R.drawable.ic_logo_small) + .setColor(ContextCompat.getColor(mContext, R.color.notification)) + .setShowWhen(true) + .setContentTitle(title) + .setContentIntent(getNotificationPendingIntent(countryId)); } @NonNull - private PendingIntent getNotificationPendingIntent(@Nullable String countryId) { + private PendingIntent getNotificationPendingIntent(@Nullable String countryId) + { final int FLAG_IMMUTABLE = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? 0 : PendingIntent.FLAG_IMMUTABLE; final Intent contentIntent = MwmActivity.createShowMapIntent(mContext, countryId); contentIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -142,8 +145,8 @@ public class DownloaderNotifier @NonNull private static CharSequence getTicker(@NonNull Context context, @NonNull String title, @NonNull String content) { - @StringRes final int templateResId = StringUtils.isRtl() ? R.string.notification_ticker_rtl - : R.string.notification_ticker_ltr; + @StringRes + final int templateResId = StringUtils.isRtl() ? R.string.notification_ticker_rtl : R.string.notification_ticker_ltr; return context.getString(templateResId, title, content); } } diff --git a/android/app/src/main/java/app/organicmaps/downloader/DownloaderService.java b/android/app/src/main/java/app/organicmaps/downloader/DownloaderService.java index 225ae9411..4cf297587 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/DownloaderService.java +++ b/android/app/src/main/java/app/organicmaps/downloader/DownloaderService.java @@ -9,15 +9,14 @@ import android.content.Intent; import android.content.pm.ServiceInfo; import android.os.Build; import android.os.IBinder; - import androidx.annotation.Nullable; import androidx.core.app.ServiceCompat; import androidx.core.content.ContextCompat; - -import java.util.List; - import app.organicmaps.MwmApplication; -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.util.log.Logger; +import java.util.List; public class DownloaderService extends Service implements MapManager.StorageCallback { @@ -52,8 +51,7 @@ public class DownloaderService extends Service implements MapManager.StorageCall } catch (Exception e) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && - e instanceof ForegroundServiceStartNotAllowedException) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e instanceof ForegroundServiceStartNotAllowedException) { // App not in a valid state to start foreground service (e.g started from bg) Logger.e(TAG, "Not in a valid state to start foreground service", e); @@ -88,7 +86,8 @@ public class DownloaderService extends Service implements MapManager.StorageCall if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { stopForeground(Service.STOP_FOREGROUND_DETACH); - } else + } + else { stopForeground(false); } @@ -100,8 +99,8 @@ public class DownloaderService extends Service implements MapManager.StorageCall @Override public void onProgress(String countryId, long localSize, long remoteSize) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && - ContextCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && ContextCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED) { Logger.w(TAG, "Permission POST_NOTIFICATIONS is not granted, skipping notification"); return; diff --git a/android/app/src/main/java/app/organicmaps/downloader/DownloaderStatusIcon.java b/android/app/src/main/java/app/organicmaps/downloader/DownloaderStatusIcon.java index 196e9ee7f..4fabcca82 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/DownloaderStatusIcon.java +++ b/android/app/src/main/java/app/organicmaps/downloader/DownloaderStatusIcon.java @@ -2,16 +2,14 @@ package app.organicmaps.downloader; import android.util.SparseIntArray; import android.view.View; - import androidx.annotation.AttrRes; import androidx.annotation.DrawableRes; - -import com.google.android.material.imageview.ShapeableImageView; - import app.organicmaps.R; -import app.organicmaps.widget.WheelProgressView; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.UiUtils; +import app.organicmaps.widget.WheelProgressView; +import com.google.android.material.imageview.ShapeableImageView; public class DownloaderStatusIcon { @@ -66,8 +64,10 @@ public class DownloaderStatusIcon protected void updateIcon(CountryItem country) { - @AttrRes int iconAttr = selectIcon(country); - @DrawableRes int icon = resolveIcon(iconAttr); + @AttrRes + int iconAttr = selectIcon(country); + @DrawableRes + int icon = resolveIcon(iconAttr); mIcon.setImageResource(icon); } @@ -75,8 +75,8 @@ public class DownloaderStatusIcon public void update(CountryItem country) { boolean pending = (country.status == CountryItem.STATUS_ENQUEUED); - boolean inProgress = (country.status == CountryItem.STATUS_PROGRESS || - country.status == CountryItem.STATUS_APPLYING || pending); + boolean inProgress = + (country.status == CountryItem.STATUS_PROGRESS || country.status == CountryItem.STATUS_APPLYING || pending); UiUtils.showIf(inProgress, mProgress); UiUtils.showIf(!inProgress, mIcon); diff --git a/android/app/src/main/java/app/organicmaps/downloader/DownloaderToolbarController.java b/android/app/src/main/java/app/organicmaps/downloader/DownloaderToolbarController.java index fddbcbc91..e6b593b92 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/DownloaderToolbarController.java +++ b/android/app/src/main/java/app/organicmaps/downloader/DownloaderToolbarController.java @@ -4,10 +4,9 @@ import android.app.Activity; import android.content.Intent; import android.text.TextUtils; import android.view.View; - import app.organicmaps.R; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.widget.SearchToolbarController; -import app.organicmaps.util.UiUtils; class DownloaderToolbarController extends SearchToolbarController { diff --git a/android/app/src/main/java/app/organicmaps/downloader/OnmapDownloader.java b/android/app/src/main/java/app/organicmaps/downloader/OnmapDownloader.java index 6c07308c5..3f09d5bdc 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/OnmapDownloader.java +++ b/android/app/src/main/java/app/organicmaps/downloader/OnmapDownloader.java @@ -4,24 +4,22 @@ import android.location.Location; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; - -import com.google.android.material.button.MaterialButton; -import com.google.android.material.textview.MaterialTextView; - import app.organicmaps.MwmActivity; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.location.LocationHelper; import app.organicmaps.routing.RoutingController; -import app.organicmaps.util.Config; -import app.organicmaps.util.ConnectionState; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.ConnectionState; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener; import app.organicmaps.widget.WheelProgressView; - +import com.google.android.material.button.MaterialButton; +import com.google.android.material.textview.MaterialTextView; import java.util.List; public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener @@ -41,8 +39,7 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener @Nullable private CountryItem mCurrentCountry; - private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback() - { + private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback() { @Override public void onStatusChanged(List data) { @@ -78,15 +75,15 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener } }; - private final MapManager.CurrentCountryChangedListener mCountryChangedListener = new MapManager.CurrentCountryChangedListener() - { - @Override - public void onCurrentCountryChanged(String countryId) - { - mCurrentCountry = (TextUtils.isEmpty(countryId) ? null : CountryItem.fill(countryId)); - updateState(true); - } - }; + private final MapManager.CurrentCountryChangedListener mCountryChangedListener = + new MapManager.CurrentCountryChangedListener() { + @Override + public void onCurrentCountryChanged(String countryId) + { + mCurrentCountry = (TextUtils.isEmpty(countryId) ? null : CountryItem.fill(countryId)); + updateState(true); + } + }; public void updateState(boolean shouldAutoDownload) { @@ -95,7 +92,8 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener private static boolean isMapDownloading(@Nullable CountryItem country) { - if (country == null) return false; + if (country == null) + return false; boolean enqueued = country.status == CountryItem.STATUS_ENQUEUED; boolean progress = country.status == CountryItem.STATUS_PROGRESS; @@ -110,18 +108,16 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener private void updateStateInternal(boolean shouldAutoDownload) { - boolean showFrame = (mCurrentCountry != null && - !mCurrentCountry.present && - !RoutingController.get().isNavigating()); + boolean showFrame = + (mCurrentCountry != null && !mCurrentCountry.present && !RoutingController.get().isNavigating()); if (showFrame) { boolean enqueued = (mCurrentCountry.status == CountryItem.STATUS_ENQUEUED); - boolean progress = (mCurrentCountry.status == CountryItem.STATUS_PROGRESS || - mCurrentCountry.status == CountryItem.STATUS_APPLYING); + boolean progress = (mCurrentCountry.status == CountryItem.STATUS_PROGRESS + || mCurrentCountry.status == CountryItem.STATUS_APPLYING); boolean failed = (mCurrentCountry.status == CountryItem.STATUS_FAILED); - showFrame = (enqueued || progress || failed || - mCurrentCountry.status == CountryItem.STATUS_DOWNLOADABLE); + showFrame = (enqueued || progress || failed || mCurrentCountry.status == CountryItem.STATUS_DOWNLOADABLE); if (showFrame) { @@ -140,9 +136,11 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener if (progress) { + int roundedProgress = Math.round(mCurrentCountry.progress); mProgress.setPending(false); - mProgress.setProgress(Math.round(mCurrentCountry.progress)); - sizeText = mActivity.getString(R.string.downloader_downloading) + " " + StringUtils.formatPercent(mCurrentCountry.progress / 100); + mProgress.setProgress(roundedProgress); + sizeText = mActivity.getString(R.string.downloader_downloading) + " " + + StringUtils.formatPercent(roundedProgress / 100.0); } else { @@ -155,26 +153,22 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener { sizeText = StringUtils.getFileSizeString(mActivity.getApplicationContext(), mCurrentCountry.totalSize); - if (shouldAutoDownload && - Config.isAutodownloadEnabled() && - !sAutodownloadLocked && - !failed && - ConnectionState.INSTANCE.isWifiConnected()) + if (shouldAutoDownload && Config.isAutodownloadEnabled() && !sAutodownloadLocked && !failed + && ConnectionState.INSTANCE.isWifiConnected()) { - Location loc = LocationHelper.from(mActivity).getSavedLocation(); + Location loc = MwmApplication.from(mActivity).getLocationHelper().getSavedLocation(); if (loc != null) { String country = MapManager.nativeFindCountry(loc.getLatitude(), loc.getLongitude()); - if (TextUtils.equals(mCurrentCountry.id, country) && - MapManager.nativeHasSpaceToDownloadCountry(country)) + if (TextUtils.equals(mCurrentCountry.id, country) + && MapManager.nativeHasSpaceToDownloadCountry(country)) { MapManager.startDownload(mCurrentCountry.id); } } } - mButton.setText(failed ? R.string.downloader_retry - : R.string.download); + mButton.setText(failed ? R.string.downloader_retry : R.string.download); } } @@ -204,37 +198,39 @@ public class OnmapDownloader implements MwmActivity.LeftAnimationTrackListener MapManager.nativeCancel(mCurrentCountry.id); setAutodownloadLocked(true); }); - mButton.setOnClickListener(v -> MapManager.warnOn3g(mActivity, mCurrentCountry == null ? null : - mCurrentCountry.id, () -> { - if (mCurrentCountry == null) - return; + mButton.setOnClickListener( + v -> MapManager.warnOn3g(mActivity, mCurrentCountry == null ? null : mCurrentCountry.id, () -> { + if (mCurrentCountry == null) + return; - boolean retry = (mCurrentCountry.status == CountryItem.STATUS_FAILED); - if (retry) - { - MapManager.retryDownload(mCurrentCountry.id); - } - else - { - MapManager.startDownload(mCurrentCountry.id); - mActivity.requestPostNotificationsPermission(); - } - })); + boolean retry = (mCurrentCountry.status == CountryItem.STATUS_FAILED); + if (retry) + { + MapManager.retryDownload(mCurrentCountry.id); + } + else + { + MapManager.startDownload(mCurrentCountry.id); + mActivity.requestPostNotificationsPermission(); + } + })); ViewCompat.setOnApplyWindowInsetsListener(mFrame, PaddingInsetsListener.allSides()); } @Override - public void onTrackStarted(boolean collapsed) {} + public void onTrackStarted(boolean collapsed) + {} @Override - public void onTrackFinished(boolean collapsed) {} + public void onTrackFinished(boolean collapsed) + {} @Override public void onTrackLeftAnimation(float offset) { - ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)mFrame.getLayoutParams(); - lp.leftMargin = (int)offset; + ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) mFrame.getLayoutParams(); + lp.leftMargin = (int) offset; mFrame.setLayoutParams(lp); } diff --git a/android/app/src/main/java/app/organicmaps/editor/AdvancedTimetableFragment.java b/android/app/src/main/java/app/organicmaps/editor/AdvancedTimetableFragment.java index 580f5ca94..9a795fafd 100644 --- a/android/app/src/main/java/app/organicmaps/editor/AdvancedTimetableFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/AdvancedTimetableFragment.java @@ -7,24 +7,21 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.webkit.WebView; - import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmFragment; -import app.organicmaps.util.Constants; +import app.organicmaps.sdk.editor.OpeningHours; +import app.organicmaps.sdk.util.Constants; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Graphics; import app.organicmaps.util.InputUtils; -import app.organicmaps.util.UiUtils; - import com.google.android.material.imageview.ShapeableImageView; import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textview.MaterialTextView; -public class AdvancedTimetableFragment extends BaseMwmFragment - implements View.OnClickListener, TimetableProvider +public class AdvancedTimetableFragment extends BaseMwmFragment implements View.OnClickListener, TimetableProvider { private boolean mIsExampleShown; private TextInputEditText mInput; @@ -89,8 +86,9 @@ public class AdvancedTimetableFragment extends BaseMwmFragment private void setExampleDrawables(@DrawableRes int left, @DrawableRes int right) { - mExamplesTitle.setCompoundDrawablesRelativeWithIntrinsicBounds(Graphics.tint(requireActivity(), left, androidx.appcompat.R.attr.colorAccent), null, - Graphics.tint(requireActivity(), right, androidx.appcompat.R.attr.colorAccent), null); + mExamplesTitle.setCompoundDrawablesRelativeWithIntrinsicBounds( + Graphics.tint(requireActivity(), left, androidx.appcompat.R.attr.colorAccent), null, + Graphics.tint(requireActivity(), right, androidx.appcompat.R.attr.colorAccent), null); } @Override @@ -136,10 +134,10 @@ public class AdvancedTimetableFragment extends BaseMwmFragment if (input == null || listener == null) return; - input.addTextChangedListener(new TextWatcher() - { + input.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + public void beforeTextChanged(CharSequence s, int start, int count, int after) + {} @Override public void onTextChanged(CharSequence s, int start, int before, int count) diff --git a/android/app/src/main/java/app/organicmaps/editor/CuisineAdapter.java b/android/app/src/main/java/app/organicmaps/editor/CuisineAdapter.java index 6d4fd5209..0c392a262 100644 --- a/android/app/src/main/java/app/organicmaps/editor/CuisineAdapter.java +++ b/android/app/src/main/java/app/organicmaps/editor/CuisineAdapter.java @@ -4,15 +4,12 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - +import app.organicmaps.R; +import app.organicmaps.sdk.editor.Editor; import com.google.android.material.checkbox.MaterialCheckBox; import com.google.android.material.textview.MaterialTextView; - -import app.organicmaps.R; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; diff --git a/android/app/src/main/java/app/organicmaps/editor/CuisineFragment.java b/android/app/src/main/java/app/organicmaps/editor/CuisineFragment.java index 533250332..a1651bbc7 100644 --- a/android/app/src/main/java/app/organicmaps/editor/CuisineFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/CuisineFragment.java @@ -1,7 +1,6 @@ package app.organicmaps.editor; import androidx.annotation.NonNull; - import app.organicmaps.base.BaseMwmRecyclerFragment; public class CuisineFragment extends BaseMwmRecyclerFragment diff --git a/android/app/src/main/java/app/organicmaps/editor/EditorActivity.java b/android/app/src/main/java/app/organicmaps/editor/EditorActivity.java index 3f6606d11..ae62a6cae 100644 --- a/android/app/src/main/java/app/organicmaps/editor/EditorActivity.java +++ b/android/app/src/main/java/app/organicmaps/editor/EditorActivity.java @@ -2,10 +2,8 @@ package app.organicmaps.editor; import android.app.Activity; import android.content.Intent; - import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; - import app.organicmaps.base.BaseMwmFragmentActivity; public class EditorActivity extends BaseMwmFragmentActivity diff --git a/android/app/src/main/java/app/organicmaps/editor/EditorFragment.java b/android/app/src/main/java/app/organicmaps/editor/EditorFragment.java index fc2a858f7..2f9b02caa 100644 --- a/android/app/src/main/java/app/organicmaps/editor/EditorFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/EditorFragment.java @@ -8,7 +8,6 @@ import android.text.method.LinkMovementMethod; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.CallSuper; import androidx.annotation.DrawableRes; import androidx.annotation.IdRes; @@ -18,28 +17,27 @@ import androidx.annotation.StringRes; import androidx.appcompat.widget.SwitchCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.imageview.ShapeableImageView; -import com.google.android.material.textfield.TextInputLayout; -import com.google.android.material.textfield.TextInputEditText; -import com.google.android.material.textview.MaterialTextView; - -import app.organicmaps.Framework; import app.organicmaps.R; import app.organicmaps.base.BaseMwmFragment; -import app.organicmaps.bookmarks.data.Metadata; import app.organicmaps.dialog.EditTextDialogFragment; -import app.organicmaps.editor.data.LocalizedName; -import app.organicmaps.editor.data.LocalizedStreet; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.bookmarks.data.Metadata; +import app.organicmaps.sdk.editor.Editor; +import app.organicmaps.sdk.editor.OpeningHours; +import app.organicmaps.sdk.editor.data.LocalizedName; +import app.organicmaps.sdk.editor.data.LocalizedStreet; import app.organicmaps.editor.data.TimeFormatUtils; -import app.organicmaps.editor.data.Timetable; +import app.organicmaps.sdk.editor.data.Timetable; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.Utils; import app.organicmaps.util.Graphics; import app.organicmaps.util.InputUtils; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; -import app.organicmaps.util.Utils; - +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.imageview.ShapeableImageView; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; +import com.google.android.material.textview.MaterialTextView; import java.util.HashMap; import java.util.Map; @@ -56,8 +54,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe private RecyclerView mNamesView; - private final RecyclerView.AdapterDataObserver mNamesObserver = new RecyclerView.AdapterDataObserver() - { + private final RecyclerView.AdapterDataObserver mNamesObserver = new RecyclerView.AdapterDataObserver() { @Override public void onChanged() { @@ -119,8 +116,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe final MetadataEntry e = mMetadata.get(type); final int id = type.toInt(); e.mEdit.setText(Editor.nativeGetMetadata(id)); - e.mEdit.addTextChangedListener(new StringUtils.SimpleTextWatcher() - { + e.mEdit.addTextChangedListener(new StringUtils.SimpleTextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { @@ -162,26 +158,28 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe mStreet.setText(street.defaultName); mHouseNumber.setText(Editor.nativeGetHouseNumber()); - mHouseNumber.addTextChangedListener(new StringUtils.SimpleTextWatcher() - { + mHouseNumber.addTextChangedListener(new StringUtils.SimpleTextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { - UiUtils.setInputError(mInputHouseNumber, Editor.nativeIsHouseValid(s.toString()) ? 0 : R.string.error_enter_correct_house_number); + UiUtils.setInputError(mInputHouseNumber, + Editor.nativeIsHouseValid(s.toString()) ? 0 : R.string.error_enter_correct_house_number); } }); initMetadataEntry(Metadata.MetadataType.FMD_POSTCODE, R.string.error_enter_correct_zip_code); mBuildingLevels.setText(Editor.nativeGetBuildingLevels()); - mBuildingLevels.addTextChangedListener(new StringUtils.SimpleTextWatcher() - { + mBuildingLevels.addTextChangedListener(new StringUtils.SimpleTextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { final Context context = mInputBuildingLevels.getContext(); final boolean isValid = Editor.nativeIsLevelValid(s.toString()); - UiUtils.setInputError(mInputBuildingLevels, isValid ? null : context.getString(R.string.error_enter_correct_storey_number, Editor.nativeGetMaxEditableBuildingLevels())); + UiUtils.setInputError(mInputBuildingLevels, + isValid ? null + : context.getString(R.string.error_enter_correct_storey_number, + Editor.nativeGetMaxEditableBuildingLevels())); } }); @@ -205,7 +203,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe initMetadataEntry(Metadata.MetadataType.FMD_OPERATOR, 0); mWifi.setChecked(Editor.nativeHasWifi()); // TODO Reimplement this to avoid https://github.com/organicmaps/organicmaps/issues/9049 - //mOutdoorSeating.setChecked(Editor.nativeGetSwitchInput(Metadata.MetadataType.FMD_OUTDOOR_SEATING.toInt(),"yes")); + // mOutdoorSeating.setChecked(Editor.nativeGetSwitchInput(Metadata.MetadataType.FMD_OUTDOOR_SEATING.toInt(),"yes")); refreshOpeningTime(); refreshEditableFields(); refreshResetButton(); @@ -229,7 +227,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe Editor.nativeSetNames(mParent.getNamesAsArray()); // TODO Reimplement this to avoid https://github.com/organicmaps/organicmaps/issues/9049 - //Editor.nativeSetSwitchInput(Metadata.MetadataType.FMD_OUTDOOR_SEATING.toInt(), mOutdoorSeating.isChecked(), "yes", "no"); + // Editor.nativeSetSwitchInput(Metadata.MetadataType.FMD_OUTDOOR_SEATING.toInt(), mOutdoorSeating.isChecked(), + // "yes", "no"); for (var e : mMetadata.entrySet()) Editor.nativeSetMetadata(e.getKey().toInt(), e.getValue().mEdit.getText().toString()); @@ -314,7 +313,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe setCardVisibility(mCardSocialMedia, mSocialMediaBlocks, editableDetails); } - private void setCardVisibility(View card, Map blocks, int[] editableDetails) { + private void setCardVisibility(View card, Map blocks, int[] editableDetails) + { for (var e : blocks.entrySet()) UiUtils.hide(e.getValue()); @@ -343,9 +343,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe { final Timetable[] timetables = OpeningHours.nativeTimetablesFromString(openingHours); String content = timetables == null ? openingHours - : TimeFormatUtils.formatTimetables(getResources(), - openingHours, - timetables); + : TimeFormatUtils.formatTimetables(getResources(), openingHours, timetables); UiUtils.hide(mEmptyOpeningHours); UiUtils.setTextAndShow(mOpeningHours, content); UiUtils.show(mEditOpeningHours); @@ -396,8 +394,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe }); } - private View initBlock(View view, Metadata.MetadataType type, @IdRes int idBlock, - @DrawableRes int idIcon, @StringRes int idName, int inputType) + private View initBlock(View view, Metadata.MetadataType type, @IdRes int idBlock, @DrawableRes int idIcon, + @StringRes int idName, int inputType) { View block = view.findViewById(idBlock); MetadataEntry e = new MetadataEntry(); @@ -429,7 +427,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe mHouseNumber = findInputAndInitBlock(blockHouseNumber, R.drawable.ic_building, R.string.house_number); mInputHouseNumber = blockHouseNumber.findViewById(R.id.custom_input); - initBlock(view, Metadata.MetadataType.FMD_POSTCODE, R.id.block_zipcode, R.drawable.ic_address, R.string.editor_zip_code, 0); + initBlock(view, Metadata.MetadataType.FMD_POSTCODE, R.id.block_zipcode, R.drawable.ic_address, + R.string.editor_zip_code, 0); // Details View mBlockLevels = view.findViewById(R.id.block_levels); @@ -441,30 +440,37 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe mEditPhoneLink = blockPhone.findViewById(R.id.edit_phone); mEditPhoneLink.setOnClickListener(this); mPhone.setOnClickListener(this); - View websiteBlock = initBlock(view, Metadata.MetadataType.FMD_WEBSITE, R.id.block_website, - R.drawable.ic_website, R.string.website, InputType.TYPE_TEXT_VARIATION_URI); - View websiteMenuBlock = initBlock(view, Metadata.MetadataType.FMD_WEBSITE_MENU, R.id.block_website_menu, - R.drawable.ic_website_menu, R.string.website_menu, InputType.TYPE_TEXT_VARIATION_URI); - View emailBlock = initBlock(view, Metadata.MetadataType.FMD_EMAIL, R.id.block_email, - R.drawable.ic_email, R.string.email, InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); - View levelBlock = initBlock(view, Metadata.MetadataType.FMD_LEVEL, R.id.block_level, - R.drawable.ic_level_white, R.string.editor_level, InputType.TYPE_CLASS_NUMBER); - View fediverseContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_FEDIVERSE, R.id.block_fediverse, - R.drawable.ic_mastodon_white, R.string.mastodon, InputType.TYPE_TEXT_VARIATION_URI); - View facebookContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_FACEBOOK, R.id.block_facebook, - R.drawable.ic_facebook_white, R.string.facebook, InputType.TYPE_TEXT_VARIATION_URI); - View instagramContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_INSTAGRAM, R.id.block_instagram, - R.drawable.ic_instagram_white, R.string.instagram, InputType.TYPE_TEXT_VARIATION_URI); - View twitterContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_TWITTER, R.id.block_twitter, - R.drawable.ic_twitterx_white, R.string.twitter, InputType.TYPE_TEXT_VARIATION_URI); - View vkContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_VK, R.id.block_vk, - R.drawable.ic_vk_white, R.string.vk, InputType.TYPE_TEXT_VARIATION_URI); - View lineContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_LINE, R.id.block_line, - R.drawable.ic_line_white, R.string.editor_line_social_network, InputType.TYPE_TEXT_VARIATION_URI); - View blueskyContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky, - R.drawable.ic_bluesky_white, R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI); + View websiteBlock = initBlock(view, Metadata.MetadataType.FMD_WEBSITE, R.id.block_website, R.drawable.ic_website, + R.string.website, InputType.TYPE_TEXT_VARIATION_URI); + View websiteMenuBlock = + initBlock(view, Metadata.MetadataType.FMD_WEBSITE_MENU, R.id.block_website_menu, R.drawable.ic_website_menu, + R.string.website_menu, InputType.TYPE_TEXT_VARIATION_URI); + View emailBlock = initBlock(view, Metadata.MetadataType.FMD_EMAIL, R.id.block_email, R.drawable.ic_email, + R.string.email, InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); + View levelBlock = initBlock(view, Metadata.MetadataType.FMD_LEVEL, R.id.block_level, R.drawable.ic_level_white, + R.string.editor_level, InputType.TYPE_CLASS_NUMBER); + View fediverseContactBlock = + initBlock(view, Metadata.MetadataType.FMD_CONTACT_FEDIVERSE, R.id.block_fediverse, R.drawable.ic_mastodon_white, + R.string.mastodon, InputType.TYPE_TEXT_VARIATION_URI); + View facebookContactBlock = + initBlock(view, Metadata.MetadataType.FMD_CONTACT_FACEBOOK, R.id.block_facebook, R.drawable.ic_facebook_white, + R.string.facebook, InputType.TYPE_TEXT_VARIATION_URI); + View instagramContactBlock = + initBlock(view, Metadata.MetadataType.FMD_CONTACT_INSTAGRAM, R.id.block_instagram, + R.drawable.ic_instagram_white, R.string.instagram, InputType.TYPE_TEXT_VARIATION_URI); + View twitterContactBlock = + initBlock(view, Metadata.MetadataType.FMD_CONTACT_TWITTER, R.id.block_twitter, R.drawable.ic_twitterx_white, + R.string.twitter, InputType.TYPE_TEXT_VARIATION_URI); + View vkContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_VK, R.id.block_vk, R.drawable.ic_vk_white, + R.string.vk, InputType.TYPE_TEXT_VARIATION_URI); + View lineContactBlock = + initBlock(view, Metadata.MetadataType.FMD_CONTACT_LINE, R.id.block_line, R.drawable.ic_line_white, + R.string.editor_line_social_network, InputType.TYPE_TEXT_VARIATION_URI); + View blueskyContactBlock = + initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky, R.drawable.ic_bluesky_white, + R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI); View operatorBlock = initBlock(view, Metadata.MetadataType.FMD_OPERATOR, R.id.block_operator, - R.drawable.ic_operator, R.string.editor_operator, 0); + R.drawable.ic_operator, R.string.editor_operator, 0); View blockCuisine = view.findViewById(R.id.block_cuisine); blockCuisine.setOnClickListener(this); @@ -502,7 +508,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe mDetailsBlocks.put(Metadata.MetadataType.FMD_SELF_SERVICE, blockSelfService); // TODO Reimplement this to avoid https://github.com/organicmaps/organicmaps/issues/9049 UiUtils.hide(blockOutdoorSeating); - //mDetailsBlocks.put(Metadata.MetadataType.FMD_OUTDOOR_SEATING, blockOutdoorSeating); + // mDetailsBlocks.put(Metadata.MetadataType.FMD_OUTDOOR_SEATING, blockOutdoorSeating); mDetailsBlocks.put(Metadata.MetadataType.FMD_WEBSITE, websiteBlock); mDetailsBlocks.put(Metadata.MetadataType.FMD_WEBSITE_MENU, websiteMenuBlock); mDetailsBlocks.put(Metadata.MetadataType.FMD_EMAIL, emailBlock); @@ -575,14 +581,14 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe private void refreshNamesCaption() { if (mNamesAdapter.getNamesCount() <= mNamesAdapter.getMandatoryNamesCount()) - setNamesArrow(0 /* arrowResourceId */); // bind arrow with empty resource (do not draw arrow) + setNamesArrow(0 /* arrowResourceId */); // bind arrow with empty resource (do not draw arrow) else if (mNamesAdapter.areAdditionalLanguagesShown()) setNamesArrow(R.drawable.ic_expand_less); else setNamesArrow(R.drawable.ic_expand_more); - boolean showAddLanguage = mNamesAdapter.getNamesCount() <= mNamesAdapter.getMandatoryNamesCount() || - mNamesAdapter.areAdditionalLanguagesShown(); + boolean showAddLanguage = mNamesAdapter.getNamesCount() <= mNamesAdapter.getMandatoryNamesCount() + || mNamesAdapter.areAdditionalLanguagesShown(); UiUtils.showIf(showAddLanguage, mAddLanguage); UiUtils.showIf(!showAddLanguage, mMoreLanguages); @@ -598,10 +604,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe } mNamesCaption.setCompoundDrawablesRelativeWithIntrinsicBounds( - null, - null, - Graphics.tint(requireActivity(), arrowResourceId, R.attr.iconTint), - null); + null, null, Graphics.tint(requireActivity(), arrowResourceId, R.attr.iconTint), null); } private void refreshResetButton() @@ -623,10 +626,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe case Editor.CREATED -> mReset.setText(R.string.editor_remove_place_button); case Editor.MODIFIED -> mReset.setText(R.string.editor_reset_edits_button); case Editor.UNTOUCHED -> mReset.setText(R.string.editor_place_doesnt_exist); - case Editor.DELETED -> - throw new IllegalStateException("Can't delete already deleted feature."); - case Editor.OBSOLETE -> - throw new IllegalStateException("Obsolete objects cannot be reverted."); + case Editor.DELETED -> throw new IllegalStateException("Can't delete already deleted feature."); + case Editor.OBSOLETE -> throw new IllegalStateException("Obsolete objects cannot be reverted."); } } @@ -643,17 +644,17 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe case Editor.CREATED -> rollback(Editor.CREATED); case Editor.MODIFIED -> rollback(Editor.MODIFIED); case Editor.UNTOUCHED -> placeDoesntExist(); - case Editor.DELETED -> - throw new IllegalStateException("Can't delete already deleted feature."); - case Editor.OBSOLETE -> - throw new IllegalStateException("Obsolete objects cannot be reverted."); + case Editor.DELETED -> throw new IllegalStateException("Can't delete already deleted feature."); + case Editor.OBSOLETE -> throw new IllegalStateException("Obsolete objects cannot be reverted."); } } private void rollback(@Editor.FeatureStatus int status) { - @StringRes final int title; - @StringRes final int message; + @StringRes + final int title; + @StringRes + final int message; if (status == Editor.CREATED) { title = R.string.editor_remove_place_button; @@ -667,25 +668,22 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog) .setTitle(message) - .setPositiveButton(title, (dialog, which) -> { - Editor.nativeRollbackMapObject(); - Framework.nativePokeSearchInViewport(); - mParent.onBackPressed(); - }) + .setPositiveButton(title, + (dialog, which) -> { + Editor.nativeRollbackMapObject(); + Framework.nativePokeSearchInViewport(); + mParent.onBackPressed(); + }) .setNegativeButton(R.string.cancel, null) .show(); } private void placeDoesntExist() { - EditTextDialogFragment dialogFragment = - EditTextDialogFragment.show(getString(R.string.editor_place_doesnt_exist), - "", - getString(R.string.editor_comment_hint), - getString(R.string.editor_report_problem_send_button), - getString(R.string.cancel), - this, - getDeleteCommentValidator()); + EditTextDialogFragment dialogFragment = EditTextDialogFragment.show( + getString(R.string.editor_place_doesnt_exist), "", getString(R.string.editor_comment_hint), + getString(R.string.editor_report_problem_send_button), getString(R.string.cancel), this, + getDeleteCommentValidator()); dialogFragment.setTextSaveListener(this::commitPlaceDoesntExists); } @@ -698,7 +696,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe @NonNull private EditTextDialogFragment.Validator getDeleteCommentValidator() { - return (activity, text) -> { + return (activity, text) -> + { if (TextUtils.isEmpty(text)) return activity.getString(R.string.delete_place_empty_comment_error); else diff --git a/android/app/src/main/java/app/organicmaps/editor/EditorHostFragment.java b/android/app/src/main/java/app/organicmaps/editor/EditorHostFragment.java index 50e324ebd..3a7cab0c3 100644 --- a/android/app/src/main/java/app/organicmaps/editor/EditorHostFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/EditorHostFragment.java @@ -7,7 +7,6 @@ import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.CallSuper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -18,24 +17,25 @@ import androidx.fragment.app.FragmentManager; import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.base.BaseMwmToolbarFragment; -import app.organicmaps.bookmarks.data.Metadata; -import app.organicmaps.editor.data.Language; -import app.organicmaps.editor.data.LocalizedName; -import app.organicmaps.editor.data.LocalizedStreet; -import app.organicmaps.editor.data.NamesDataSource; import app.organicmaps.editor.data.PhoneFragment; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.bookmarks.data.Metadata; +import app.organicmaps.sdk.editor.Editor; +import app.organicmaps.sdk.editor.OsmOAuth; +import app.organicmaps.sdk.editor.data.Language; +import app.organicmaps.sdk.editor.data.LocalizedName; +import app.organicmaps.sdk.editor.data.LocalizedStreet; +import app.organicmaps.sdk.editor.data.NamesDataSource; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Utils; import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener; import app.organicmaps.widget.SearchToolbarController; import app.organicmaps.widget.ToolbarController; import com.google.android.material.dialog.MaterialAlertDialogBuilder; - import java.util.ArrayList; import java.util.List; -public class EditorHostFragment extends BaseMwmToolbarFragment implements View.OnClickListener, - LanguagesFragment.Listener +public class EditorHostFragment + extends BaseMwmToolbarFragment implements View.OnClickListener, LanguagesFragment.Listener { private boolean mIsNewObject; @Nullable @@ -129,8 +129,7 @@ public class EditorHostFragment extends BaseMwmToolbarFragment implements View.O mToolbarInnerLayout = toolbar.findViewById(R.id.toolbar_inner_layout); mSave = toolbar.findViewById(R.id.save); mSave.setOnClickListener(this); - UiUtils.setupHomeUpButtonAsNavigationIcon(getToolbarController().getToolbar(), - v -> onBackPressed()); + UiUtils.setupHomeUpButtonAsNavigationIcon(getToolbarController().getToolbar(), v -> onBackPressed()); if (getArguments() != null) mIsNewObject = getArguments().getBoolean(EditorActivity.EXTRA_NEW_OBJECT, false); @@ -152,8 +151,7 @@ public class EditorHostFragment extends BaseMwmToolbarFragment implements View.O @Override protected ToolbarController onCreateToolbarController(@NonNull View root) { - return new SearchToolbarController(root, requireActivity()) - { + return new SearchToolbarController(root, requireActivity()) { @Override protected void onTextChanged(String query) { @@ -196,12 +194,12 @@ public class EditorHostFragment extends BaseMwmToolbarFragment implements View.O if (focusToLastName) args.putInt(EditorFragment.LAST_INDEX_OF_NAMES_ARRAY, sNames.size() - 1); FragmentManager fragmentManager = getChildFragmentManager(); - final Fragment editorFragment = fragmentManager.getFragmentFactory() - .instantiate(requireActivity().getClassLoader(), EditorFragment.class.getName()); + final Fragment editorFragment = fragmentManager.getFragmentFactory().instantiate(requireActivity().getClassLoader(), + EditorFragment.class.getName()); editorFragment.setArguments(args); fragmentManager.beginTransaction() - .replace(R.id.fragment_container, editorFragment, EditorFragment.class.getName()) - .commit(); + .replace(R.id.fragment_container, editorFragment, EditorFragment.class.getName()) + .commit(); } protected void editTimetable() @@ -243,7 +241,8 @@ public class EditorHostFragment extends BaseMwmToolbarFragment implements View.O editWithFragment(Mode.LANGUAGE, R.string.choose_language, args, LanguagesFragment.class, false); } - private void editWithFragment(Mode newMode, @StringRes int toolbarTitle, @Nullable Bundle args, Class fragmentClass, boolean showSearch) + private void editWithFragment(Mode newMode, @StringRes int toolbarTitle, @Nullable Bundle args, + Class fragmentClass, boolean showSearch) { if (!setEdits()) return; @@ -252,11 +251,13 @@ public class EditorHostFragment extends BaseMwmToolbarFragment implements View.O getToolbarController().setTitle(toolbarTitle); showSearchControls(showSearch); FragmentManager fragmentManager = requireActivity().getSupportFragmentManager(); - final Fragment fragment = fragmentManager.getFragmentFactory().instantiate(requireActivity().getClassLoader(), fragmentClass.getName()); + final Fragment fragment = + fragmentManager.getFragmentFactory().instantiate(requireActivity().getClassLoader(), fragmentClass.getName()); fragment.setArguments(args); - getChildFragmentManager().beginTransaction() - .replace(R.id.fragment_container, fragment, fragmentClass.getName()) - .commit(); + getChildFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, fragment, fragmentClass.getName()) + .commit(); } private void showSearchControls(boolean showSearch) @@ -265,9 +266,8 @@ public class EditorHostFragment extends BaseMwmToolbarFragment implements View.O if (mToolbarInnerLayout != null && mSave != null) { // Make room for the toolbar title if the search controls are hidden. - mToolbarInnerLayout.getLayoutParams().width = showSearch - ? ViewGroup.LayoutParams.MATCH_PARENT - : mSave.getLayoutParams().width; + mToolbarInnerLayout.getLayoutParams().width = + showSearch ? ViewGroup.LayoutParams.MATCH_PARENT : mSave.getLayoutParams().width; } } @@ -285,20 +285,28 @@ public class EditorHostFragment extends BaseMwmToolbarFragment implements View.O { case OPENING_HOURS -> { - final String timetables = ((TimetableContainerFragment) getChildFragmentManager().findFragmentByTag(TimetableContainerFragment.class.getName())).getTimetable(); + final String timetables = ((TimetableContainerFragment) getChildFragmentManager().findFragmentByTag( + TimetableContainerFragment.class.getName())) + .getTimetable(); Editor.nativeSetOpeningHours(timetables); editMapObject(); } case STREET -> - setStreet(((StreetFragment) getChildFragmentManager().findFragmentByTag(StreetFragment.class.getName())).getStreet()); + setStreet(((StreetFragment) getChildFragmentManager().findFragmentByTag(StreetFragment.class.getName())) + .getStreet()); case CUISINE -> { - String[] cuisines = ((CuisineFragment) getChildFragmentManager().findFragmentByTag(CuisineFragment.class.getName())).getCuisines(); + String[] cuisines = + ((CuisineFragment) getChildFragmentManager().findFragmentByTag(CuisineFragment.class.getName())) + .getCuisines(); Editor.nativeSetSelectedCuisines(cuisines); editMapObject(); } case SELF_SERVICE -> - setSelection(Metadata.MetadataType.FMD_SELF_SERVICE, ((SelfServiceFragment) getChildFragmentManager().findFragmentByTag(SelfServiceFragment.class.getName())).getSelection()); + setSelection( + Metadata.MetadataType.FMD_SELF_SERVICE, + ((SelfServiceFragment) getChildFragmentManager().findFragmentByTag(SelfServiceFragment.class.getName())) + .getSelection()); case LANGUAGE -> editMapObject(); case MAP_OBJECT -> { @@ -318,7 +326,8 @@ public class EditorHostFragment extends BaseMwmToolbarFragment implements View.O } case PHONE -> { - final String phone = ((PhoneFragment) getChildFragmentManager().findFragmentByTag(PhoneFragment.class.getName())).getPhone(); + final String phone = + ((PhoneFragment) getChildFragmentManager().findFragmentByTag(PhoneFragment.class.getName())).getPhone(); if (Editor.nativeIsPhoneValid(phone)) { Editor.nativeSetPhone(phone); @@ -347,8 +356,7 @@ public class EditorHostFragment extends BaseMwmToolbarFragment implements View.O private void processEditedFeatures() { - Context context = requireContext(); - if (OsmOAuth.isAuthorized(context)) + if (OsmOAuth.isAuthorized()) { Utils.navigateToParent(requireActivity()); return; @@ -376,15 +384,14 @@ public class EditorHostFragment extends BaseMwmToolbarFragment implements View.O { new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog) .setTitle(R.string.editor_share_to_all_dialog_title) - .setMessage(getString(R.string.editor_share_to_all_dialog_message_1) - + " " + getString(R.string.editor_share_to_all_dialog_message_2)) - .setPositiveButton(android.R.string.ok, (dlg, which) -> { - MwmApplication.prefs(requireContext()).edit() - .putBoolean(NOOB_ALERT_SHOWN, true) - .apply(); - saveNote(); - saveMapObjectEdits(); - }) + .setMessage(getString(R.string.editor_share_to_all_dialog_message_1) + " " + + getString(R.string.editor_share_to_all_dialog_message_2)) + .setPositiveButton(android.R.string.ok, + (dlg, which) -> { + MwmApplication.prefs(requireContext()).edit().putBoolean(NOOB_ALERT_SHOWN, true).apply(); + saveNote(); + saveMapObjectEdits(); + }) .setNegativeButton(android.R.string.cancel, null) .show(); } diff --git a/android/app/src/main/java/app/organicmaps/editor/FeatureCategoryActivity.java b/android/app/src/main/java/app/organicmaps/editor/FeatureCategoryActivity.java index 09f08f5b8..750ebdb2b 100644 --- a/android/app/src/main/java/app/organicmaps/editor/FeatureCategoryActivity.java +++ b/android/app/src/main/java/app/organicmaps/editor/FeatureCategoryActivity.java @@ -1,13 +1,13 @@ package app.organicmaps.editor; import android.content.Intent; - import androidx.fragment.app.Fragment; - import app.organicmaps.base.BaseMwmFragmentActivity; -import app.organicmaps.editor.data.FeatureCategory; +import app.organicmaps.sdk.editor.Editor; +import app.organicmaps.sdk.editor.data.FeatureCategory; -public class FeatureCategoryActivity extends BaseMwmFragmentActivity implements FeatureCategoryFragment.FeatureCategoryListener +public class FeatureCategoryActivity + extends BaseMwmFragmentActivity implements FeatureCategoryFragment.FeatureCategoryListener { public static final String EXTRA_FEATURE_CATEGORY = "FeatureCategory"; diff --git a/android/app/src/main/java/app/organicmaps/editor/FeatureCategoryAdapter.java b/android/app/src/main/java/app/organicmaps/editor/FeatureCategoryAdapter.java index f55256d50..ad4eeb008 100644 --- a/android/app/src/main/java/app/organicmaps/editor/FeatureCategoryAdapter.java +++ b/android/app/src/main/java/app/organicmaps/editor/FeatureCategoryAdapter.java @@ -4,20 +4,16 @@ import android.text.method.LinkMovementMethod; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.textview.MaterialTextView; - import app.organicmaps.R; -import app.organicmaps.editor.data.FeatureCategory; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.editor.data.FeatureCategory; +import app.organicmaps.sdk.util.UiUtils; +import com.google.android.material.textview.MaterialTextView; public class FeatureCategoryAdapter extends RecyclerView.Adapter { - private static final int TYPE_CATEGORY = 0; private static final int TYPE_FOOTER = 1; @@ -25,7 +21,8 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter { - return new FeatureViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category, parent, false)); + switch (viewType) + { + case TYPE_CATEGORY -> + { + return new FeatureViewHolder( + LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category, parent, false)); } - case TYPE_FOOTER -> { - return new FooterViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category_footer, parent, false)); + case TYPE_FOOTER -> + { + return new FooterViewHolder( + LayoutInflater.from(parent.getContext()).inflate(R.layout.item_feature_category_footer, parent, false)); } default -> throw new IllegalArgumentException("Unsupported"); } @@ -95,15 +97,14 @@ public class FeatureCategoryAdapter extends RecyclerView.Adapter { mOkButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE); mOkButton.setOnClickListener(v -> { if (mSelectedTab == TAB_FROM) { - //noinspection ConstantConditions + // noinspection ConstantConditions mTabs.getTabAt(TAB_TO).select(); return; } @@ -142,17 +140,16 @@ public class HoursMinutesPickerFragment extends BaseMwmDialogFragment mTabs = root.findViewById(R.id.tabs); MaterialTextView tabView = (MaterialTextView) inflater.inflate(R.layout.tab_timepicker, mTabs, false); tabView.setText(getResources().getString(R.string.editor_time_from)); - final ColorStateList textColor = AppCompatResources.getColorStateList(requireContext(), - ThemeUtils.isNightTheme(requireContext()) ? R.color.accent_color_selector_night - : R.color.accent_color_selector); + final ColorStateList textColor = AppCompatResources.getColorStateList( + requireContext(), ThemeUtils.isNightTheme(requireContext()) ? R.color.accent_color_selector_night + : R.color.accent_color_selector); tabView.setTextColor(textColor); mTabs.addTab(mTabs.newTab().setCustomView(tabView), true); tabView = (MaterialTextView) inflater.inflate(R.layout.tab_timepicker, mTabs, false); tabView.setText(getResources().getString(R.string.editor_time_to)); tabView.setTextColor(textColor); mTabs.addTab(mTabs.newTab().setCustomView(tabView), true); - mTabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() - { + mTabs.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { @@ -167,10 +164,12 @@ public class HoursMinutesPickerFragment extends BaseMwmDialogFragment } @Override - public void onTabUnselected(TabLayout.Tab tab) {} + public void onTabUnselected(TabLayout.Tab tab) + {} @Override - public void onTabReselected(TabLayout.Tab tab) {} + public void onTabReselected(TabLayout.Tab tab) + {} }); return root; @@ -179,8 +178,8 @@ public class HoursMinutesPickerFragment extends BaseMwmDialogFragment private void saveHoursMinutes() { boolean is24HourFormat = DateUtils.is24HourFormat(requireContext()); - final HoursMinutes hoursMinutes = new HoursMinutes(mPicker.getCurrentHour(), - mPicker.getCurrentMinute(), is24HourFormat); + final HoursMinutes hoursMinutes = + new HoursMinutes(mPicker.getCurrentHour(), mPicker.getCurrentMinute(), is24HourFormat); if (mSelectedTab == TAB_FROM) mFrom = hoursMinutes; else diff --git a/android/app/src/main/java/app/organicmaps/editor/LanguagesAdapter.java b/android/app/src/main/java/app/organicmaps/editor/LanguagesAdapter.java index 97623fa7d..be0e0c481 100644 --- a/android/app/src/main/java/app/organicmaps/editor/LanguagesAdapter.java +++ b/android/app/src/main/java/app/organicmaps/editor/LanguagesAdapter.java @@ -3,14 +3,11 @@ package app.organicmaps.editor; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.textview.MaterialTextView; - import app.organicmaps.R; -import app.organicmaps.editor.data.Language; +import app.organicmaps.sdk.editor.data.Language; +import com.google.android.material.textview.MaterialTextView; public class LanguagesAdapter extends RecyclerView.Adapter { diff --git a/android/app/src/main/java/app/organicmaps/editor/LanguagesFragment.java b/android/app/src/main/java/app/organicmaps/editor/LanguagesFragment.java index 261eff5df..75ee40a7f 100644 --- a/android/app/src/main/java/app/organicmaps/editor/LanguagesFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/LanguagesFragment.java @@ -1,13 +1,11 @@ package app.organicmaps.editor; import android.os.Bundle; - import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; - import app.organicmaps.base.BaseMwmRecyclerFragment; -import app.organicmaps.editor.data.Language; - +import app.organicmaps.sdk.editor.Editor; +import app.organicmaps.sdk.editor.data.Language; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -15,7 +13,6 @@ import java.util.HashSet; import java.util.List; import java.util.Set; - public class LanguagesFragment extends BaseMwmRecyclerFragment { final static String EXISTING_LOCALIZED_NAMES = "ExistingLocalizedNames"; @@ -32,9 +29,8 @@ public class LanguagesFragment extends BaseMwmRecyclerFragment protected LanguagesAdapter createAdapter() { Bundle args = getArguments(); - Set existingLanguages = args != null - ? new HashSet<>(args.getStringArrayList(EXISTING_LOCALIZED_NAMES)) - : new HashSet<>(); + Set existingLanguages = + args != null ? new HashSet<>(args.getStringArrayList(EXISTING_LOCALIZED_NAMES)) : new HashSet<>(); List languages = new ArrayList<>(); for (Language lang : Editor.nativeGetSupportedLanguages(false)) diff --git a/android/app/src/main/java/app/organicmaps/editor/MultilanguageAdapter.java b/android/app/src/main/java/app/organicmaps/editor/MultilanguageAdapter.java index 1d781f56b..c4f226af0 100644 --- a/android/app/src/main/java/app/organicmaps/editor/MultilanguageAdapter.java +++ b/android/app/src/main/java/app/organicmaps/editor/MultilanguageAdapter.java @@ -3,19 +3,17 @@ package app.organicmaps.editor; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.textfield.TextInputLayout; -import com.google.android.material.textfield.TextInputEditText; import app.organicmaps.R; -import app.organicmaps.editor.data.Language; -import app.organicmaps.editor.data.LocalizedName; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.editor.Editor; +import app.organicmaps.sdk.editor.data.Language; +import app.organicmaps.sdk.editor.data.LocalizedName; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Utils; - +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; import java.util.List; public class MultilanguageAdapter extends RecyclerView.Adapter @@ -62,7 +60,10 @@ public class MultilanguageAdapter extends RecyclerView.Adapter { - // TODO(mgsergio): Implement item deletion. - // int position = getAdapterPosition(); - // mHostFragment.removeLocalizedName(position + 1); - // mNames.remove(position); - // notifyItemRemoved(position); - }); + itemView.findViewById(R.id.delete) + .setOnClickListener(v + -> { + // TODO(mgsergio): Implement item deletion. + // int position = getAdapterPosition(); + // mHostFragment.removeLocalizedName(position + 1); + // mNames.remove(position); + // notifyItemRemoved(position); + }); } } } diff --git a/android/app/src/main/java/app/organicmaps/editor/OhState.java b/android/app/src/main/java/app/organicmaps/editor/OhState.java index d302542b1..e957d9523 100644 --- a/android/app/src/main/java/app/organicmaps/editor/OhState.java +++ b/android/app/src/main/java/app/organicmaps/editor/OhState.java @@ -6,25 +6,25 @@ import androidx.annotation.Keep; @Keep public class OhState { - public enum State - { - Open, - Closed, - Unknown - } + public enum State + { + Open, + Closed, + Unknown + } - public State state; - /** Unix timestamp in seconds**/ - public long nextTimeOpen; - /** Unix timestamp in seconds **/ - public long nextTimeClosed; + public State state; + /** Unix timestamp in seconds**/ + public long nextTimeOpen; + /** Unix timestamp in seconds **/ + public long nextTimeClosed; - // Used by JNI. - @Keep - public OhState(State state, long nextTimeOpen, long nextTimeClosed) - { - this.state = state; - this.nextTimeOpen = nextTimeOpen; - this.nextTimeClosed = nextTimeClosed; - } -} \ No newline at end of file + // Used by JNI. + @Keep + public OhState(State state, long nextTimeOpen, long nextTimeClosed) + { + this.state = state; + this.nextTimeOpen = nextTimeOpen; + this.nextTimeClosed = nextTimeClosed; + } +} diff --git a/android/app/src/main/java/app/organicmaps/editor/OsmLoginActivity.java b/android/app/src/main/java/app/organicmaps/editor/OsmLoginActivity.java index 0e15133d1..42828a55d 100644 --- a/android/app/src/main/java/app/organicmaps/editor/OsmLoginActivity.java +++ b/android/app/src/main/java/app/organicmaps/editor/OsmLoginActivity.java @@ -3,10 +3,8 @@ package app.organicmaps.editor; import android.app.Activity; import android.content.Intent; import android.os.Bundle; - import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; - import app.organicmaps.base.BaseMwmFragmentActivity; public class OsmLoginActivity extends BaseMwmFragmentActivity diff --git a/android/app/src/main/java/app/organicmaps/editor/OsmLoginFragment.java b/android/app/src/main/java/app/organicmaps/editor/OsmLoginFragment.java index 761a40d27..f99bfa254 100644 --- a/android/app/src/main/java/app/organicmaps/editor/OsmLoginFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/OsmLoginFragment.java @@ -8,22 +8,19 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.ScrollView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; -import app.organicmaps.Framework; import app.organicmaps.R; import app.organicmaps.base.BaseMwmToolbarFragment; -import app.organicmaps.util.Constants; -import app.organicmaps.util.DateUtils; +import app.organicmaps.sdk.editor.OsmOAuth; +import app.organicmaps.sdk.util.Constants; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.concurrency.ThreadPool; +import app.organicmaps.sdk.util.concurrency.UiThread; import app.organicmaps.util.InputUtils; -import app.organicmaps.util.UiUtils; import app.organicmaps.util.Utils; import app.organicmaps.util.WindowInsetUtils.ScrollableContentInsetsListener; -import app.organicmaps.util.concurrency.ThreadPool; -import app.organicmaps.util.concurrency.UiThread; - import com.google.android.material.button.MaterialButton; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textfield.TextInputEditText; @@ -55,20 +52,19 @@ public class OsmLoginFragment extends BaseMwmToolbarFragment MaterialButton registerButton = view.findViewById(R.id.register); registerButton.setOnClickListener((v) -> Utils.openUrl(requireActivity(), Constants.Url.OSM_REGISTER)); mProgress = view.findViewById(R.id.osm_login_progress); - final String dataVersion = DateUtils.getShortDateFormatter().format(Framework.getDataVersion()); // TODO(@pastk): remove unused flow with users entering credentials into app's form // Hide login and password inputs and Forgot password button - UiUtils.hide(view.findViewById(R.id.osm_username_container), - view.findViewById(R.id.osm_password_container), - mLostPasswordButton); + UiUtils.hide(view.findViewById(R.id.osm_username_container), view.findViewById(R.id.osm_password_container), + mLostPasswordButton); mLoginButton.setOnClickListener((v) -> loginWithBrowser()); /* login via in-app form else { mLoginButton.setOnClickListener((v) -> login()); - mLostPasswordButton.setOnClickListener((v) -> Utils.openUrl(requireActivity(), Constants.Url.OSM_RECOVER_PASSWORD)); + mLostPasswordButton.setOnClickListener((v) -> Utils.openUrl(requireActivity(), + Constants.Url.OSM_RECOVER_PASSWORD)); } */ @@ -142,7 +138,7 @@ public class OsmLoginFragment extends BaseMwmToolbarFragment private void onAuthSuccess(String oauthToken, String username) { - OsmOAuth.setAuthorization(requireContext(), oauthToken, username); + OsmOAuth.setAuthorization(oauthToken, username); final Bundle extras = requireActivity().getIntent().getExtras(); if (extras != null && extras.getBoolean("redirectToProfile", false)) startActivity(new Intent(requireContext(), ProfileActivity.class)); @@ -159,15 +155,11 @@ public class OsmLoginFragment extends BaseMwmToolbarFragment onAuthFail(); else { - ThreadPool.getWorker().execute(() -> - { + ThreadPool.getWorker().execute(() -> { // Finish OAuth2 auth flow and get username for UI. final String oauthToken = OsmOAuth.nativeAuthWithOAuth2Code(oauth2code); final String username = (oauthToken == null) ? null : OsmOAuth.nativeGetOsmUsername(oauthToken); - UiThread.run(() -> - { - processAuth(oauthToken, username); - }); + UiThread.run(() -> processAuth(oauthToken, username)); }); } } diff --git a/android/app/src/main/java/app/organicmaps/editor/OsmOAuth.java b/android/app/src/main/java/app/organicmaps/editor/OsmOAuth.java deleted file mode 100644 index 264be509b..000000000 --- a/android/app/src/main/java/app/organicmaps/editor/OsmOAuth.java +++ /dev/null @@ -1,166 +0,0 @@ -package app.organicmaps.editor; - -import android.content.Context; -import android.content.SharedPreferences; -import android.graphics.Bitmap; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.Size; -import androidx.annotation.WorkerThread; -import androidx.fragment.app.FragmentManager; - -import app.organicmaps.MwmApplication; -import app.organicmaps.util.NetworkPolicy; - -public final class OsmOAuth -{ - private OsmOAuth() {} - - public enum AuthType - { - OSM("OSM"), - GOOGLE("Google"); - - public final String name; - - AuthType(String name) - { - this.name = name; - } - } - - public static final int OK = 0; - - private static final String PREF_OSM_TOKEN = "OsmToken"; // Unused after migration from OAuth1 to OAuth2 - private static final String PREF_OSM_SECRET = "OsmSecret"; // Unused after migration from OAuth1 to OAuth2 - private static final String PREF_OSM_USERNAME = "OsmUsername"; - private static final String PREF_OSM_CHANGESETS_COUNT = "OsmChangesetsCount"; - private static final String PREF_OSM_OAUTH2_TOKEN = "OsmOAuth2Token"; - - public static final String URL_PARAM_VERIFIER = "oauth_verifier"; - - public static boolean isAuthorized(@NonNull Context context) - { - return MwmApplication.prefs(context).contains(PREF_OSM_OAUTH2_TOKEN); - } - - public static boolean containsOAuth1Credentials(@NonNull Context context) - { - SharedPreferences prefs = MwmApplication.prefs(context); - return prefs.contains(PREF_OSM_TOKEN) && prefs.contains(PREF_OSM_SECRET); - } - - public static void clearOAuth1Credentials(@NonNull Context context) - { - MwmApplication.prefs(context).edit() - .remove(PREF_OSM_TOKEN) - .remove(PREF_OSM_SECRET) - .apply(); - } - - public static String getAuthToken(@NonNull Context context) - { - return MwmApplication.prefs(context).getString(PREF_OSM_OAUTH2_TOKEN, ""); - } - - public static String getUsername(@NonNull Context context) - { - return MwmApplication.prefs(context).getString(PREF_OSM_USERNAME, ""); - } - - public static Bitmap getProfilePicture(@NonNull Context context) - { - //TODO(HB): load and store image in cache here - return null; - } - - public static void setAuthorization(@NonNull Context context, String oauthToken, String username) - { - MwmApplication.prefs(context).edit() - .putString(PREF_OSM_OAUTH2_TOKEN, oauthToken) - .putString(PREF_OSM_USERNAME, username) - .apply(); - } - - public static void clearAuthorization(@NonNull Context context) - { - MwmApplication.prefs(context).edit() - .remove(PREF_OSM_TOKEN) - .remove(PREF_OSM_SECRET) - .remove(PREF_OSM_USERNAME) - .remove(PREF_OSM_OAUTH2_TOKEN) - .apply(); - } - - public static String getHistoryUrl(@NonNull Context context) - { - return nativeGetHistoryUrl(getUsername(context)); - } - - public static String getNotesUrl(@NonNull Context context) - { - return nativeGetNotesUrl(getUsername(context)); - } - - /* - Returns 5 strings: ServerURL, ClientId, ClientSecret, Scope, RedirectUri - */ - @NonNull - public static native String nativeGetOAuth2Url(); - - /** - * @return string with OAuth2 token - */ - @WorkerThread - @Size(2) - @Nullable - public static native String nativeAuthWithPassword(String login, String password); - - /** - * @return string with OAuth2 token - */ - @WorkerThread - @Nullable - public static native String nativeAuthWithOAuth2Code(String oauth2code); - - @WorkerThread - @Nullable - public static native String nativeGetOsmUsername(String oauthToken); - - @WorkerThread - @Nullable - public static native String nativeGetOsmProfilePictureUrl(String oauthToken); - - @WorkerThread - @NonNull - public static native String nativeGetHistoryUrl(String user); - - @WorkerThread - @NonNull - public static native String nativeGetNotesUrl(String user); - - /** - * @return < 0 if failed to get changesets count. - */ - @WorkerThread - private static native int nativeGetOsmChangesetsCount(String oauthToken); - - @WorkerThread - public static int getOsmChangesetsCount(@NonNull Context context, @NonNull FragmentManager fm) { - final int[] editsCount = {-1}; - NetworkPolicy.checkNetworkPolicy(fm, policy -> { - if (!policy.canUseNetwork()) - return; - - final String token = getAuthToken(context); - editsCount[0] = OsmOAuth.nativeGetOsmChangesetsCount(token); - }); - final SharedPreferences prefs = MwmApplication.prefs(context); - if (editsCount[0] < 0) - return prefs.getInt(PREF_OSM_CHANGESETS_COUNT, 0); - - prefs.edit().putInt(PREF_OSM_CHANGESETS_COUNT, editsCount[0]).apply(); - return editsCount[0]; - } -} diff --git a/android/app/src/main/java/app/organicmaps/editor/PhoneListAdapter.java b/android/app/src/main/java/app/organicmaps/editor/PhoneListAdapter.java index a49084391..b4e22b1c2 100644 --- a/android/app/src/main/java/app/organicmaps/editor/PhoneListAdapter.java +++ b/android/app/src/main/java/app/organicmaps/editor/PhoneListAdapter.java @@ -4,17 +4,15 @@ import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.imageview.ShapeableImageView; -import com.google.android.material.textfield.TextInputLayout; -import com.google.android.material.textfield.TextInputEditText; import app.organicmaps.R; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; - +import app.organicmaps.sdk.editor.Editor; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; +import com.google.android.material.imageview.ShapeableImageView; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; import java.util.ArrayList; import java.util.List; @@ -34,19 +32,20 @@ public class PhoneListAdapter extends RecyclerView.Adapter Utils.openUrl(requireActivity(), getString(R.string.osm_wiki_about_url))); - view.findViewById(R.id.osm_history).setOnClickListener((v) -> Utils.openUrl(requireActivity(), OsmOAuth.getHistoryUrl(requireContext()))); - view.findViewById(R.id.osm_notes).setOnClickListener((v) -> Utils.openUrl(requireActivity(), OsmOAuth.getNotesUrl(requireContext()))); + view.findViewById(R.id.about_osm) + .setOnClickListener((v) -> Utils.openUrl(requireActivity(), getString(R.string.osm_wiki_about_url))); + view.findViewById(R.id.osm_history) + .setOnClickListener((v) -> Utils.openUrl(requireActivity(), OsmOAuth.getHistoryUrl())); + view.findViewById(R.id.osm_notes) + .setOnClickListener((v) -> Utils.openUrl(requireActivity(), OsmOAuth.getNotesUrl())); View buttonsContainer = view.findViewById(R.id.buttons_container); ViewCompat.setOnApplyWindowInsetsListener( buttonsContainer, - new WindowInsetUtils.PaddingInsetsListener - .Builder() + new WindowInsetUtils.PaddingInsetsListener.Builder() .setInsetsTypeMask(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout()) .setExcludeTop() .build()); @@ -74,7 +75,7 @@ public class ProfileFragment extends BaseMwmToolbarFragment private void refreshViews() { - if (OsmOAuth.isAuthorized(requireContext())) + if (OsmOAuth.isAuthorized()) { // Update the number of uploaded changesets from OSM. ThreadPool.getWorker().execute(() -> { @@ -83,9 +84,9 @@ public class ProfileFragment extends BaseMwmToolbarFragment UiUtils.show(mProfileInfoLoading); UiUtils.hide(mUserInfoBlock); } - final int profileEditCount = OsmOAuth.getOsmChangesetsCount(requireContext(), getParentFragmentManager()); - final String profileUsername = OsmOAuth.getUsername(requireContext()); - final Bitmap profilePicture = OsmOAuth.getProfilePicture(requireContext()); + final int profileEditCount = OsmOAuth.getOsmChangesetsCount(getParentFragmentManager()); + final String profileUsername = OsmOAuth.getUsername(); + final Bitmap profilePicture = OsmOAuth.getProfilePicture(); UiThread.run(() -> { mEditsSent.setText(NumberFormat.getInstance().format(profileEditCount)); @@ -115,11 +116,11 @@ public class ProfileFragment extends BaseMwmToolbarFragment { new MaterialAlertDialogBuilder(requireContext(), R.style.MwmTheme_AlertDialog) .setMessage(R.string.osm_log_out_confirmation) - .setPositiveButton(R.string.yes, (dialog, which) -> - { - OsmOAuth.clearAuthorization(requireContext()); - refreshViews(); - }) + .setPositiveButton(R.string.yes, + (dialog, which) -> { + OsmOAuth.clearAuthorization(); + refreshViews(); + }) .setNegativeButton(R.string.no, null) .show(); } diff --git a/android/app/src/main/java/app/organicmaps/editor/ReportActivity.java b/android/app/src/main/java/app/organicmaps/editor/ReportActivity.java index 3579e5b8b..96b250faf 100644 --- a/android/app/src/main/java/app/organicmaps/editor/ReportActivity.java +++ b/android/app/src/main/java/app/organicmaps/editor/ReportActivity.java @@ -1,7 +1,6 @@ package app.organicmaps.editor; import androidx.fragment.app.Fragment; - import app.organicmaps.base.BaseMwmFragmentActivity; public class ReportActivity extends BaseMwmFragmentActivity diff --git a/android/app/src/main/java/app/organicmaps/editor/ReportFragment.java b/android/app/src/main/java/app/organicmaps/editor/ReportFragment.java index 995d91656..a041ea44d 100644 --- a/android/app/src/main/java/app/organicmaps/editor/ReportFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/ReportFragment.java @@ -5,13 +5,13 @@ import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import app.organicmaps.R; import app.organicmaps.base.BaseMwmToolbarFragment; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.editor.Editor; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.WindowInsetUtils.ScrollableContentInsetsListener; import com.google.android.material.textfield.TextInputEditText; @@ -44,8 +44,8 @@ public class ReportFragment extends BaseMwmToolbarFragment implements View.OnCli mSave.setOnClickListener(this); mSimpleProblems = view.findViewById(R.id.ll__problems); mSimpleProblems.findViewById(R.id.problem_not_exist).setOnClickListener(this); -// mSimpleProblems.findViewById(R.id.problem_closed_repair).setOnClickListener(this); -// mSimpleProblems.findViewById(R.id.problem_duplicated_place).setOnClickListener(this); + // mSimpleProblems.findViewById(R.id.problem_closed_repair).setOnClickListener(this); + // mSimpleProblems.findViewById(R.id.problem_duplicated_place).setOnClickListener(this); mSimpleProblems.findViewById(R.id.problem_other).setOnClickListener(this); mAdvancedProblem = view.findViewById(R.id.ll__other_problem); mProblemInput = mAdvancedProblem.findViewById(R.id.input); diff --git a/android/app/src/main/java/app/organicmaps/editor/SelfServiceAdapter.java b/android/app/src/main/java/app/organicmaps/editor/SelfServiceAdapter.java index e9810e3d6..aa4efae8a 100644 --- a/android/app/src/main/java/app/organicmaps/editor/SelfServiceAdapter.java +++ b/android/app/src/main/java/app/organicmaps/editor/SelfServiceAdapter.java @@ -4,23 +4,19 @@ import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - +import app.organicmaps.R; +import app.organicmaps.sdk.util.Utils; import com.google.android.material.radiobutton.MaterialRadioButton; import com.google.android.material.textview.MaterialTextView; -import app.organicmaps.R; -import app.organicmaps.util.Utils; - public class SelfServiceAdapter extends RecyclerView.Adapter { - private final String[] mItems = new String[]{"yes", "only", "partially", "no"}; + private final String[] mItems = new String[] {"yes", "only", "partially", "no"}; private final SelfServiceFragment mFragment; private String mSelectedOption; - public SelfServiceAdapter(@NonNull SelfServiceFragment host, @NonNull String selected) { mFragment = host; @@ -35,7 +31,8 @@ public class SelfServiceAdapter extends RecyclerView.Adapter { diff --git a/android/app/src/main/java/app/organicmaps/editor/SimpleTimetableAdapter.java b/android/app/src/main/java/app/organicmaps/editor/SimpleTimetableAdapter.java index f019b941b..0b2d20002 100644 --- a/android/app/src/main/java/app/organicmaps/editor/SimpleTimetableAdapter.java +++ b/android/app/src/main/java/app/organicmaps/editor/SimpleTimetableAdapter.java @@ -6,33 +6,29 @@ import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.LinearLayout; - import androidx.annotation.IdRes; import androidx.annotation.IntRange; import androidx.annotation.Nullable; import androidx.appcompat.widget.SwitchCompat; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; - +import app.organicmaps.R; +import app.organicmaps.sdk.editor.OpeningHours; +import app.organicmaps.sdk.editor.data.HoursMinutes; +import app.organicmaps.editor.data.TimeFormatUtils; +import app.organicmaps.sdk.editor.data.Timespan; +import app.organicmaps.sdk.editor.data.Timetable; +import app.organicmaps.sdk.util.UiUtils; import com.google.android.material.button.MaterialButton; import com.google.android.material.checkbox.MaterialCheckBox; import com.google.android.material.textview.MaterialTextView; - -import app.organicmaps.R; -import app.organicmaps.editor.data.HoursMinutes; -import app.organicmaps.editor.data.TimeFormatUtils; -import app.organicmaps.editor.data.Timespan; -import app.organicmaps.editor.data.Timetable; -import app.organicmaps.util.UiUtils; - import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.List; class SimpleTimetableAdapter extends RecyclerView.Adapter - implements HoursMinutesPickerFragment.OnPickListener, - TimetableProvider + implements HoursMinutesPickerFragment.OnPickListener, TimetableProvider { private static final int TYPE_TIMETABLE = 0; private static final int TYPE_ADD_TIMETABLE = 1; @@ -79,8 +75,9 @@ class SimpleTimetableAdapter extends RecyclerView.Adapter - implements TimetableProvider, - HoursMinutesPickerFragment.OnPickListener + implements TimetableProvider, HoursMinutesPickerFragment.OnPickListener { private SimpleTimetableAdapter mAdapter; @Nullable diff --git a/android/app/src/main/java/app/organicmaps/editor/StreetAdapter.java b/android/app/src/main/java/app/organicmaps/editor/StreetAdapter.java index 2ccc6bbf6..931e21dc7 100644 --- a/android/app/src/main/java/app/organicmaps/editor/StreetAdapter.java +++ b/android/app/src/main/java/app/organicmaps/editor/StreetAdapter.java @@ -4,18 +4,15 @@ import android.content.res.Resources; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.radiobutton.MaterialRadioButton; -import com.google.android.material.textview.MaterialTextView; - import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.dialog.EditTextDialogFragment; -import app.organicmaps.editor.data.LocalizedStreet; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.editor.data.LocalizedStreet; +import app.organicmaps.sdk.util.UiUtils; +import com.google.android.material.radiobutton.MaterialRadioButton; +import com.google.android.material.textview.MaterialTextView; public class StreetAdapter extends RecyclerView.Adapter { @@ -26,7 +23,8 @@ public class StreetAdapter extends RecyclerView.Adapter { @@ -67,7 +66,8 @@ public class StreetFragment extends BaseMwmRecyclerFragment @NonNull public static EditTextDialogFragment.Validator getStreetValidator() { - return (activity, text) -> { + return (activity, text) -> + { if (TextUtils.isEmpty(text)) return activity.getString(R.string.empty_street_name_error); else diff --git a/android/app/src/main/java/app/organicmaps/editor/TimetableContainerFragment.java b/android/app/src/main/java/app/organicmaps/editor/TimetableContainerFragment.java index 9b01da328..3012d0d88 100644 --- a/android/app/src/main/java/app/organicmaps/editor/TimetableContainerFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/TimetableContainerFragment.java @@ -7,16 +7,15 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmFragment; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.editor.OpeningHours; +import app.organicmaps.sdk.util.UiUtils; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textview.MaterialTextView; @@ -26,22 +25,31 @@ public class TimetableContainerFragment extends BaseMwmFragment implements Timet private enum Mode { - SIMPLE - { + SIMPLE { @NonNull - String getFragmentClassname() { return SimpleTimetableFragment.class.getName(); } + String getFragmentClassname() + { + return SimpleTimetableFragment.class.getName(); + } @StringRes - int getSwitchButtonLabel() { return R.string.editor_time_advanced; } + int getSwitchButtonLabel() + { + return R.string.editor_time_advanced; + } }, - ADVANCED - { + ADVANCED { @NonNull - String getFragmentClassname() { return AdvancedTimetableFragment.class.getName(); } + String getFragmentClassname() + { + return AdvancedTimetableFragment.class.getName(); + } @StringRes - int getSwitchButtonLabel() { return R.string.editor_time_simple; } + int getSwitchButtonLabel() + { + return R.string.editor_time_simple; + } - void setTimetableChangedListener(@NonNull Fragment fragment, - @NonNull TimetableChangedListener listener) + void setTimetableChangedListener(@NonNull Fragment fragment, @NonNull TimetableChangedListener listener) { ((AdvancedTimetableFragment) fragment).setTimetableChangedListener(listener); } @@ -51,10 +59,7 @@ public class TimetableContainerFragment extends BaseMwmFragment implements Timet abstract String getFragmentClassname(); @StringRes abstract int getSwitchButtonLabel(); - void setTimetableChangedListener(@NonNull Fragment fragment, - @NonNull TimetableChangedListener listener) - { - } + void setTimetableChangedListener(@NonNull Fragment fragment, @NonNull TimetableChangedListener listener) {} @NonNull static TimetableProvider getTimetableProvider(@NonNull Fragment fragment) { @@ -119,8 +124,8 @@ public class TimetableContainerFragment extends BaseMwmFragment implements Timet @Override public void onTimetableChanged(@Nullable String timetable) { - boolean isValidTimetable = TextUtils.isEmpty(timetable) - || OpeningHours.nativeTimetablesFromString(timetable) != null; + boolean isValidTimetable = + TextUtils.isEmpty(timetable) || OpeningHours.nativeTimetablesFromString(timetable) != null; UiUtils.showIf(isValidTimetable, mSwitchMode); UiUtils.showIf(isValidTimetable, mBottomBar); } @@ -140,8 +145,7 @@ public class TimetableContainerFragment extends BaseMwmFragment implements Timet private void switchMode() { - final String filledTimetables = mTimetableProvider != null ? mTimetableProvider.getTimetables() - : null; + final String filledTimetables = mTimetableProvider != null ? mTimetableProvider.getTimetables() : null; if (filledTimetables != null && !OpeningHours.nativeIsTimetableStringValid(filledTimetables)) { @@ -150,9 +154,9 @@ public class TimetableContainerFragment extends BaseMwmFragment implements Timet return; new MaterialAlertDialogBuilder(activity) - .setMessage(R.string.editor_correct_mistake) - .setPositiveButton(android.R.string.ok, null) - .show(); + .setMessage(R.string.editor_correct_mistake) + .setPositiveButton(android.R.string.ok, null) + .show(); return; } @@ -168,9 +172,10 @@ public class TimetableContainerFragment extends BaseMwmFragment implements Timet mMode = mode; mSwitchMode.setText(mMode.getSwitchButtonLabel()); - if (mFragments[mMode.ordinal()] == null) { - mFragments[mMode.ordinal()] = requireActivity().getSupportFragmentManager().getFragmentFactory() - .instantiate(requireActivity().getClassLoader(), mMode.getFragmentClassname()); + if (mFragments[mMode.ordinal()] == null) + { + mFragments[mMode.ordinal()] = requireActivity().getSupportFragmentManager().getFragmentFactory().instantiate( + requireActivity().getClassLoader(), mMode.getFragmentClassname()); } Fragment fragment = mFragments[mMode.ordinal()]; getChildFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).commit(); diff --git a/android/app/src/main/java/app/organicmaps/editor/TimetableProvider.java b/android/app/src/main/java/app/organicmaps/editor/TimetableProvider.java index 28ad4c8f6..7c44a5d86 100644 --- a/android/app/src/main/java/app/organicmaps/editor/TimetableProvider.java +++ b/android/app/src/main/java/app/organicmaps/editor/TimetableProvider.java @@ -4,6 +4,7 @@ import androidx.annotation.Nullable; interface TimetableProvider { - @Nullable String getTimetables(); + @Nullable + String getTimetables(); void setTimetables(@Nullable String timetables); } diff --git a/android/app/src/main/java/app/organicmaps/editor/data/PhoneFragment.java b/android/app/src/main/java/app/organicmaps/editor/data/PhoneFragment.java index 2707736e7..4e40d65fe 100644 --- a/android/app/src/main/java/app/organicmaps/editor/data/PhoneFragment.java +++ b/android/app/src/main/java/app/organicmaps/editor/data/PhoneFragment.java @@ -4,12 +4,10 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmFragment; import app.organicmaps.editor.PhoneListAdapter; @@ -56,7 +54,8 @@ public class PhoneFragment extends BaseMwmFragment implements View.OnClickListen { if (view.getId() == R.id.tv__append_phone) { - if (mAdapter != null) mAdapter.appendPhone(); + if (mAdapter != null) + mAdapter.appendPhone(); } } } diff --git a/android/app/src/main/java/app/organicmaps/editor/data/TimeFormatUtils.java b/android/app/src/main/java/app/organicmaps/editor/data/TimeFormatUtils.java index d9a40d894..f70b601af 100644 --- a/android/app/src/main/java/app/organicmaps/editor/data/TimeFormatUtils.java +++ b/android/app/src/main/java/app/organicmaps/editor/data/TimeFormatUtils.java @@ -1,13 +1,12 @@ package app.organicmaps.editor.data; import android.content.res.Resources; - import androidx.annotation.IntRange; import androidx.annotation.NonNull; - import app.organicmaps.R; +import app.organicmaps.sdk.editor.data.Timespan; +import app.organicmaps.sdk.editor.data.Timetable; import app.organicmaps.util.Utils; - import java.text.DateFormatSymbols; import java.util.Locale; @@ -59,7 +58,7 @@ public class TimeFormatUtils refreshWithCurrentLocale(); final StringBuilder builder = new StringBuilder(sShortWeekdays[weekdays[0]]); boolean iteratingRange; - for (int i = 1; i < weekdays.length; ) + for (int i = 1; i < weekdays.length;) { iteratingRange = (weekdays[i] == weekdays[i - 1] + 1); if (iteratingRange) @@ -84,7 +83,8 @@ public class TimeFormatUtils StringBuilder closedTextBuilder = new StringBuilder(); boolean firstLine = true; - for (Timespan cts: closedTimespans) { + for (Timespan cts : closedTimespans) + { if (!firstLine) closedTextBuilder.append('\n'); @@ -107,8 +107,8 @@ public class TimeFormatUtils return resources.getString(R.string.twentyfour_seven); if (tt.closedTimespans == null || tt.closedTimespans.length == 0) return resources.getString(R.string.daily) + " " + tt.workingTimespan.toWideString(); - return resources.getString(R.string.daily) + " " + tt.workingTimespan.toWideString() + - "\n" + formatNonBusinessTime(tt.closedTimespans, resources.getString(R.string.editor_hours_closed)); + return resources.getString(R.string.daily) + " " + tt.workingTimespan.toWideString() + "\n" + + formatNonBusinessTime(tt.closedTimespans, resources.getString(R.string.editor_hours_closed)); } // Generate full week multiline string. E.g. @@ -123,14 +123,13 @@ public class TimeFormatUtils weekSchedule.append('\n'); final String weekdays = formatWeekdays(tt); - final String openTime = tt.isFullday ? - Utils.unCapitalize(resources.getString(R.string.editor_time_allday)) : - tt.workingTimespan.toWideString(); + final String openTime = tt.isFullday ? Utils.unCapitalize(resources.getString(R.string.editor_time_allday)) + : tt.workingTimespan.toWideString(); weekSchedule.append(weekdays).append(' ').append(openTime); if (tt.closedTimespans != null && tt.closedTimespans.length > 0) - weekSchedule.append('\n') - .append(formatNonBusinessTime(tt.closedTimespans, resources.getString(R.string.editor_hours_closed))); + weekSchedule.append('\n').append( + formatNonBusinessTime(tt.closedTimespans, resources.getString(R.string.editor_hours_closed))); firstRow = false; } diff --git a/android/app/src/main/java/app/organicmaps/help/CopyrightFragment.java b/android/app/src/main/java/app/organicmaps/help/CopyrightFragment.java index 38f3d0737..4ebfd7703 100644 --- a/android/app/src/main/java/app/organicmaps/help/CopyrightFragment.java +++ b/android/app/src/main/java/app/organicmaps/help/CopyrightFragment.java @@ -5,14 +5,12 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.Nullable; - import androidx.core.view.ViewCompat; import app.organicmaps.R; import app.organicmaps.WebContainerDelegate; import app.organicmaps.base.BaseMwmFragment; -import app.organicmaps.util.Constants; +import app.organicmaps.sdk.util.Constants; import app.organicmaps.util.WindowInsetUtils; public class CopyrightFragment extends BaseMwmFragment @@ -26,8 +24,7 @@ public class CopyrightFragment extends BaseMwmFragment ViewCompat.setOnApplyWindowInsetsListener(root, WindowInsetUtils.PaddingInsetsListener.excludeTop()); - mDelegate = new WebContainerDelegate(root, Constants.Url.COPYRIGHT) - { + mDelegate = new WebContainerDelegate(root, Constants.Url.COPYRIGHT) { @Override protected void doStartActivity(Intent intent) { diff --git a/android/app/src/main/java/app/organicmaps/help/FaqFragment.java b/android/app/src/main/java/app/organicmaps/help/FaqFragment.java index b0c329c44..94585eaca 100644 --- a/android/app/src/main/java/app/organicmaps/help/FaqFragment.java +++ b/android/app/src/main/java/app/organicmaps/help/FaqFragment.java @@ -7,7 +7,6 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -15,7 +14,7 @@ import androidx.core.view.ViewCompat; import app.organicmaps.R; import app.organicmaps.WebContainerDelegate; import app.organicmaps.base.BaseMwmFragment; -import app.organicmaps.util.Constants; +import app.organicmaps.sdk.util.Constants; import app.organicmaps.util.SharingUtils; import app.organicmaps.util.Utils; import app.organicmaps.util.WindowInsetUtils; @@ -27,8 +26,7 @@ public class FaqFragment extends BaseMwmFragment private ActivityResultLauncher shareLauncher; @NonNull - private final DialogInterface.OnClickListener mDialogClickListener = new DialogInterface.OnClickListener() - { + private final DialogInterface.OnClickListener mDialogClickListener = new DialogInterface.OnClickListener() { private void sendGeneralFeedback() { Utils.sendFeedback(shareLauncher, requireActivity()); @@ -57,8 +55,7 @@ public class FaqFragment extends BaseMwmFragment ViewCompat.setOnApplyWindowInsetsListener(root, WindowInsetUtils.PaddingInsetsListener.excludeTop()); - new WebContainerDelegate(root, Constants.Url.FAQ) - { + new WebContainerDelegate(root, Constants.Url.FAQ) { @Override protected void doStartActivity(Intent intent) { @@ -67,12 +64,14 @@ public class FaqFragment extends BaseMwmFragment }; FloatingActionButton feedbackFab = root.findViewById(R.id.feedback_fab); - feedbackFab.setOnClickListener(v -> new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog) - .setTitle(R.string.feedback) - .setNegativeButton(R.string.cancel, null) - .setItems(new CharSequence[] { getString(R.string.feedback_general), getString(R.string.report_a_bug) }, - mDialogClickListener) - .show()); + feedbackFab.setOnClickListener( + v + -> new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog) + .setTitle(R.string.feedback) + .setNegativeButton(R.string.cancel, null) + .setItems(new CharSequence[] {getString(R.string.feedback_general), getString(R.string.report_a_bug)}, + mDialogClickListener) + .show()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { diff --git a/android/app/src/main/java/app/organicmaps/help/HelpActivity.java b/android/app/src/main/java/app/organicmaps/help/HelpActivity.java index 2afd13132..3af92e7aa 100644 --- a/android/app/src/main/java/app/organicmaps/help/HelpActivity.java +++ b/android/app/src/main/java/app/organicmaps/help/HelpActivity.java @@ -1,7 +1,6 @@ package app.organicmaps.help; import androidx.fragment.app.Fragment; - import app.organicmaps.base.BaseToolbarActivity; public class HelpActivity extends BaseToolbarActivity @@ -11,4 +10,4 @@ public class HelpActivity extends BaseToolbarActivity { return HelpFragment.class; } -} \ No newline at end of file +} diff --git a/android/app/src/main/java/app/organicmaps/help/HelpFragment.java b/android/app/src/main/java/app/organicmaps/help/HelpFragment.java index 8f53f6b2b..d40673623 100644 --- a/android/app/src/main/java/app/organicmaps/help/HelpFragment.java +++ b/android/app/src/main/java/app/organicmaps/help/HelpFragment.java @@ -8,19 +8,18 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; - import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import app.organicmaps.BuildConfig; -import app.organicmaps.Framework; import app.organicmaps.R; import app.organicmaps.base.BaseMwmFragment; -import app.organicmaps.util.Config; -import app.organicmaps.util.Constants; -import app.organicmaps.util.DateUtils; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.Constants; +import app.organicmaps.sdk.util.DateUtils; import app.organicmaps.util.Graphics; import app.organicmaps.util.SharingUtils; import app.organicmaps.util.Utils; @@ -31,13 +30,12 @@ public class HelpFragment extends BaseMwmFragment implements View.OnClickListene private String mDonateUrl; private ActivityResultLauncher shareLauncher; - private TextView setupItem(@IdRes int id, boolean tint, @NonNull View frame) + private void setupItem(@IdRes int id, boolean tint, @NonNull View frame) { final TextView view = frame.findViewById(id); view.setOnClickListener(this); if (tint) Graphics.tint(view); - return view; } @Override @@ -46,8 +44,7 @@ public class HelpFragment extends BaseMwmFragment implements View.OnClickListene mDonateUrl = Config.getDonateUrl(requireContext()); View root = inflater.inflate(R.layout.about, container, false); - ((TextView) root.findViewById(R.id.version)) - .setText(BuildConfig.VERSION_NAME); + ((TextView) root.findViewById(R.id.version)).setText(BuildConfig.VERSION_NAME); final boolean isLandscape = getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE; @@ -66,7 +63,7 @@ public class HelpFragment extends BaseMwmFragment implements View.OnClickListene setupItem(R.id.telegram, false, root); setupItem(R.id.instagram, false, root); setupItem(R.id.facebook, false, root); - //setupItem(R.id.twitter, true, root); + // setupItem(R.id.twitter, true, root); setupItem(R.id.matrix, true, root); setupItem(R.id.mastodon, false, root); setupItem(R.id.openstreetmap, true, root); @@ -85,9 +82,8 @@ public class HelpFragment extends BaseMwmFragment implements View.OnClickListene donateView.setVisibility(View.GONE); else { - if (Config.isNY()) - donateView.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_christmas_tree, 0, - R.drawable.ic_christmas_tree, 0); + /*donateView.setCompoundDrawablesRelativeWithIntrinsicBounds(R.drawable.ic_donate, 0, + R.drawable.ic_donate, 0);*/ setupItem(R.id.donate, isLandscape, root); } @@ -98,8 +94,10 @@ public class HelpFragment extends BaseMwmFragment implements View.OnClickListene View termOfUseView = root.findViewById(R.id.term_of_use_link); View privacyPolicyView = root.findViewById(R.id.privacy_policy); - termOfUseView.setOnClickListener(v -> Utils.openUrl(requireActivity(), getResources().getString(R.string.app_site_url) + "terms/")); - privacyPolicyView.setOnClickListener(v -> Utils.openUrl(requireActivity(), getResources().getString(R.string.app_site_url) + "privacy/")); + termOfUseView.setOnClickListener( + v -> Utils.openUrl(requireActivity(), getResources().getString(R.string.app_site_url) + "terms/")); + privacyPolicyView.setOnClickListener( + v -> Utils.openUrl(requireActivity(), getResources().getString(R.string.app_site_url) + "privacy/")); shareLauncher = SharingUtils.RegisterLauncher(this); @@ -126,8 +124,8 @@ public class HelpFragment extends BaseMwmFragment implements View.OnClickListene Utils.openUrl(requireActivity(), getString(R.string.instagram_url)); else if (id == R.id.facebook) Utils.showFacebookPage(requireActivity()); -// else if (id == R.id.twitter) -// Utils.openUrl(requireActivity(), Constants.Url.TWITTER); + // else if (id == R.id.twitter) + // Utils.openUrl(requireActivity(), Constants.Url.TWITTER); else if (id == R.id.matrix) Utils.openUrl(requireActivity(), Constants.Url.MATRIX); else if (id == R.id.mastodon) diff --git a/android/app/src/main/java/app/organicmaps/intent/Factory.java b/android/app/src/main/java/app/organicmaps/intent/Factory.java index 0fd3c867e..e28aa5aad 100644 --- a/android/app/src/main/java/app/organicmaps/intent/Factory.java +++ b/android/app/src/main/java/app/organicmaps/intent/Factory.java @@ -1,36 +1,33 @@ package app.organicmaps.intent; +import static app.organicmaps.api.Const.EXTRA_PICK_POINT; + import android.content.ContentResolver; import android.content.Intent; import android.net.Uri; - import androidx.annotation.NonNull; import androidx.core.content.IntentCompat; - -import app.organicmaps.Framework; -import app.organicmaps.Map; import app.organicmaps.MwmActivity; import app.organicmaps.MwmApplication; -import app.organicmaps.api.ParsedRoutingData; -import app.organicmaps.api.ParsedSearchRequest; -import app.organicmaps.api.RequestType; -import app.organicmaps.api.RoutePoint; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.FeatureId; -import app.organicmaps.bookmarks.data.MapObject; import app.organicmaps.editor.OsmLoginActivity; import app.organicmaps.routing.RoutingController; -import app.organicmaps.search.SearchActivity; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.Map; +import app.organicmaps.sdk.api.ParsedRoutingData; +import app.organicmaps.sdk.api.ParsedSearchRequest; +import app.organicmaps.sdk.api.RequestType; +import app.organicmaps.sdk.api.RoutePoint; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.FeatureId; +import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.search.SearchEngine; -import app.organicmaps.util.StorageUtils; -import app.organicmaps.util.concurrency.ThreadPool; - +import app.organicmaps.sdk.util.StorageUtils; +import app.organicmaps.sdk.util.concurrency.ThreadPool; +import app.organicmaps.search.SearchActivity; import java.io.File; import java.util.Collections; import java.util.List; -import static app.organicmaps.api.Const.EXTRA_PICK_POINT; - public class Factory { public static boolean isStartedForApiResult(@NonNull Intent intent) @@ -81,8 +78,7 @@ public class Factory switch (Framework.nativeParseAndSetApiUrl(uri.toString())) { - case RequestType.INCORRECT: - return false; + case RequestType.INCORRECT: return false; case RequestType.MAP: SearchEngine.INSTANCE.cancelInteractiveSearch(); @@ -95,10 +91,9 @@ public class Factory RoutingController.get().setRouterType(data.mRouterType); final RoutePoint from = data.mPoints[0]; final RoutePoint to = data.mPoints[1]; - RoutingController.get().prepare(MapObject.createMapObject(FeatureId.EMPTY, MapObject.API_POINT, - from.mName, "", from.mLat, from.mLon), - MapObject.createMapObject(FeatureId.EMPTY, MapObject.API_POINT, - to.mName, "", to.mLat, to.mLon)); + RoutingController.get().prepare( + MapObject.createMapObject(FeatureId.EMPTY, MapObject.API_POINT, from.mName, "", from.mLat, from.mLon), + MapObject.createMapObject(FeatureId.EMPTY, MapObject.API_POINT, to.mName, "", to.mLat, to.mLon)); return true; case RequestType.SEARCH: { diff --git a/android/app/src/main/java/app/organicmaps/intent/IntentProcessor.java b/android/app/src/main/java/app/organicmaps/intent/IntentProcessor.java index 9795f7be4..964032429 100644 --- a/android/app/src/main/java/app/organicmaps/intent/IntentProcessor.java +++ b/android/app/src/main/java/app/organicmaps/intent/IntentProcessor.java @@ -1,10 +1,8 @@ package app.organicmaps.intent; import android.content.Intent; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.MwmActivity; public interface IntentProcessor diff --git a/android/app/src/main/java/app/organicmaps/leftbutton/LeftButtonsHolder.java b/android/app/src/main/java/app/organicmaps/leftbutton/LeftButtonsHolder.java index 67ac90de4..d9cf53c38 100644 --- a/android/app/src/main/java/app/organicmaps/leftbutton/LeftButtonsHolder.java +++ b/android/app/src/main/java/app/organicmaps/leftbutton/LeftButtonsHolder.java @@ -3,14 +3,10 @@ package app.organicmaps.leftbutton; import android.content.Context; import android.content.SharedPreferences; import android.text.TextUtils; - import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; - import app.organicmaps.R; - import java.util.Collection; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; @@ -82,21 +78,18 @@ public class LeftButtonsHolder private void initDisableButton(Context context) { - availableButtons.put(DISABLE_BUTTON_CODE, new LeftButton() - { - @Override - public String getCode() - { - return DISABLE_BUTTON_CODE; - } + availableButtons.put(DISABLE_BUTTON_CODE, new LeftButton() { + @Override + public String getCode() + { + return DISABLE_BUTTON_CODE; + } - @Override - public String getPrefsName() - { - return context.getString(R.string.pref_left_button_disable); - } - } - ); + @Override + public String getPrefsName() + { + return context.getString(R.string.pref_left_button_disable); + } + }); } } - diff --git a/android/app/src/main/java/app/organicmaps/location/TrackRecordingService.java b/android/app/src/main/java/app/organicmaps/location/TrackRecordingService.java index dc2d564db..0f93d5a18 100644 --- a/android/app/src/main/java/app/organicmaps/location/TrackRecordingService.java +++ b/android/app/src/main/java/app/organicmaps/location/TrackRecordingService.java @@ -1,5 +1,9 @@ package app.organicmaps.location; +import static android.Manifest.permission.ACCESS_FINE_LOCATION; +import static android.Manifest.permission.POST_NOTIFICATIONS; +import static android.content.pm.PackageManager.PERMISSION_GRANTED; + import android.app.ForegroundServiceStartNotAllowedException; import android.app.NotificationManager; import android.app.PendingIntent; @@ -10,7 +14,6 @@ import android.content.pm.ServiceInfo; import android.location.Location; import android.os.Build; import android.os.IBinder; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresPermission; @@ -23,12 +26,11 @@ import androidx.core.content.ContextCompat; import app.organicmaps.MwmActivity; import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.util.LocationUtils; -import app.organicmaps.util.log.Logger; - -import static android.Manifest.permission.ACCESS_FINE_LOCATION; -import static android.Manifest.permission.POST_NOTIFICATIONS; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import app.organicmaps.sdk.location.LocationHelper; +import app.organicmaps.sdk.location.LocationListener; +import app.organicmaps.sdk.location.TrackRecorder; +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.log.Logger; public class TrackRecordingService extends Service implements LocationListener { @@ -54,19 +56,19 @@ public class TrackRecordingService extends Service implements LocationListener { if (!TrackRecorder.nativeIsTrackRecordingEnabled()) TrackRecorder.nativeStartTrackRecording(); - LocationHelper.from(context).restartWithNewMode(); + MwmApplication.from(context).getLocationHelper().restartWithNewMode(); ContextCompat.startForegroundService(context, new Intent(context, TrackRecordingService.class)); } public static void createNotificationChannel(@NonNull Context context) { final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); - final NotificationChannelCompat channel = new NotificationChannelCompat.Builder(TRACK_REC_CHANNEL_ID, - NotificationManagerCompat.IMPORTANCE_LOW) - .setName(context.getString(R.string.track_recording)) - .setLightsEnabled(false) - .setVibrationEnabled(false) - .build(); + final NotificationChannelCompat channel = + new NotificationChannelCompat.Builder(TRACK_REC_CHANNEL_ID, NotificationManagerCompat.IMPORTANCE_LOW) + .setName(context.getString(R.string.track_recording)) + .setLightsEnabled(false) + .setVibrationEnabled(false) + .build(); notificationManager.createNotificationChannel(channel); } @@ -77,8 +79,8 @@ public class TrackRecordingService extends Service implements LocationListener final int FLAG_IMMUTABLE = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? 0 : PendingIntent.FLAG_IMMUTABLE; final Intent contentIntent = new Intent(context, MwmActivity.class); - mPendingIntent = PendingIntent.getActivity(context, 0, contentIntent, - PendingIntent.FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); + mPendingIntent = + PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); return mPendingIntent; } @@ -90,8 +92,8 @@ public class TrackRecordingService extends Service implements LocationListener final int FLAG_IMMUTABLE = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? 0 : PendingIntent.FLAG_IMMUTABLE; final Intent exitIntent = new Intent(context, MwmActivity.class); exitIntent.setAction(STOP_TRACK_RECORDING); - mExitPendingIntent = PendingIntent.getActivity(context, 1, exitIntent, - PendingIntent.FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); + mExitPendingIntent = + PendingIntent.getActivity(context, 1, exitIntent, PendingIntent.FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); return mExitPendingIntent; } @@ -101,18 +103,19 @@ public class TrackRecordingService extends Service implements LocationListener if (mNotificationBuilder != null) return mNotificationBuilder; - mNotificationBuilder = new NotificationCompat.Builder(context, TRACK_REC_CHANNEL_ID) - .setCategory(NotificationCompat.CATEGORY_SERVICE) - .setPriority(NotificationManager.IMPORTANCE_DEFAULT) - .setVisibility(NotificationCompat.VISIBILITY_SECRET) - .setOngoing(true) - .setShowWhen(true) - .setOnlyAlertOnce(true) - .setSmallIcon(R.drawable.ic_logo_small) - .setContentTitle(context.getString(R.string.track_recording)) - .addAction(0, context.getString(R.string.navigation_stop_button), getExitPendingIntent(context)) - .setContentIntent(getPendingIntent(context)) - .setColor(ContextCompat.getColor(context, R.color.notification)); + mNotificationBuilder = + new NotificationCompat.Builder(context, TRACK_REC_CHANNEL_ID) + .setCategory(NotificationCompat.CATEGORY_SERVICE) + .setPriority(NotificationManager.IMPORTANCE_DEFAULT) + .setVisibility(NotificationCompat.VISIBILITY_SECRET) + .setOngoing(true) + .setShowWhen(true) + .setOnlyAlertOnce(true) + .setSmallIcon(R.drawable.ic_logo_small) + .setContentTitle(context.getString(R.string.track_recording)) + .addAction(0, context.getString(R.string.navigation_stop_button), getExitPendingIntent(context)) + .setContentIntent(getPendingIntent(context)) + .setColor(ContextCompat.getColor(context, R.color.notification)); return mNotificationBuilder; } @@ -130,7 +133,7 @@ public class TrackRecordingService extends Service implements LocationListener mWarningBuilder = null; if (TrackRecorder.nativeIsTrackRecordingEnabled()) TrackRecorder.nativeStopTrackRecording(); - LocationHelper.from(this).removeListener(this); + MwmApplication.from(this).getLocationHelper().removeListener(this); // The notification is cancelled automatically by the system. } @@ -167,12 +170,12 @@ public class TrackRecordingService extends Service implements LocationListener int type = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) type = ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION; - ServiceCompat.startForeground(this, TrackRecordingService.TRACK_REC_NOTIFICATION_ID, getNotificationBuilder(this).build(), type); + ServiceCompat.startForeground(this, TrackRecordingService.TRACK_REC_NOTIFICATION_ID, + getNotificationBuilder(this).build(), type); } catch (Exception e) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && - e instanceof ForegroundServiceStartNotAllowedException) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e instanceof ForegroundServiceStartNotAllowedException) { // App not in a valid state to start foreground service (e.g started from bg) Logger.e(TAG, "Not in a valid state to start foreground service", e); @@ -181,7 +184,7 @@ public class TrackRecordingService extends Service implements LocationListener Logger.e(TAG, "Failed to promote the service to foreground", e); } - final LocationHelper locationHelper = LocationHelper.from(this); + final LocationHelper locationHelper = MwmApplication.from(this).getLocationHelper(); // Subscribe to location updates. This call is idempotent. locationHelper.addListener(this); @@ -197,21 +200,22 @@ public class TrackRecordingService extends Service implements LocationListener if (mWarningBuilder != null) return mWarningBuilder; - mWarningBuilder = new NotificationCompat.Builder(context, TRACK_REC_CHANNEL_ID) - .setCategory(NotificationCompat.CATEGORY_SERVICE) - .setPriority(NotificationManager.IMPORTANCE_DEFAULT) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setOngoing(true) - .setShowWhen(true) - .setOnlyAlertOnce(true) - .setSmallIcon(R.drawable.warning_icon) - .setContentTitle(context.getString(R.string.current_location_unknown_error_title)) - .setContentText(context.getString(R.string.dialog_routing_location_turn_wifi)) - .setStyle(new NotificationCompat.BigTextStyle() - .bigText(context.getString(R.string.dialog_routing_location_turn_wifi))) - .addAction(0, context.getString(R.string.navigation_stop_button), getExitPendingIntent(context)) - .setContentIntent(getPendingIntent(context)) - .setColor(ContextCompat.getColor(context, R.color.notification_warning)); + mWarningBuilder = + new NotificationCompat.Builder(context, TRACK_REC_CHANNEL_ID) + .setCategory(NotificationCompat.CATEGORY_SERVICE) + .setPriority(NotificationManager.IMPORTANCE_DEFAULT) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setOngoing(true) + .setShowWhen(true) + .setOnlyAlertOnce(true) + .setSmallIcon(R.drawable.warning_icon) + .setContentTitle(context.getString(R.string.current_location_unknown_error_title)) + .setContentText(context.getString(R.string.dialog_routing_location_turn_wifi)) + .setStyle(new NotificationCompat.BigTextStyle().bigText( + context.getString(R.string.dialog_routing_location_turn_wifi))) + .addAction(0, context.getString(R.string.navigation_stop_button), getExitPendingIntent(context)) + .setContentIntent(getPendingIntent(context)) + .setColor(ContextCompat.getColor(context, R.color.notification_warning)); return mWarningBuilder; } @@ -223,12 +227,11 @@ public class TrackRecordingService extends Service implements LocationListener mWarningNotification = true; // post notification permission is not there but we will not stop the runnable because if // in between user gives permission then warning will not be updated until next restart - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && - ActivityCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && ActivityCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED) return; - NotificationManagerCompat.from(this) - .notify(TRACK_REC_NOTIFICATION_ID, getWarningBuilder(this).build()); + NotificationManagerCompat.from(this).notify(TRACK_REC_NOTIFICATION_ID, getWarningBuilder(this).build()); } @Override @@ -242,12 +245,11 @@ public class TrackRecordingService extends Service implements LocationListener // post notification permission is not there but we will not stop the runnable because if // in between user gives permission then warning will not be updated until next restart - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && - ActivityCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && ActivityCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED) return; - NotificationManagerCompat.from(this) - .notify(TRACK_REC_NOTIFICATION_ID, getNotificationBuilder(this).build()); + NotificationManagerCompat.from(this).notify(TRACK_REC_NOTIFICATION_ID, getNotificationBuilder(this).build()); } } } diff --git a/android/app/src/main/java/app/organicmaps/maplayer/LayerBottomSheetItem.java b/android/app/src/main/java/app/organicmaps/maplayer/LayerBottomSheetItem.java index 5ac9eb47d..4cdd7fdca 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/LayerBottomSheetItem.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/LayerBottomSheetItem.java @@ -2,13 +2,12 @@ package app.organicmaps.maplayer; import android.content.Context; import android.view.View; - import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.StringRes; - import app.organicmaps.R; import app.organicmaps.adapter.OnItemClickListener; +import app.organicmaps.sdk.maplayer.Mode; import app.organicmaps.util.ThemeUtils; public class LayerBottomSheetItem @@ -24,10 +23,8 @@ public class LayerBottomSheetItem @NonNull private final OnItemClickListener mItemClickListener; - LayerBottomSheetItem(@DrawableRes int enabledStateDrawableResId, - @DrawableRes int disabledStateDrawableResId, - @StringRes int titleResId, - @NonNull Mode mode, + LayerBottomSheetItem(@DrawableRes int enabledStateDrawableResId, @DrawableRes int disabledStateDrawableResId, + @StringRes int titleResId, @NonNull Mode mode, @NonNull OnItemClickListener itemClickListener) { mEnabledStateDrawableResId = enabledStateDrawableResId; @@ -37,7 +34,8 @@ public class LayerBottomSheetItem mItemClickListener = itemClickListener; } - public static LayerBottomSheetItem create(@NonNull Context mContext, Mode mode, @NonNull OnItemClickListener layerItemClickListener) + public static LayerBottomSheetItem create(@NonNull Context mContext, Mode mode, + @NonNull OnItemClickListener layerItemClickListener) { int disabledResource = 0; int enabledResource = 0; diff --git a/android/app/src/main/java/app/organicmaps/maplayer/LayerHolder.java b/android/app/src/main/java/app/organicmaps/maplayer/LayerHolder.java index 6cccb697e..a348ff8ef 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/LayerHolder.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/LayerHolder.java @@ -3,11 +3,9 @@ package app.organicmaps.maplayer; import android.view.View; import android.widget.ImageView; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; - import app.organicmaps.R; import app.organicmaps.adapter.OnItemClickListener; diff --git a/android/app/src/main/java/app/organicmaps/maplayer/LayersAdapter.java b/android/app/src/main/java/app/organicmaps/maplayer/LayersAdapter.java index 7f2d02876..2d5e20ea8 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/LayersAdapter.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/LayersAdapter.java @@ -4,14 +4,11 @@ import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - import app.organicmaps.R; -import app.organicmaps.util.SharedPropertiesUtils; -import app.organicmaps.util.UiUtils; - +import app.organicmaps.sdk.util.SharedPropertiesUtils; +import app.organicmaps.sdk.util.UiUtils; import java.util.List; public class LayersAdapter extends RecyclerView.Adapter @@ -46,11 +43,9 @@ public class LayersAdapter extends RecyclerView.Adapter holder.mButton.setContentDescription(context.getString(item.getTitle())); holder.mTitle.setSelected(isEnabled); holder.mTitle.setText(item.getTitle()); - boolean isNewLayer = SharedPropertiesUtils.shouldShowNewMarkerForLayerMode(context, - item.getMode()); + boolean isNewLayer = SharedPropertiesUtils.shouldShowNewMarkerForLayerMode(item.getMode()); UiUtils.showIf(isNewLayer, holder.mNewMarker); - holder.mButton.setImageResource(isEnabled ? item.getEnabledStateDrawable() - : item.getDisabledStateDrawable()); + holder.mButton.setImageResource(isEnabled ? item.getEnabledStateDrawable() : item.getDisabledStateDrawable()); holder.mListener = item::onClick; } diff --git a/android/app/src/main/java/app/organicmaps/maplayer/LayersButton.java b/android/app/src/main/java/app/organicmaps/maplayer/LayersButton.java index 571846807..2530b3c84 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/LayersButton.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/LayersButton.java @@ -2,42 +2,40 @@ package app.organicmaps.maplayer; import android.content.Context; import android.util.AttributeSet; - -import com.google.android.material.floatingactionbutton.FloatingActionButton; - import app.organicmaps.R; +import com.google.android.material.floatingactionbutton.FloatingActionButton; public class LayersButton extends FloatingActionButton { private boolean mAreLayersActive = false; - + public LayersButton(Context context) { super(context); } - + public LayersButton(Context context, AttributeSet attrs) { super(context, attrs); } - + public LayersButton(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } - + @Override public int[] onCreateDrawableState(int extraSpace) { final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); if (mAreLayersActive) - mergeDrawableStates(drawableState, new int[]{R.attr.layers_enabled}); + mergeDrawableStates(drawableState, new int[] {R.attr.layers_enabled}); return drawableState; } - + public void setHasActiveLayers(boolean areLayersActive) { mAreLayersActive = areLayersActive; refreshDrawableState(); } -} \ No newline at end of file +} diff --git a/android/app/src/main/java/app/organicmaps/maplayer/LayersUtils.java b/android/app/src/main/java/app/organicmaps/maplayer/LayersUtils.java index 21aca4c7f..73378e07a 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/LayersUtils.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/LayersUtils.java @@ -1,5 +1,6 @@ package app.organicmaps.maplayer; +import app.organicmaps.sdk.maplayer.Mode; import java.util.ArrayList; import java.util.List; diff --git a/android/app/src/main/java/app/organicmaps/maplayer/MapButtonsController.java b/android/app/src/main/java/app/organicmaps/maplayer/MapButtonsController.java index e4f9b0059..cdfe67050 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/MapButtonsController.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/MapButtonsController.java @@ -1,6 +1,5 @@ package app.organicmaps.maplayer; -import static app.organicmaps.leftbutton.LeftButtonsHolder.BUTTON_HELP_CODE; import static app.organicmaps.leftbutton.LeftButtonsHolder.DISABLE_BUTTON_CODE; import android.animation.ArgbEvaluator; @@ -9,13 +8,11 @@ import android.content.Context; import android.content.res.ColorStateList; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.text.TextUtils; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.OptIn; @@ -25,31 +22,28 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; - -import app.organicmaps.Framework; import app.organicmaps.MwmActivity; import app.organicmaps.R; -import app.organicmaps.downloader.MapManager; -import app.organicmaps.downloader.UpdateInfo; -import app.organicmaps.location.TrackRecorder; -import app.organicmaps.maplayer.isolines.IsolinesManager; -import app.organicmaps.maplayer.subway.SubwayManager; -import app.organicmaps.maplayer.traffic.TrafficManager; -import app.organicmaps.routing.RoutingController; import app.organicmaps.leftbutton.LeftButton; import app.organicmaps.leftbutton.LeftToggleButton; -import app.organicmaps.util.Config; +import app.organicmaps.routing.RoutingController; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.downloader.UpdateInfo; +import app.organicmaps.sdk.location.TrackRecorder; +import app.organicmaps.sdk.maplayer.isolines.IsolinesManager; +import app.organicmaps.sdk.maplayer.subway.SubwayManager; +import app.organicmaps.sdk.maplayer.traffic.TrafficManager; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.UiUtils; import app.organicmaps.util.WindowInsetUtils; import app.organicmaps.widget.menu.MyPositionButton; import app.organicmaps.widget.placepage.PlacePageViewModel; - import com.google.android.material.badge.BadgeDrawable; import com.google.android.material.badge.BadgeUtils; import com.google.android.material.badge.ExperimentalBadgeUtils; import com.google.android.material.floatingactionbutton.FloatingActionButton; - import java.util.HashMap; import java.util.Map; @@ -81,7 +75,8 @@ public class MapButtonsController extends Fragment private final Observer mButtonHiddenObserver = this::setButtonsHidden; private final Observer mMyPositionModeObserver = this::updateNavMyPositionButton; private final Observer mSearchOptionObserver = this::onSearchOptionChange; - private final Observer mTrackRecorderObserver = (enable) -> { + private final Observer mTrackRecorderObserver = (enable) -> + { updateMenuBadge(enable); showButton(enable, MapButtons.trackRecordingStatus); updateLeftButtonToggleState(enable); @@ -92,7 +87,8 @@ public class MapButtonsController extends Fragment @Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { final FragmentActivity activity = requireActivity(); mMapButtonClickListener = (MwmActivity) activity; @@ -116,28 +112,31 @@ public class MapButtonsController extends Fragment final View zoomFrame = mFrame.findViewById(R.id.zoom_buttons_container); mFrame.findViewById(R.id.nav_zoom_in) - .setOnClickListener((v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.zoomIn)); + .setOnClickListener((v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.zoomIn)); mFrame.findViewById(R.id.nav_zoom_out) - .setOnClickListener((v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.zoomOut)); + .setOnClickListener((v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.zoomOut)); final View myPosition = mFrame.findViewById(R.id.my_position); - mNavMyPosition = new MyPositionButton(myPosition, (v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.myPosition)); + mNavMyPosition = + new MyPositionButton(myPosition, (v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.myPosition)); // Some buttons do not exist in navigation mode mToggleMapLayerButton = mFrame.findViewById(R.id.layers_button); if (mToggleMapLayerButton != null) { - mToggleMapLayerButton.setOnClickListener(view -> mMapButtonClickListener.onMapButtonClick(MapButtons.toggleMapLayer)); + mToggleMapLayerButton.setOnClickListener( + view -> mMapButtonClickListener.onMapButtonClick(MapButtons.toggleMapLayer)); mToggleMapLayerButton.setVisibility(View.VISIBLE); } mMapButtonsViewModel.setTopButtonsMarginTop(-1); mTrackRecordingStatusButton = mFrame.findViewById(R.id.track_recording_status); if (mTrackRecordingStatusButton != null) - mTrackRecordingStatusButton.setOnClickListener(view -> mMapButtonClickListener.onMapButtonClick(MapButtons.trackRecordingStatus)); + mTrackRecordingStatusButton.setOnClickListener( + view -> mMapButtonClickListener.onMapButtonClick(MapButtons.trackRecordingStatus)); mSearchWheel = new SearchWheel(mFrame, - (v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.search), - (v) -> mMapButtonClickListener.onSearchCanceled(), - mMapButtonsViewModel); + (v) + -> mMapButtonClickListener.onMapButtonClick(MapButtons.search), + (v) -> mMapButtonClickListener.onSearchCanceled(), mMapButtonsViewModel); // Used to get the maximum height the buttons will evolve in mFrame.addOnLayoutChangeListener(new MapButtonsController.ContentViewLayoutChangeListener(mFrame)); @@ -179,9 +178,9 @@ public class MapButtonsController extends Fragment if (menuButton != null) { menuButton.setOnClickListener((v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.menu)); - // This hack is needed to show the badge on the initial startup. For some reason, updateMenuBadge does not work from onResume() there. - menuButton.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() - { + // This hack is needed to show the badge on the initial startup. For some reason, updateMenuBadge does not work + // from onResume() there. + menuButton.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { @@ -206,22 +205,9 @@ public class MapButtonsController extends Fragment leftButtonView.setImageTintList(ColorStateList.valueOf(ThemeUtils.getColor(context, R.attr.iconTint))); - // Christmas tree with help button - if (Config.isNY() && - mLeftButton.getCode().equals(BUTTON_HELP_CODE) && - !TextUtils.isEmpty(Config.getDonateUrl(requireContext())) - ) - { - leftButtonView.setImageResource(R.drawable.ic_christmas_tree); - leftButtonView.setContentDescription(getString(R.string.about_help)); - leftButtonView.setOnClickListener((v) -> mMapButtonClickListener.onMapButtonClick(MapButtons.help)); - } - else - { - mLeftButton.drawIcon(leftButtonView); - leftButtonView.setContentDescription(mLeftButton.getPrefsName()); - leftButtonView.setOnClickListener((v) -> mLeftButton.onClick(leftButtonView)); - } + mLeftButton.drawIcon(leftButtonView); + leftButtonView.setContentDescription(mLeftButton.getPrefsName()); + leftButtonView.setOnClickListener((v) -> mLeftButton.onClick(leftButtonView)); // else // { // helpButton.setImageResource(R.drawable.ic_launcher); @@ -244,9 +230,7 @@ public class MapButtonsController extends Fragment return; switch (button) { - case zoom: - UiUtils.showIf(show && Config.showZoomButtons(), buttonView); - break; + case zoom: UiUtils.showIf(show && Config.showZoomButtons(), buttonView); break; case toggleMapLayer: if (mToggleMapLayerButton != null) UiUtils.showIf(show && !isInNavigationMode(), mToggleMapLayerButton); @@ -255,12 +239,9 @@ public class MapButtonsController extends Fragment if (mNavMyPosition != null) mNavMyPosition.showButton(show); break; - case search: - mSearchWheel.show(show); + case search: mSearchWheel.show(show); case bookmarks: - case menu: - UiUtils.showIf(show, buttonView); - break; + case menu: UiUtils.showIf(show, buttonView); break; case trackRecordingStatus: UiUtils.showIf(show, buttonView); animateIconBlinking(show, (FloatingActionButton) buttonView); @@ -272,11 +253,7 @@ public class MapButtonsController extends Fragment if (show) { Drawable drawable = button.getDrawable(); - ObjectAnimator colorAnimator = ObjectAnimator.ofArgb( - drawable, - "tint", - 0xFF757575, - 0xFFFF0000); + ObjectAnimator colorAnimator = ObjectAnimator.ofArgb(drawable, "tint", 0xFF757575, 0xFFFF0000); colorAnimator.setDuration(2500); colorAnimator.setEvaluator(new ArgbEvaluator()); colorAnimator.setRepeatCount(ObjectAnimator.INFINITE); @@ -309,8 +286,7 @@ public class MapButtonsController extends Fragment return; final UpdateInfo info = MapManager.nativeGetUpdateInfo(null); final int count = (info == null ? 0 : info.filesCount); - final int verticalOffset = dpToPx(8, context) + dpToPx(Integer.toString(0) - .length() * 5, context); + final int verticalOffset = dpToPx(8, context) + dpToPx(Integer.toString(0).length() * 5, context); if (count == 0) { @@ -335,8 +311,7 @@ public class MapButtonsController extends Fragment return; final UpdateInfo info = MapManager.nativeGetUpdateInfo(null); final int count = (info == null ? 0 : info.filesCount); - final int verticalOffset = dpToPx(8, context) + dpToPx(Integer.toString(0) - .length() * 5, context); + final int verticalOffset = dpToPx(8, context) + dpToPx(Integer.toString(0).length() * 5, context); BadgeUtils.detachBadgeDrawable(mBadgeDrawable, menuButton); mBadgeDrawable = BadgeDrawable.create(context); mBadgeDrawable.setMaxCharacterCount(3); @@ -353,10 +328,8 @@ public class MapButtonsController extends Fragment { if (mToggleMapLayerButton == null) return; - final boolean buttonSelected = TrafficManager.INSTANCE.isEnabled() - || IsolinesManager.isEnabled() - || SubwayManager.isEnabled() - || Framework.nativeIsOutdoorsLayerEnabled(); + final boolean buttonSelected = TrafficManager.INSTANCE.isEnabled() || IsolinesManager.isEnabled() + || SubwayManager.isEnabled() || Framework.nativeIsOutdoorsLayerEnabled(); mToggleMapLayerButton.setHasActiveLayers(buttonSelected); } @@ -381,11 +354,11 @@ public class MapButtonsController extends Fragment return; // Move the buttons containers to follow the place page - if (mInnerRightButtonsFrame != null && - (isBehindPlacePage(mInnerRightButtonsFrame) || isMoving(mInnerRightButtonsFrame))) + if (mInnerRightButtonsFrame != null + && (isBehindPlacePage(mInnerRightButtonsFrame) || isMoving(mInnerRightButtonsFrame))) applyMove(mInnerRightButtonsFrame, translationY); - if (mInnerLeftButtonsFrame != null && - (isBehindPlacePage(mInnerLeftButtonsFrame) || isMoving(mInnerLeftButtonsFrame))) + if (mInnerLeftButtonsFrame != null + && (isBehindPlacePage(mInnerLeftButtonsFrame) || isMoving(mInnerLeftButtonsFrame))) applyMove(mInnerLeftButtonsFrame, translationY); } @@ -414,15 +387,14 @@ public class MapButtonsController extends Fragment final View button = entry.getValue(); if (button.getParent() == parent) { - int toleranceOffset = 0; - // Allow offset tolerance for zoom buttons - switch(entry.getKey()) + int toleranceOffset = switch (entry.getKey()) { - case zoomIn: case zoomOut: case zoom: - toleranceOffset = -140; - break; - } - showButton(getViewTopOffset(translation, button) >= toleranceOffset, entry.getKey()); + case zoomIn, zoomOut, zoom -> -140; + default -> + 0; + // Allow offset tolerance for zoom buttons + }; + showButton(getViewTopOffset(translation, button) >= toleranceOffset, entry.getKey()); } } } @@ -478,10 +450,11 @@ public class MapButtonsController extends Fragment mSearchWheel.onResume(); updateMenuBadge(); updateLayerButton(); - final WindowInsetUtils.PaddingInsetsListener insetsListener = new WindowInsetUtils.PaddingInsetsListener.Builder() - .setInsetsTypeMask(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout()) - .setAllSides() - .build(); + final WindowInsetUtils.PaddingInsetsListener insetsListener = + new WindowInsetUtils.PaddingInsetsListener.Builder() + .setInsetsTypeMask(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout()) + .setAllSides() + .build(); ViewCompat.setOnApplyWindowInsetsListener(mFrame, insetsListener); // Fixes insets on older Androids and with a search opened via API on all Androids. if (mFrame.hasWindowFocus()) @@ -572,8 +545,8 @@ public class MapButtonsController extends Fragment } @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, - int oldTop, int oldRight, int oldBottom) + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, + int oldBottom) { mContentHeight = bottom - top; mContentWidth = right - left; diff --git a/android/app/src/main/java/app/organicmaps/maplayer/MapButtonsViewModel.java b/android/app/src/main/java/app/organicmaps/maplayer/MapButtonsViewModel.java index ab3bf73de..7483192c6 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/MapButtonsViewModel.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/MapButtonsViewModel.java @@ -3,17 +3,19 @@ package app.organicmaps.maplayer; import androidx.annotation.Nullable; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; -import app.organicmaps.location.TrackRecorder; +import app.organicmaps.sdk.location.TrackRecorder; public class MapButtonsViewModel extends ViewModel { private final MutableLiveData mButtonsHidden = new MutableLiveData<>(false); private final MutableLiveData mBottomButtonsHeight = new MutableLiveData<>(0f); private final MutableLiveData mTopButtonsMarginTop = new MutableLiveData<>(-1); - private final MutableLiveData mLayoutMode = new MutableLiveData<>(MapButtonsController.LayoutMode.regular); + private final MutableLiveData mLayoutMode = + new MutableLiveData<>(MapButtonsController.LayoutMode.regular); private final MutableLiveData mMyPositionMode = new MutableLiveData<>(); private final MutableLiveData mSearchOption = new MutableLiveData<>(); - private final MutableLiveData mTrackRecorderState = new MutableLiveData<>(TrackRecorder.nativeIsTrackRecordingEnabled()); + private final MutableLiveData mTrackRecorderState = + new MutableLiveData<>(TrackRecorder.nativeIsTrackRecordingEnabled()); public MutableLiveData getButtonsHidden() { diff --git a/android/app/src/main/java/app/organicmaps/maplayer/Mode.java b/android/app/src/main/java/app/organicmaps/maplayer/Mode.java deleted file mode 100644 index 7b69e5ed5..000000000 --- a/android/app/src/main/java/app/organicmaps/maplayer/Mode.java +++ /dev/null @@ -1,78 +0,0 @@ -package app.organicmaps.maplayer; - -import android.content.Context; - -import androidx.annotation.NonNull; - -import app.organicmaps.Framework; -import app.organicmaps.maplayer.isolines.IsolinesManager; -import app.organicmaps.maplayer.subway.SubwayManager; -import app.organicmaps.maplayer.traffic.TrafficManager; -import app.organicmaps.util.ThemeSwitcher; - -public enum Mode -{ - TRAFFIC - { - @Override - public boolean isEnabled(@NonNull Context context) - { - return !SubwayManager.isEnabled() && TrafficManager.INSTANCE.isEnabled(); - } - - @Override - public void setEnabled(@NonNull Context context, boolean isEnabled) - { - TrafficManager.INSTANCE.setEnabled(isEnabled); - } - }, - SUBWAY - { - @Override - public boolean isEnabled(@NonNull Context context) - { - return SubwayManager.isEnabled(); - } - - @Override - public void setEnabled(@NonNull Context context, boolean isEnabled) - { - SubwayManager.setEnabled(isEnabled); - } - }, - - ISOLINES - { - @Override - public boolean isEnabled(@NonNull Context context) - { - return IsolinesManager.isEnabled(); - } - - @Override - public void setEnabled(@NonNull Context context, boolean isEnabled) - { - IsolinesManager.setEnabled(isEnabled); - } - }, - OUTDOORS - { - @Override - public boolean isEnabled(@NonNull Context context) - { - return Framework.nativeIsOutdoorsLayerEnabled(); - } - - @Override - public void setEnabled(@NonNull Context context, boolean isEnabled) - { - Framework.nativeSetOutdoorsLayerEnabled(isEnabled); - ThemeSwitcher.INSTANCE.restart(true); - } - }; - - public abstract boolean isEnabled(@NonNull Context context); - - public abstract void setEnabled(@NonNull Context context, boolean isEnabled); - -} diff --git a/android/app/src/main/java/app/organicmaps/maplayer/SearchWheel.java b/android/app/src/main/java/app/organicmaps/maplayer/SearchWheel.java index 077534ab8..1d05d8e58 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/SearchWheel.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/SearchWheel.java @@ -8,7 +8,6 @@ import android.util.DisplayMetrics; import android.view.View; import android.view.WindowManager; import android.widget.ImageView; - import androidx.annotation.DrawableRes; import androidx.annotation.IdRes; import androidx.annotation.NonNull; @@ -17,9 +16,9 @@ import androidx.annotation.StringRes; import app.organicmaps.R; import app.organicmaps.routing.RoutingController; import app.organicmaps.sdk.search.SearchEngine; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.concurrency.UiThread; import app.organicmaps.util.Graphics; -import app.organicmaps.util.UiUtils; -import app.organicmaps.util.concurrency.UiThread; public class SearchWheel implements View.OnClickListener { @@ -65,8 +64,7 @@ public class SearchWheel implements View.OnClickListener @StringRes private final int mQueryId; - SearchOption(@IdRes int resId, @DrawableRes int drawableOff, - @StringRes int queryId) + SearchOption(@IdRes int resId, @DrawableRes int drawableOff, @StringRes int queryId) { this.mResId = resId; this.mDrawableOff = drawableOff; @@ -83,7 +81,6 @@ public class SearchWheel implements View.OnClickListener } throw new IllegalArgumentException("No navigation search for id " + resId); } - } public SearchWheel(View frame, @NonNull View.OnClickListener onSearchPressedListener, @@ -114,7 +111,7 @@ public class SearchWheel implements View.OnClickListener WindowManager windowmanager = (WindowManager) mFrame.getContext().getSystemService(Context.WINDOW_SERVICE); windowmanager.getDefaultDisplay().getMetrics(displayMetrics); // Get available screen height in DP - int height = Math.round(displayMetrics.heightPixels / displayMetrics.density); + int height = Math.round(displayMetrics.heightPixels / displayMetrics.density); // If height is less than 400dp, the search wheel in a straight line // In this case, move the pivot for the animation if (height < 400) @@ -180,8 +177,7 @@ public class SearchWheel implements View.OnClickListener animator.start(); if (mTouchInterceptor != null) UiUtils.visibleIf(mIsExpanded, mTouchInterceptor); - animator.addListener(new UiUtils.SimpleAnimatorListener() - { + animator.addListener(new UiUtils.SimpleAnimatorListener() { @Override public void onAnimationEnd(Animator animation) { @@ -211,18 +207,15 @@ public class SearchWheel implements View.OnClickListener private void resetSearchButtonImage() { - mSearchButton.setImageDrawable(Graphics.tint(mSearchButton.getContext(), - R.drawable.ic_search)); + mSearchButton.setImageDrawable(Graphics.tint(mSearchButton.getContext(), R.drawable.ic_search)); } private void refreshSearchButtonImage() { final SearchOption searchOption = mMapButtonsViewModel.getSearchOption().getValue(); - mSearchButton.setImageDrawable(Graphics.tint(mSearchButton.getContext(), - searchOption == null ? - R.drawable.ic_routing_search_off : - searchOption.mDrawableOff, - androidx.appcompat.R.attr.colorAccent)); + mSearchButton.setImageDrawable(Graphics.tint( + mSearchButton.getContext(), searchOption == null ? R.drawable.ic_routing_search_off : searchOption.mDrawableOff, + androidx.appcompat.R.attr.colorAccent)); } @Override @@ -233,11 +226,8 @@ public class SearchWheel implements View.OnClickListener onSearchButtonClick(v); else if (id == R.id.touch_interceptor) toggleSearchLayout(); - else if (id == R.id.search_fuel || - id == R.id.search_parking || - id == R.id.search_eat || - id == R.id.search_food || - id == R.id.search_atm) + else if (id == R.id.search_fuel || id == R.id.search_parking || id == R.id.search_eat || id == R.id.search_food + || id == R.id.search_atm) startSearch(SearchOption.fromResId(id)); } @@ -252,7 +242,8 @@ public class SearchWheel implements View.OnClickListener return; } - if (mMapButtonsViewModel.getSearchOption().getValue() != null || !TextUtils.isEmpty(SearchEngine.INSTANCE.getQuery())) + if (mMapButtonsViewModel.getSearchOption().getValue() != null + || !TextUtils.isEmpty(SearchEngine.INSTANCE.getQuery())) { mOnSearchCanceledListener.onClick(v); refreshSearchVisibility(); diff --git a/android/app/src/main/java/app/organicmaps/maplayer/ToggleMapLayerFragment.java b/android/app/src/main/java/app/organicmaps/maplayer/ToggleMapLayerFragment.java index 84ded9f3b..60e774e80 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/ToggleMapLayerFragment.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/ToggleMapLayerFragment.java @@ -5,20 +5,19 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.maplayer.isolines.IsolinesManager; -import app.organicmaps.util.SharedPropertiesUtils; +import app.organicmaps.sdk.maplayer.Mode; +import app.organicmaps.sdk.util.SharedPropertiesUtils; import app.organicmaps.util.Utils; import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment; import app.organicmaps.widget.recycler.SpanningLinearLayoutManager; import com.google.android.material.button.MaterialButton; - import java.util.ArrayList; import java.util.List; @@ -31,11 +30,13 @@ public class ToggleMapLayerFragment extends Fragment @Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { View mRoot = inflater.inflate(R.layout.fragment_toggle_map_layer, container, false); - mMapButtonsController = (MapButtonsController) requireActivity().getSupportFragmentManager().findFragmentById(R.id.map_buttons); + mMapButtonsController = + (MapButtonsController) requireActivity().getSupportFragmentManager().findFragmentById(R.id.map_buttons); MaterialButton mCloseButton = mRoot.findViewById(R.id.close_button); mCloseButton.setOnClickListener(view -> closeLayerBottomSheet()); @@ -46,9 +47,8 @@ public class ToggleMapLayerFragment extends Fragment private void initRecycler(@NonNull View root) { RecyclerView recycler = root.findViewById(R.id.recycler); - RecyclerView.LayoutManager layoutManager = new SpanningLinearLayoutManager(requireContext(), - LinearLayoutManager.HORIZONTAL, - false); + RecyclerView.LayoutManager layoutManager = + new SpanningLinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false); recycler.setLayoutManager(layoutManager); mAdapter = new LayersAdapter(getLayersItems()); recycler.setAdapter(mAdapter); @@ -70,11 +70,11 @@ public class ToggleMapLayerFragment extends Fragment { Mode mode = item.getMode(); Context context = v.getContext(); - SharedPropertiesUtils.setLayerMarkerShownForLayerMode(context, mode); + SharedPropertiesUtils.setLayerMarkerShownForLayerMode(mode); mode.setEnabled(context, !mode.isEnabled(context)); mAdapter.notifyDataSetChanged(); mMapButtonsController.updateLayerButton(); - if (IsolinesManager.from(context).shouldShowNotification()) + if (MwmApplication.from(context).getIsolinesManager().shouldShowNotification()) Utils.showSnackbar(context, v.getRootView(), R.string.isolines_toast_zooms_1_10); } diff --git a/android/app/src/main/java/app/organicmaps/maplayer/isolines/IsolinesState.java b/android/app/src/main/java/app/organicmaps/maplayer/isolines/IsolinesState.java deleted file mode 100644 index 86b03a514..000000000 --- a/android/app/src/main/java/app/organicmaps/maplayer/isolines/IsolinesState.java +++ /dev/null @@ -1,46 +0,0 @@ -package app.organicmaps.maplayer.isolines; - -import android.content.Context; -import android.view.View; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import app.organicmaps.R; -import app.organicmaps.util.Utils; - -public enum IsolinesState -{ - DISABLED, - ENABLED, - EXPIREDDATA - { - @Override - public void activate(@NonNull Context context, @Nullable View view, @Nullable View viewAbove) - { - if (view != null) - Utils.showSnackbar(context, view, viewAbove, R.string.isolines_activation_error_dialog); - else - Toast.makeText(context, R.string.isolines_activation_error_dialog, Toast.LENGTH_SHORT) - .show(); - } - }, - NODATA - { - @Override - public void activate(@NonNull Context context, @Nullable View view, @Nullable View viewAbove) - { - if (view != null) - Utils.showSnackbar(context, view, viewAbove, R.string.isolines_location_error_dialog); - else - Toast.makeText(context, R.string.isolines_location_error_dialog, Toast.LENGTH_SHORT) - .show(); - } - }; - - public void activate(@NonNull Context context, @Nullable View viewAbove, @Nullable View view) - { - /* Do nothing by default */ - } -} diff --git a/android/app/src/main/java/app/organicmaps/maplayer/traffic/TrafficState.java b/android/app/src/main/java/app/organicmaps/maplayer/traffic/TrafficState.java deleted file mode 100644 index b0ced15f8..000000000 --- a/android/app/src/main/java/app/organicmaps/maplayer/traffic/TrafficState.java +++ /dev/null @@ -1,111 +0,0 @@ -package app.organicmaps.maplayer.traffic; - -import androidx.annotation.Keep; -import androidx.annotation.MainThread; -import androidx.annotation.NonNull; - -import java.util.List; - -@SuppressWarnings("unused") -enum TrafficState -{ - DISABLED - { - @Override - protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) - { - callback.onDisabled(); - } - }, - - ENABLED - { - @Override - protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) - { - callback.onEnabled(); - } - }, - - WAITING_DATA - { - @Override - protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) - { - callback.onWaitingData(); - } - }, - - OUTDATED - { - @Override - protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) - { - callback.onOutdated(); - } - }, - - NO_DATA - { - @Override - protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) - { - callback.onNoData(); - } - }, - - NETWORK_ERROR - { - @Override - protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) - { - callback.onNetworkError(); - } - }, - - EXPIRED_DATA - { - @Override - protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) - { - callback.onExpiredData(); - } - }, - - EXPIRED_APP - { - @Override - protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) - { - callback.onExpiredApp(); - } - }; - - public void activate(@NonNull List trafficCallbacks) - { - for (TrafficManager.TrafficCallback callback : trafficCallbacks) - activateInternal(callback); - } - - protected abstract void activateInternal(@NonNull TrafficManager.TrafficCallback callback); - - interface StateChangeListener - { - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @MainThread - void onTrafficStateChanged(int state); - } - - @MainThread - static native void nativeSetListener(@NonNull StateChangeListener listener); - - static native void nativeRemoveListener(); - - static native void nativeEnable(); - - static native void nativeDisable(); - - static native boolean nativeIsEnabled(); -} diff --git a/android/app/src/main/java/app/organicmaps/maplayer/traffic/widget/TrafficButton.java b/android/app/src/main/java/app/organicmaps/maplayer/traffic/widget/TrafficButton.java index edfd31a18..f2bda4035 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/traffic/widget/TrafficButton.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/traffic/widget/TrafficButton.java @@ -7,14 +7,11 @@ import android.graphics.drawable.Drawable; import android.view.View; import android.widget.ImageButton; import android.widget.RelativeLayout; - import androidx.annotation.NonNull; import androidx.core.content.res.ResourcesCompat; - import app.organicmaps.R; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.UiUtils; - import java.util.Objects; @SuppressWarnings("unused") diff --git a/android/app/src/main/java/app/organicmaps/maplayer/traffic/widget/TrafficButtonController.java b/android/app/src/main/java/app/organicmaps/maplayer/traffic/widget/TrafficButtonController.java index a39e74c25..d03f1a2d5 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/traffic/widget/TrafficButtonController.java +++ b/android/app/src/main/java/app/organicmaps/maplayer/traffic/widget/TrafficButtonController.java @@ -2,12 +2,10 @@ package app.organicmaps.maplayer.traffic.widget; import android.app.Activity; import android.app.Dialog; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.R; -import app.organicmaps.maplayer.traffic.TrafficManager; +import app.organicmaps.sdk.maplayer.traffic.TrafficManager; import app.organicmaps.util.Utils; import com.google.android.material.dialog.MaterialAlertDialogBuilder; @@ -21,8 +19,7 @@ public class TrafficButtonController implements TrafficManager.TrafficCallback @Nullable private Dialog mDialog; - public TrafficButtonController(@NonNull TrafficButton button, - @NonNull Activity activity) + public TrafficButtonController(@NonNull TrafficButton button, @NonNull Activity activity) { mButton = button; mActivity = activity; @@ -101,8 +98,7 @@ public class TrafficButtonController implements TrafficManager.TrafficCallback { turnOn(); Utils.showSnackbar(mActivity, mActivity.findViewById(R.id.coordinator), - mActivity.findViewById(R.id.navigation_frame), - R.string.traffic_data_unavailable); + mActivity.findViewById(R.id.navigation_frame), R.string.traffic_data_unavailable); } @Override @@ -112,11 +108,11 @@ public class TrafficButtonController implements TrafficManager.TrafficCallback return; mDialog = new MaterialAlertDialogBuilder(mActivity, R.style.MwmTheme_AlertDialog) - .setMessage(R.string.common_check_internet_connection_dialog) - .setPositiveButton(R.string.ok, (dialog, which) -> TrafficManager.INSTANCE.setEnabled(false)) - .setCancelable(true) - .setOnCancelListener(dialog -> TrafficManager.INSTANCE.setEnabled(false)) - .show(); + .setMessage(R.string.common_check_internet_connection_dialog) + .setPositiveButton(R.string.ok, (dialog, which) -> TrafficManager.INSTANCE.setEnabled(false)) + .setCancelable(true) + .setOnCancelListener(dialog -> TrafficManager.INSTANCE.setEnabled(false)) + .show(); } public void destroy() @@ -130,8 +126,7 @@ public class TrafficButtonController implements TrafficManager.TrafficCallback { turnOn(); Utils.showSnackbar(mActivity, mActivity.findViewById(R.id.coordinator), - mActivity.findViewById(R.id.navigation_frame), - R.string.traffic_update_maps_text); + mActivity.findViewById(R.id.navigation_frame), R.string.traffic_update_maps_text); } @Override @@ -139,7 +134,6 @@ public class TrafficButtonController implements TrafficManager.TrafficCallback { turnOn(); Utils.showSnackbar(mActivity, mActivity.findViewById(R.id.coordinator), - mActivity.findViewById(R.id.navigation_frame), - R.string.traffic_update_app); + mActivity.findViewById(R.id.navigation_frame), R.string.traffic_update_app); } } diff --git a/android/app/src/main/java/app/organicmaps/routing/BaseRoutingErrorDialogFragment.java b/android/app/src/main/java/app/organicmaps/routing/BaseRoutingErrorDialogFragment.java index 830271a0e..1628b7bbf 100644 --- a/android/app/src/main/java/app/organicmaps/routing/BaseRoutingErrorDialogFragment.java +++ b/android/app/src/main/java/app/organicmaps/routing/BaseRoutingErrorDialogFragment.java @@ -9,19 +9,16 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ExpandableListAdapter; import android.widget.ExpandableListView; -import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; - import app.organicmaps.R; import app.organicmaps.adapter.DisabledChildSimpleExpandableListAdapter; import app.organicmaps.base.BaseMwmDialogFragment; -import app.organicmaps.downloader.CountryItem; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import com.google.android.material.dialog.MaterialAlertDialogBuilder; - +import com.google.android.material.textview.MaterialTextView; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -46,8 +43,7 @@ abstract class BaseRoutingErrorDialogFragment extends BaseMwmDialogFragment private Dialog createDialog(AlertDialog.Builder builder) { - View view = (mMissingMaps.size() == 1 ? buildSingleMapView(mMissingMaps.get(0)) - : buildMultipleMapView()); + View view = (mMissingMaps.size() == 1 ? buildSingleMapView(mMissingMaps.get(0)) : buildMultipleMapView()); builder.setView(view); return builder.create(); } @@ -58,8 +54,8 @@ abstract class BaseRoutingErrorDialogFragment extends BaseMwmDialogFragment { parseArguments(); MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog) - .setCancelable(true) - .setNegativeButton(android.R.string.cancel, null); + .setCancelable(true) + .setNegativeButton(android.R.string.cancel, null); beforeDialogCreated(builder); return createDialog(builder); } @@ -97,9 +93,9 @@ abstract class BaseRoutingErrorDialogFragment extends BaseMwmDialogFragment { @SuppressLint("InflateParams") final View countryView = View.inflate(requireActivity(), R.layout.dialog_missed_map, null); - ((TextView) countryView.findViewById(R.id.tv__title)).setText(map.name); + ((MaterialTextView) countryView.findViewById(R.id.tv__title)).setText(map.name); - final TextView szView = countryView.findViewById(R.id.tv__size); + final MaterialTextView szView = countryView.findViewById(R.id.tv__size); szView.setText(StringUtils.getFileSizeString(requireContext(), map.totalSize)); ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) szView.getLayoutParams(); lp.rightMargin = 0; @@ -142,7 +138,7 @@ abstract class BaseRoutingErrorDialogFragment extends BaseMwmDialogFragment List> countries = new ArrayList<>(); long size = 0; - for (CountryItem item: mMissingMaps) + for (CountryItem item : mMissingMaps) { Map data = new HashMap<>(); data.put(COUNTRY_NAME, item.name); @@ -161,17 +157,10 @@ abstract class BaseRoutingErrorDialogFragment extends BaseMwmDialogFragment List>> children = new ArrayList<>(); children.add(countries); - return new DisabledChildSimpleExpandableListAdapter(requireActivity(), - groups, - R.layout.item_missed_map_group, - R.layout.item_missed_map, - new String[] { GROUP_NAME, GROUP_SIZE }, - new int[] { R.id.tv__title, R.id.tv__size }, - children, - R.layout.item_missed_map, - new String[] { COUNTRY_NAME }, - new int[] { R.id.tv__title }) - { + return new DisabledChildSimpleExpandableListAdapter( + requireActivity(), groups, R.layout.item_missed_map_group, R.layout.item_missed_map, + new String[] {GROUP_NAME, GROUP_SIZE}, new int[] {R.id.tv__title, R.id.tv__size}, children, + R.layout.item_missed_map, new String[] {COUNTRY_NAME}, new int[] {R.id.tv__title}) { @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { diff --git a/android/app/src/main/java/app/organicmaps/routing/ManageRouteAdapter.java b/android/app/src/main/java/app/organicmaps/routing/ManageRouteAdapter.java index b8976aced..bf7f32769 100644 --- a/android/app/src/main/java/app/organicmaps/routing/ManageRouteAdapter.java +++ b/android/app/src/main/java/app/organicmaps/routing/ManageRouteAdapter.java @@ -8,20 +8,17 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.appcompat.content.res.AppCompatResources; import androidx.recyclerview.widget.RecyclerView; - +import com.google.android.material.imageview.ShapeableImageView; +import com.google.android.material.textview.MaterialTextView; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.MapObject; +import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.routing.RouteMarkData; import app.organicmaps.sdk.routing.RouteMarkType; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; - +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -52,8 +49,7 @@ public class ManageRouteAdapter extends RecyclerView.Adapter { - if (event.getAction() == MotionEvent.ACTION_DOWN) { - RectF deleteButtonRect = new RectF(holder.mImageViewDelete.getLeft(), - holder.mImageViewDelete.getTop(), - holder.mImageViewDelete.getRight(), - holder.mImageViewDelete.getBottom()); + RectF deleteButtonRect = new RectF(holder.mImageViewDelete.getLeft(), holder.mImageViewDelete.getTop(), + holder.mImageViewDelete.getRight(), holder.mImageViewDelete.getBottom()); if (holder.mImageViewDelete.isShown() && deleteButtonRect.contains(event.getX(), event.getY())) { @@ -177,14 +169,11 @@ public class ManageRouteAdapter extends RecyclerView.Adapter= 2); + assert (mRoutePoints.size() >= 2); // Set starting point. mRoutePoints.get(0).mPointType = RouteMarkType.Start; @@ -243,16 +232,16 @@ public class ManageRouteAdapter extends RecyclerView.Adapter { - - FrameLayout bottomSheet = ((BottomSheetDialog) dialogInterface).findViewById( - com.google.android.material.R.id.design_bottom_sheet); + FrameLayout bottomSheet = + ((BottomSheetDialog) dialogInterface).findViewById(com.google.android.material.R.id.design_bottom_sheet); if (bottomSheet != null) BottomSheetBehavior.from(bottomSheet).setState(BottomSheetBehavior.STATE_EXPANDED); @@ -90,7 +85,6 @@ public class ManageRouteBottomSheet extends BottomSheetDialogFragment // Set key listener to detect back button pressed. dialog.setOnKeyListener((dialog1, keyCode, event) -> { - if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { // Dismiss the fragment @@ -130,7 +124,7 @@ public class ManageRouteBottomSheet extends BottomSheetDialogFragment ArrayList newRoutePoints = mManageRouteAdapter.getRoutePoints(); // Make sure that the new route contains at least 2 points (start and destination). - assert(newRoutePoints.size() >= 2); + assert (newRoutePoints.size() >= 2); // Remove all existing route points. Framework.nativeRemoveRoutePoints(); @@ -187,8 +181,7 @@ public class ManageRouteBottomSheet extends BottomSheetDialogFragment } @Override - public int getMovementFlags(@NonNull RecyclerView recyclerView, - @NonNull RecyclerView.ViewHolder viewHolder) + public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { // Enable up & down dragging. No left-right swiping is enabled. return makeMovementFlags(UP | DOWN, 0); @@ -207,23 +200,19 @@ public class ManageRouteBottomSheet extends BottomSheetDialogFragment } @Override - public boolean onMove(@NonNull RecyclerView recyclerView, - @NonNull RecyclerView.ViewHolder viewHolder, + public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { - mManageRouteAdapter.moveRoutePoint(viewHolder.getAbsoluteAdapterPosition(), - target.getAbsoluteAdapterPosition()); + mManageRouteAdapter.moveRoutePoint(viewHolder.getAbsoluteAdapterPosition(), target.getAbsoluteAdapterPosition()); return true; } @Override public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) - { - } + {} @Override - public void clearView(@NonNull RecyclerView recyclerView, - @NonNull RecyclerView.ViewHolder viewHolder) + public void clearView(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { super.clearView(recyclerView, viewHolder); diff --git a/android/app/src/main/java/app/organicmaps/routing/NavigationController.java b/android/app/src/main/java/app/organicmaps/routing/NavigationController.java index c3d5a9fb3..63a51b8bd 100644 --- a/android/app/src/main/java/app/organicmaps/routing/NavigationController.java +++ b/android/app/src/main/java/app/organicmaps/routing/NavigationController.java @@ -4,8 +4,6 @@ import android.location.Location; import android.text.TextUtils; import android.view.View; import android.widget.ImageView; -import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; @@ -13,37 +11,38 @@ import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import androidx.lifecycle.ViewModelProvider; -import app.organicmaps.Framework; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.location.LocationHelper; import app.organicmaps.maplayer.MapButtonsViewModel; -import app.organicmaps.maplayer.traffic.TrafficManager; +import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Router; +import app.organicmaps.sdk.maplayer.traffic.TrafficManager; import app.organicmaps.sdk.routing.CarDirection; import app.organicmaps.sdk.routing.RoutingInfo; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Utils; import app.organicmaps.util.WindowInsetUtils; import app.organicmaps.widget.LanesView; import app.organicmaps.widget.SpeedLimitView; import app.organicmaps.widget.menu.NavMenu; import com.google.android.material.bottomsheet.BottomSheetBehavior; +import com.google.android.material.imageview.ShapeableImageView; +import com.google.android.material.textview.MaterialTextView; -public class NavigationController implements TrafficManager.TrafficCallback, - NavMenu.NavMenuListener +public class NavigationController implements TrafficManager.TrafficCallback, NavMenu.NavMenuListener { private final View mFrame; private final ImageView mNextTurnImage; - private final TextView mNextTurnDistance; - private final TextView mCircleExit; + private final MaterialTextView mNextTurnDistance; + private final MaterialTextView mCircleExit; private final View mNextNextTurnFrame; private final ImageView mNextNextTurnImage; private final View mStreetFrame; - private final TextView mNextStreet; + private final MaterialTextView mNextStreet; @NonNull private final LanesView mLanesView; @@ -57,11 +56,12 @@ public class NavigationController implements TrafficManager.TrafficCallback, private void addWindowsInsets(@NonNull View topFrame) { - ViewCompat.setOnApplyWindowInsetsListener(topFrame.findViewById(R.id.nav_next_turn_container), (view, windowInsets) -> { - view.setPadding(windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).left, view.getPaddingTop(), - view.getPaddingEnd(), view.getPaddingBottom()); - return windowInsets; - }); + ViewCompat.setOnApplyWindowInsetsListener( + topFrame.findViewById(R.id.nav_next_turn_container), (view, windowInsets) -> { + view.setPadding(windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).left, view.getPaddingTop(), + view.getPaddingEnd(), view.getPaddingBottom()); + return windowInsets; + }); } public NavigationController(AppCompatActivity activity, View.OnClickListener onSettingsClickListener, @@ -99,9 +99,8 @@ public class NavigationController implements TrafficManager.TrafficCallback, UiUtils.setViewInsetsPaddingNoBottom(v, windowInsets); final Insets safeDrawingInsets = windowInsets.getInsets(WindowInsetUtils.TYPE_SAFE_DRAWING); - nextTurnContainer.setPadding( - safeDrawingInsets.left, nextTurnContainer.getPaddingTop(), - nextTurnContainer.getPaddingEnd(), nextTurnContainer.getPaddingBottom()); + nextTurnContainer.setPadding(safeDrawingInsets.left, nextTurnContainer.getPaddingTop(), + nextTurnContainer.getPaddingEnd(), nextTurnContainer.getPaddingBottom()); navigationBarBackground.getLayoutParams().height = safeDrawingInsets.bottom; // The gesture navigation bar stays at the bottom in landscape // We need to add a background only above the nav menu @@ -261,8 +260,9 @@ public class NavigationController implements TrafficManager.TrafficCallback, private void updateSpeedLimit(@NonNull final RoutingInfo info) { - final Location location = LocationHelper.from(mFrame.getContext()).getSavedLocation(); - if (location == null) { + final Location location = MwmApplication.from(mFrame.getContext()).getLocationHelper().getSavedLocation(); + if (location == null) + { mSpeedLimit.setSpeedLimit(0, false); return; } diff --git a/android/app/src/main/java/app/organicmaps/routing/NavigationService.java b/android/app/src/main/java/app/organicmaps/routing/NavigationService.java index 4bec7926d..9582f7ae1 100644 --- a/android/app/src/main/java/app/organicmaps/routing/NavigationService.java +++ b/android/app/src/main/java/app/organicmaps/routing/NavigationService.java @@ -4,7 +4,7 @@ import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; import static android.Manifest.permission.POST_NOTIFICATIONS; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static app.organicmaps.util.Constants.Vendor.XIAOMI; +import static app.organicmaps.sdk.util.Constants.Vendor.XIAOMI; import android.annotation.SuppressLint; import android.app.ForegroundServiceStartNotAllowedException; @@ -19,7 +19,6 @@ import android.graphics.drawable.Drawable; import android.location.Location; import android.os.Build; import android.os.IBinder; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresPermission; @@ -30,20 +29,19 @@ import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationManagerCompat; import androidx.core.app.ServiceCompat; import androidx.core.content.ContextCompat; - -import app.organicmaps.Framework; import app.organicmaps.MwmActivity; import app.organicmaps.MwmApplication; import app.organicmaps.R; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.location.LocationHelper; +import app.organicmaps.sdk.location.LocationListener; import app.organicmaps.sdk.routing.RoutingInfo; -import app.organicmaps.sound.MediaPlayerWrapper; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.LocationListener; -import app.organicmaps.sound.TtsPlayer; -import app.organicmaps.util.Config; +import app.organicmaps.sdk.sound.MediaPlayerWrapper; +import app.organicmaps.sdk.sound.TtsPlayer; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.util.Graphics; -import app.organicmaps.util.LocationUtils; -import app.organicmaps.util.log.Logger; public class NavigationService extends Service implements LocationListener { @@ -84,7 +82,8 @@ public class NavigationService extends Service implements LocationListener * @param carNotificationExtender Extender used for displaying notifications in the Android Auto */ @RequiresPermission(value = ACCESS_FINE_LOCATION) - public static void startForegroundService(@NonNull Context context, @NonNull NotificationCompat.Extender carNotificationExtender) + public static void startForegroundService(@NonNull Context context, + @NonNull NotificationCompat.Extender carNotificationExtender) { Logger.i(TAG); mCarNotificationExtender = carNotificationExtender; @@ -112,12 +111,13 @@ public class NavigationService extends Service implements LocationListener Logger.i(TAG); final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); - final NotificationChannelCompat channel = new NotificationChannelCompat.Builder(CHANNEL_ID, - NotificationManagerCompat.IMPORTANCE_LOW) - .setName(context.getString(R.string.pref_navigation)) - .setLightsEnabled(false) // less annoying - .setVibrationEnabled(false) // less annoying - .build(); + final NotificationChannelCompat channel = + new NotificationChannelCompat.Builder(CHANNEL_ID, + NotificationManagerCompat.IMPORTANCE_LOW) + .setName(context.getString(R.string.pref_navigation)) + .setLightsEnabled(false) // less annoying + .setVibrationEnabled(false) // less annoying + .build(); notificationManager.createNotificationChannel(channel); } @@ -128,8 +128,7 @@ public class NavigationService extends Service implements LocationListener { // Nice colorized notifications should be supported on API=26 and later. // Nonetheless, even on API=32, Xiaomi uses their own legacy implementation that displays white-on-white instead. - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && - !XIAOMI.equalsIgnoreCase(Build.MANUFACTURER); + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !XIAOMI.equalsIgnoreCase(Build.MANUFACTURER); } @NonNull @@ -140,26 +139,26 @@ public class NavigationService extends Service implements LocationListener final int FLAG_IMMUTABLE = Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? 0 : PendingIntent.FLAG_IMMUTABLE; final Intent contentIntent = new Intent(context, MwmActivity.class); - final PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, contentIntent, - PendingIntent.FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); + final PendingIntent pendingIntent = + PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); final Intent exitIntent = new Intent(context, NavigationService.class); exitIntent.setAction(STOP_NAVIGATION); - final PendingIntent exitPendingIntent = PendingIntent.getService(context, 0, exitIntent, - PendingIntent.FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); + final PendingIntent exitPendingIntent = + PendingIntent.getService(context, 0, exitIntent, PendingIntent.FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE); mNotificationBuilder = new NotificationCompat.Builder(context, CHANNEL_ID) - .setCategory(NotificationCompat.CATEGORY_NAVIGATION) - .setPriority(NotificationManager.IMPORTANCE_LOW) - .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) - .setOngoing(true) - .setShowWhen(false) - .setOnlyAlertOnce(true) - .setSmallIcon(R.drawable.ic_logo_small) - .setContentIntent(pendingIntent) - .addAction(0, context.getString(R.string.navigation_stop_button), exitPendingIntent) - .setColorized(isColorizedSupported()) - .setColor(ContextCompat.getColor(context, R.color.notification)); + .setCategory(NotificationCompat.CATEGORY_NAVIGATION) + .setPriority(NotificationManager.IMPORTANCE_LOW) + .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) + .setOngoing(true) + .setShowWhen(false) + .setOnlyAlertOnce(true) + .setSmallIcon(R.drawable.ic_logo_small) + .setContentIntent(pendingIntent) + .addAction(0, context.getString(R.string.navigation_stop_button), exitPendingIntent) + .setColorized(isColorizedSupported()) + .setColor(ContextCompat.getColor(context, R.color.notification)); return mNotificationBuilder; } @@ -179,7 +178,7 @@ public class NavigationService extends Service implements LocationListener mNotificationBuilder = null; mCarNotificationExtender = null; - LocationHelper.from(this).removeListener(this); + MwmApplication.from(this).getLocationHelper().removeListener(this); TtsPlayer.INSTANCE.stop(); // The notification is cancelled automatically by the system. @@ -233,12 +232,12 @@ public class NavigationService extends Service implements LocationListener int type = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) type = ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION; - ServiceCompat.startForeground(this, NavigationService.NOTIFICATION_ID, getNotificationBuilder(this).build(), type); + ServiceCompat.startForeground(this, NavigationService.NOTIFICATION_ID, getNotificationBuilder(this).build(), + type); } catch (Exception e) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && - e instanceof ForegroundServiceStartNotAllowedException) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e instanceof ForegroundServiceStartNotAllowedException) { // App not in a valid state to start foreground service (e.g started from bg) Logger.e(TAG, "Not in a valid state to start foreground service", e); @@ -247,7 +246,7 @@ public class NavigationService extends Service implements LocationListener Logger.e(TAG, "Failed to promote the service to foreground", e); } - final LocationHelper locationHelper = LocationHelper.from(this); + final LocationHelper locationHelper = MwmApplication.from(this).getLocationHelper(); // Subscribe to location updates. This call is idempotent. locationHelper.addListener(this); @@ -288,7 +287,7 @@ public class NavigationService extends Service implements LocationListener if (Framework.nativeIsRouteFinished()) { routingController.cancel(); - LocationHelper.from(this).restartWithNewMode(); + MwmApplication.from(this).getLocationHelper().restartWithNewMode(); stopSelf(); return; } @@ -301,20 +300,20 @@ public class NavigationService extends Service implements LocationListener mPlayer.playback(R.raw.speed_cams_beep); // Don't spend time on updating RemoteView if notifications are not allowed. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && - ActivityCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU + && ActivityCompat.checkSelfPermission(this, POST_NOTIFICATIONS) != PERMISSION_GRANTED) return; final NotificationCompat.Builder notificationBuilder = getNotificationBuilder(this) - .setContentTitle(routingInfo.distToTurn.toString(this)) - .setContentText(routingInfo.nextStreet); + .setContentTitle(routingInfo.distToTurn.toString(this)) + .setContentText(routingInfo.nextStreet); final Drawable drawable = AppCompatResources.getDrawable(this, routingInfo.carDirection.getTurnRes()); if (drawable != null) { - final Bitmap bitmap = isColorizedSupported() ? - Graphics.drawableToBitmap(drawable) : - Graphics.drawableToBitmapWithTint(drawable, ContextCompat.getColor(this, R.color.base_accent)); + final Bitmap bitmap = isColorizedSupported() ? Graphics.drawableToBitmap(drawable) + : Graphics.drawableToBitmapWithTint( + drawable, ContextCompat.getColor(this, R.color.base_accent)); notificationBuilder.setLargeIcon(bitmap); } diff --git a/android/app/src/main/java/app/organicmaps/routing/ResultCodesHelper.java b/android/app/src/main/java/app/organicmaps/routing/ResultCodesHelper.java index cda873245..b06255377 100644 --- a/android/app/src/main/java/app/organicmaps/routing/ResultCodesHelper.java +++ b/android/app/src/main/java/app/organicmaps/routing/ResultCodesHelper.java @@ -3,119 +3,96 @@ package app.organicmaps.routing; import android.content.Context; import android.content.res.Resources; import android.util.Pair; - import androidx.annotation.NonNull; import androidx.annotation.StringRes; - import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.location.LocationHelper; - +import app.organicmaps.sdk.routing.ResultCodes; import java.util.ArrayList; import java.util.List; public class ResultCodesHelper { - // Codes correspond to native routing::RouterResultCode in routing/routing_callbacks.hpp - static final int NO_ERROR = 0; - static final int CANCELLED = 1; - static final int NO_POSITION = 2; - private static final int INCONSISTENT_MWM_ROUTE = 3; - private static final int ROUTING_FILE_NOT_EXIST = 4; - private static final int START_POINT_NOT_FOUND = 5; - private static final int END_POINT_NOT_FOUND = 6; - private static final int DIFFERENT_MWM = 7; - private static final int ROUTE_NOT_FOUND = 8; - private static final int NEED_MORE_MAPS = 9; - private static final int INTERNAL_ERROR = 10; - private static final int FILE_TOO_OLD = 11; - private static final int INTERMEDIATE_POINT_NOT_FOUND = 12; - private static final int TRANSIT_ROUTE_NOT_FOUND_NO_NETWORK = 13; - private static final int TRANSIT_ROUTE_NOT_FOUND_TOO_LONG_PEDESTRIAN = 14; - private static final int ROUTE_NOT_FOUND_REDRESS_ROUTE_ERROR = 15; - static final int HAS_WARNINGS = 16; - @NonNull - public static ResourcesHolder getDialogTitleSubtitle(@NonNull Context context, - int errorCode, int missingCount) + public static ResourcesHolder getDialogTitleSubtitle(@NonNull Context context, int errorCode, int missingCount) { - Resources resources = MwmApplication.from(context).getResources(); + Resources resources = context.getResources(); int titleRes = 0; List messages = new ArrayList<>(); @StringRes int cancelBtnResId = android.R.string.cancel; switch (errorCode) { - case NO_POSITION: - if (!LocationHelper.from(context).isActive()) - { - titleRes = R.string.dialog_routing_location_turn_on; - messages.add(resources.getString(R.string.dialog_routing_location_unknown_turn_on)); - } - else - { - titleRes = R.string.dialog_routing_check_gps; - messages.add(resources.getString(R.string.dialog_routing_error_location_not_found)); - messages.add(resources.getString(R.string.dialog_routing_location_turn_wifi)); - } - break; - case INCONSISTENT_MWM_ROUTE: - case ROUTING_FILE_NOT_EXIST: - titleRes = R.string.routing_download_maps_along; - messages.add(resources.getString(R.string.routing_requires_all_map)); - break; - case START_POINT_NOT_FOUND: - titleRes = R.string.dialog_routing_change_start; - messages.add(resources.getString(R.string.dialog_routing_start_not_determined)); - messages.add(resources.getString(R.string.dialog_routing_select_closer_start)); - break; - case END_POINT_NOT_FOUND: - titleRes = R.string.dialog_routing_change_end; - messages.add(resources.getString(R.string.dialog_routing_end_not_determined)); - messages.add(resources.getString(R.string.dialog_routing_select_closer_end)); - break; - case INTERMEDIATE_POINT_NOT_FOUND: - titleRes = R.string.dialog_routing_change_intermediate; - messages.add(resources.getString(R.string.dialog_routing_intermediate_not_determined)); - break; - case DIFFERENT_MWM: - messages.add(resources.getString(R.string.routing_failed_cross_mwm_building)); - break; - case FILE_TOO_OLD: - titleRes = R.string.downloader_update_maps; - messages.add(resources.getString(R.string.downloader_mwm_migration_dialog)); - break; - case TRANSIT_ROUTE_NOT_FOUND_NO_NETWORK: - messages.add(resources.getString(R.string.transit_not_found)); - break; - case TRANSIT_ROUTE_NOT_FOUND_TOO_LONG_PEDESTRIAN: - titleRes = R.string.dialog_pedestrian_route_is_long_header; - messages.add(resources.getString(R.string.dialog_pedestrian_route_is_long_message)); - cancelBtnResId = R.string.ok; - break; - case ROUTE_NOT_FOUND: - case ROUTE_NOT_FOUND_REDRESS_ROUTE_ERROR: - if (missingCount == 0) - { - titleRes = R.string.dialog_routing_unable_locate_route; - messages.add(resources.getString(R.string.dialog_routing_cant_build_route)); - messages.add(resources.getString(R.string.dialog_routing_change_start_or_end)); - } - else - { + case ResultCodes.NO_POSITION: + if (!MwmApplication.from(context).getLocationHelper().isActive()) + { + titleRes = R.string.dialog_routing_location_turn_on; + messages.add(resources.getString(R.string.dialog_routing_location_unknown_turn_on)); + } + else + { + titleRes = R.string.dialog_routing_check_gps; + messages.add(resources.getString(R.string.dialog_routing_error_location_not_found)); + messages.add(resources.getString(R.string.dialog_routing_location_turn_wifi)); + } + break; + case ResultCodes.INCONSISTENT_MWM_ROUTE: + case ResultCodes.ROUTING_FILE_NOT_EXIST: titleRes = R.string.routing_download_maps_along; messages.add(resources.getString(R.string.routing_requires_all_map)); - } - break; - case INTERNAL_ERROR: - titleRes = R.string.dialog_routing_system_error; - messages.add(resources.getString(R.string.dialog_routing_application_error)); - messages.add(resources.getString(R.string.dialog_routing_try_again)); - break; - case NEED_MORE_MAPS: - titleRes = R.string.dialog_routing_download_and_build_cross_route; - messages.add(resources.getString(R.string.dialog_routing_download_cross_route)); - break; + break; + case ResultCodes.START_POINT_NOT_FOUND: + titleRes = R.string.dialog_routing_change_start; + messages.add(resources.getString(R.string.dialog_routing_start_not_determined)); + messages.add(resources.getString(R.string.dialog_routing_select_closer_start)); + break; + case ResultCodes.END_POINT_NOT_FOUND: + titleRes = R.string.dialog_routing_change_end; + messages.add(resources.getString(R.string.dialog_routing_end_not_determined)); + messages.add(resources.getString(R.string.dialog_routing_select_closer_end)); + break; + case ResultCodes.INTERMEDIATE_POINT_NOT_FOUND: + titleRes = R.string.dialog_routing_change_intermediate; + messages.add(resources.getString(R.string.dialog_routing_intermediate_not_determined)); + break; + case ResultCodes.DIFFERENT_MWM: + messages.add(resources.getString(R.string.routing_failed_cross_mwm_building)); + break; + case ResultCodes.FILE_TOO_OLD: + titleRes = R.string.downloader_update_maps; + messages.add(resources.getString(R.string.downloader_mwm_migration_dialog)); + break; + case ResultCodes.TRANSIT_ROUTE_NOT_FOUND_NO_NETWORK: + messages.add(resources.getString(R.string.transit_not_found)); + break; + case ResultCodes.TRANSIT_ROUTE_NOT_FOUND_TOO_LONG_PEDESTRIAN: + titleRes = R.string.dialog_pedestrian_route_is_long_header; + messages.add(resources.getString(R.string.dialog_pedestrian_route_is_long_message)); + cancelBtnResId = R.string.ok; + break; + case ResultCodes.ROUTE_NOT_FOUND: + case ResultCodes.ROUTE_NOT_FOUND_REDRESS_ROUTE_ERROR: + if (missingCount == 0) + { + titleRes = R.string.dialog_routing_unable_locate_route; + messages.add(resources.getString(R.string.dialog_routing_cant_build_route)); + messages.add(resources.getString(R.string.dialog_routing_change_start_or_end)); + } + else + { + titleRes = R.string.routing_download_maps_along; + messages.add(resources.getString(R.string.routing_requires_all_map)); + } + break; + case ResultCodes.INTERNAL_ERROR: + titleRes = R.string.dialog_routing_system_error; + messages.add(resources.getString(R.string.dialog_routing_application_error)); + messages.add(resources.getString(R.string.dialog_routing_try_again)); + break; + case ResultCodes.NEED_MORE_MAPS: + titleRes = R.string.dialog_routing_download_and_build_cross_route; + messages.add(resources.getString(R.string.dialog_routing_download_cross_route)); + break; } StringBuilder builder = new StringBuilder(); @@ -127,9 +104,8 @@ public class ResultCodesHelper builder.append(messagePart); } - return new ResourcesHolder( - new Pair<>(titleRes == 0 ? "" : resources.getString(titleRes), builder.toString()), - cancelBtnResId); + return new ResourcesHolder(new Pair<>(titleRes == 0 ? "" : resources.getString(titleRes), builder.toString()), + cancelBtnResId); } public static boolean isDownloadable(int resultCode, int missingCount) @@ -139,20 +115,17 @@ public class ResultCodesHelper return switch (resultCode) { - case INCONSISTENT_MWM_ROUTE, - ROUTE_NOT_FOUND_REDRESS_ROUTE_ERROR, - ROUTING_FILE_NOT_EXIST, - NEED_MORE_MAPS, - ROUTE_NOT_FOUND, - FILE_TOO_OLD -> - true; + case ResultCodes.INCONSISTENT_MWM_ROUTE, ResultCodes.ROUTE_NOT_FOUND_REDRESS_ROUTE_ERROR, + ResultCodes.ROUTING_FILE_NOT_EXIST, ResultCodes.NEED_MORE_MAPS, ResultCodes.ROUTE_NOT_FOUND, + ResultCodes.FILE_TOO_OLD -> + true; default -> false; }; } public static boolean isMoreMapsNeeded(int resultCode) { - return resultCode == NEED_MORE_MAPS; + return resultCode == ResultCodes.NEED_MORE_MAPS; } public static class ResourcesHolder diff --git a/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java b/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java index faf2b85b2..66b4502da 100644 --- a/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java +++ b/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuController.java @@ -21,32 +21,28 @@ import android.widget.Button; import android.widget.ImageView; import android.widget.ScrollView; import android.widget.TextView; - import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.imageview.ShapeableImageView; -import com.google.android.material.textview.MaterialTextView; - -import app.organicmaps.Framework; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.DistanceAndAzimut; -import app.organicmaps.location.LocationHelper; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.bookmarks.data.DistanceAndAzimut; import app.organicmaps.sdk.routing.RouteMarkData; import app.organicmaps.sdk.routing.RouteMarkType; import app.organicmaps.sdk.routing.RoutingInfo; import app.organicmaps.sdk.routing.TransitRouteInfo; import app.organicmaps.sdk.routing.TransitStepInfo; -import app.organicmaps.util.Distance; +import app.organicmaps.sdk.util.Distance; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Graphics; import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.UiUtils; import app.organicmaps.widget.recycler.DotDividerItemDecoration; import app.organicmaps.widget.recycler.MultilineLayoutManager; - +import com.google.android.material.imageview.ShapeableImageView; +import com.google.android.material.textview.MaterialTextView; import java.util.LinkedList; import java.util.List; @@ -64,7 +60,7 @@ final class RoutingBottomMenuController implements View.OnClickListener @NonNull private final View mTransitFrame; @NonNull - private final TextView mError; + private final MaterialTextView mError; @NonNull private final Button mStart; @NonNull @@ -98,7 +94,7 @@ final class RoutingBottomMenuController implements View.OnClickListener View altitudeChartFrame = getViewById(activity, frame, R.id.altitude_chart_panel); View timeElevationLine = getViewById(activity, frame, R.id.time_elevation_line); View transitFrame = getViewById(activity, frame, R.id.transit_panel); - TextView error = (TextView) getViewById(activity, frame, R.id.error); + MaterialTextView error = (MaterialTextView) getViewById(activity, frame, R.id.error); Button start = (Button) getViewById(activity, frame, R.id.start); ImageView altitudeChart = (ImageView) getViewById(activity, frame, R.id.altitude_chart); MaterialTextView time = (MaterialTextView) getViewById(activity, frame, R.id.time); @@ -107,32 +103,24 @@ final class RoutingBottomMenuController implements View.OnClickListener MaterialTextView arrival = (MaterialTextView) getViewById(activity, frame, R.id.arrival); View actionFrame = getViewById(activity, frame, R.id.routing_action_frame); - return new RoutingBottomMenuController(activity, altitudeChartFrame, timeElevationLine, transitFrame, - error, start, altitudeChart, time, altitudeDifference, - timeVehicle, arrival, actionFrame, listener); + return new RoutingBottomMenuController(activity, altitudeChartFrame, timeElevationLine, transitFrame, error, start, + altitudeChart, time, altitudeDifference, timeVehicle, arrival, actionFrame, + listener); } @NonNull - private static View getViewById(@NonNull Activity activity, @NonNull View frame, - @IdRes int resourceId) + private static View getViewById(@NonNull Activity activity, @NonNull View frame, @IdRes int resourceId) { View view = frame.findViewById(resourceId); return view == null ? activity.findViewById(resourceId) : view; } - private RoutingBottomMenuController(@NonNull Activity context, - @NonNull View altitudeChartFrame, - @NonNull View timeElevationLine, - @NonNull View transitFrame, - @NonNull TextView error, - @NonNull Button start, - @NonNull ImageView altitudeChart, - @NonNull MaterialTextView time, - @NonNull MaterialTextView altitudeDifference, - @NonNull TextView timeVehicle, - @Nullable MaterialTextView arrival, - @NonNull View actionFrame, - @Nullable RoutingBottomMenuListener listener) + private RoutingBottomMenuController(@NonNull Activity context, @NonNull View altitudeChartFrame, + @NonNull View timeElevationLine, @NonNull View transitFrame, + @NonNull MaterialTextView error, @NonNull Button start, @NonNull ImageView altitudeChart, + @NonNull MaterialTextView time, @NonNull MaterialTextView altitudeDifference, + @NonNull TextView timeVehicle, @Nullable MaterialTextView arrival, + @NonNull View actionFrame, @Nullable RoutingBottomMenuListener listener) { mContext = context; mAltitudeChartFrame = altitudeChartFrame; @@ -157,8 +145,9 @@ final class RoutingBottomMenuController implements View.OnClickListener int dividerRes = ThemeUtils.getResource(mContext, R.attr.transitStepDivider); Drawable dividerDrawable = ContextCompat.getDrawable(mContext, dividerRes); Resources res = mContext.getResources(); - mTransitViewDecorator = new DotDividerItemDecoration(dividerDrawable, res.getDimensionPixelSize(R.dimen.margin_base), - res.getDimensionPixelSize(R.dimen.margin_half)); + mTransitViewDecorator = + new DotDividerItemDecoration(dividerDrawable, res.getDimensionPixelSize(R.dimen.margin_base), + res.getDimensionPixelSize(R.dimen.margin_half)); Button manageRouteButton = altitudeChartFrame.findViewById(R.id.btn__manage_route); manageRouteButton.setOnClickListener(this); @@ -202,8 +191,8 @@ final class RoutingBottomMenuController implements View.OnClickListener scrollToBottom(rv); MaterialTextView totalTimeView = mTransitFrame.findViewById(R.id.total_time); - totalTimeView.setText(RoutingController.formatRoutingTime(mContext, info.getTotalTime(), - R.dimen.text_size_routing_number)); + totalTimeView.setText( + RoutingController.formatRoutingTime(mContext, info.getTotalTime(), R.dimen.text_size_routing_number)); View dotView = mTransitFrame.findViewById(R.id.dot); View pedestrianIcon = mTransitFrame.findViewById(R.id.pedestrian_icon); MaterialTextView distanceView = mTransitFrame.findViewById(R.id.total_distance); @@ -234,9 +223,9 @@ final class RoutingBottomMenuController implements View.OnClickListener else UiUtils.hide(rv); // Show only distance between start and finish - TextView totalTimeView = mTransitFrame.findViewById(R.id.total_time); - totalTimeView.setText(mContext.getString(R.string.placepage_distance) + ": " + - totalLength.mDistanceStr + " " + totalLength.getUnitsStr(mContext)); + MaterialTextView totalTimeView = mTransitFrame.findViewById(R.id.total_time); + totalTimeView.setText(mContext.getString(R.string.placepage_distance) + ": " + totalLength.mDistanceStr + " " + + totalLength.getUnitsStr(mContext)); UiUtils.hide(mTransitFrame, R.id.dot); UiUtils.hide(mTransitFrame, R.id.pedestrian_icon); @@ -251,10 +240,12 @@ final class RoutingBottomMenuController implements View.OnClickListener { RouteMarkData segmentStart = points[i - 1]; RouteMarkData segmentEnd = points[i]; - DistanceAndAzimut dist = Framework.nativeGetDistanceAndAzimuthFromLatLon(segmentStart.mLat, segmentStart.mLon, segmentEnd.mLat, segmentEnd.mLon, 0); + DistanceAndAzimut dist = Framework.nativeGetDistanceAndAzimuthFromLatLon(segmentStart.mLat, segmentStart.mLon, + segmentEnd.mLat, segmentEnd.mLon, 0); if (i > 1) transitSteps.add(TransitStepInfo.intermediatePoint(i - 2)); - transitSteps.add(TransitStepInfo.ruler(dist.getDistance().mDistanceStr, dist.getDistance().getUnitsStr(mContext))); + transitSteps.add( + TransitStepInfo.ruler(dist.getDistance().mDistanceStr, dist.getDistance().getUnitsStr(mContext))); } return transitSteps; @@ -266,12 +257,12 @@ final class RoutingBottomMenuController implements View.OnClickListener UiUtils.show(mActionFrame); mActionMessage.setText(R.string.routing_add_start_point); mActionMessage.setTag(RouteMarkType.Start); - if (LocationHelper.from(mContext).getMyPosition() != null) + if (MwmApplication.from(mContext).getLocationHelper().getMyPosition() != null) { UiUtils.show(mActionButton); Drawable icon = ContextCompat.getDrawable(mContext, R.drawable.ic_location_crosshair); - int colorAccent = ContextCompat.getColor(mContext, - UiUtils.getStyledResourceId(mContext, androidx.appcompat.R.attr.colorAccent)); + int colorAccent = ContextCompat.getColor( + mContext, UiUtils.getStyledResourceId(mContext, androidx.appcompat.R.attr.colorAccent)); mActionIcon.setImageDrawable(Graphics.tint(icon, colorAccent)); } else @@ -360,9 +351,10 @@ final class RoutingBottomMenuController implements View.OnClickListener { mAltitudeChart.setImageBitmap(bm); UiUtils.show(mAltitudeChart); - final String unit = limits.isMetricUnits ? mAltitudeDifference.getResources().getString(R.string.m) : mAltitudeDifference.getResources().getString(R.string.ft); - mAltitudeDifference.setText("↗ " + limits.totalAscentString + " " + unit + - " ↘ " + limits.totalDescentString + " " + unit); + final String unit = limits.isMetricUnits ? mAltitudeDifference.getResources().getString(R.string.m) + : mAltitudeDifference.getResources().getString(R.string.ft); + mAltitudeDifference.setText("↗ " + limits.totalAscentString + " " + unit + " ↘ " + limits.totalDescentString + " " + + unit); UiUtils.show(mAltitudeDifference); } } @@ -407,9 +399,8 @@ final class RoutingBottomMenuController implements View.OnClickListener private static Spanned makeSpannedRoutingDetails(@NonNull Context context, @NonNull RoutingInfo routingInfo) { - CharSequence time = RoutingController.formatRoutingTime(context, - routingInfo.totalTimeInSeconds, - R.dimen.text_size_routing_number); + CharSequence time = + RoutingController.formatRoutingTime(context, routingInfo.totalTimeInSeconds, R.dimen.text_size_routing_number); SpannableStringBuilder builder = new SpannableStringBuilder(); initTimeBuilderSequence(context, time, builder); @@ -427,24 +418,14 @@ final class RoutingBottomMenuController implements View.OnClickListener { builder.append(time); - builder.setSpan(new TypefaceSpan(context.getResources().getString(R.string.robotoMedium)), - 0, - builder.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - builder.setSpan(new AbsoluteSizeSpan(context.getResources() - .getDimensionPixelSize(R.dimen.text_size_routing_number)), - 0, - builder.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - builder.setSpan(new StyleSpan(Typeface.BOLD), - 0, - builder.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - builder.setSpan(new ForegroundColorSpan(ThemeUtils.getColor(context, - android.R.attr.textColorPrimary)), - 0, - builder.length(), + builder.setSpan(new TypefaceSpan(context.getResources().getString(R.string.robotoMedium)), 0, builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + builder.setSpan( + new AbsoluteSizeSpan(context.getResources().getDimensionPixelSize(R.dimen.text_size_routing_number)), 0, + builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + builder.setSpan(new StyleSpan(Typeface.BOLD), 0, builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + builder.setSpan(new ForegroundColorSpan(ThemeUtils.getColor(context, android.R.attr.textColorPrimary)), 0, + builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } private static void initDotBuilderSequence(@NonNull Context context, @NonNull String dot, @@ -452,18 +433,12 @@ final class RoutingBottomMenuController implements View.OnClickListener { builder.append(dot); builder.setSpan(new TypefaceSpan(context.getResources().getString(R.string.robotoMedium)), - builder.length() - dot.length(), - builder.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - builder.setSpan(new AbsoluteSizeSpan(context.getResources() - .getDimensionPixelSize(R.dimen.text_size_routing_number)), - builder.length() - dot.length(), - builder.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + builder.length() - dot.length(), builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + builder.setSpan( + new AbsoluteSizeSpan(context.getResources().getDimensionPixelSize(R.dimen.text_size_routing_number)), + builder.length() - dot.length(), builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); builder.setSpan(new ForegroundColorSpan(ThemeUtils.getColor(context, R.attr.secondary)), - builder.length() - dot.length(), - builder.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + builder.length() - dot.length(), builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } private static void initDistanceBuilderSequence(@NonNull Context context, @NonNull String arrivalTime, @@ -471,22 +446,14 @@ final class RoutingBottomMenuController implements View.OnClickListener { builder.append(arrivalTime); builder.setSpan(new TypefaceSpan(context.getResources().getString(R.string.robotoMedium)), - builder.length() - arrivalTime.length(), - builder.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - builder.setSpan(new AbsoluteSizeSpan(context.getResources() - .getDimensionPixelSize(R.dimen.text_size_routing_number)), - builder.length() - arrivalTime.length(), - builder.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); - builder.setSpan(new StyleSpan(Typeface.NORMAL), - builder.length() - arrivalTime.length(), - builder.length(), + builder.length() - arrivalTime.length(), builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + builder.setSpan( + new AbsoluteSizeSpan(context.getResources().getDimensionPixelSize(R.dimen.text_size_routing_number)), + builder.length() - arrivalTime.length(), builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + builder.setSpan(new StyleSpan(Typeface.NORMAL), builder.length() - arrivalTime.length(), builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); builder.setSpan(new ForegroundColorSpan(ThemeUtils.getColor(context, android.R.attr.textColorPrimary)), - builder.length() - arrivalTime.length(), - builder.length(), - Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + builder.length() - arrivalTime.length(), builder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } @Override diff --git a/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuListener.java b/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuListener.java index cdbb78c68..1f50fdc22 100644 --- a/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuListener.java +++ b/android/app/src/main/java/app/organicmaps/routing/RoutingBottomMenuListener.java @@ -1,7 +1,6 @@ package app.organicmaps.routing; import androidx.annotation.NonNull; - import app.organicmaps.sdk.routing.RouteMarkType; public interface RoutingBottomMenuListener diff --git a/android/app/src/main/java/app/organicmaps/routing/RoutingController.java b/android/app/src/main/java/app/organicmaps/routing/RoutingController.java index 04ee5ca15..3df9ad8f0 100644 --- a/android/app/src/main/java/app/organicmaps/routing/RoutingController.java +++ b/android/app/src/main/java/app/organicmaps/routing/RoutingController.java @@ -3,20 +3,19 @@ package app.organicmaps.routing; import android.content.Context; import android.text.SpannableStringBuilder; import android.text.TextUtils; - import androidx.annotation.DimenRes; import androidx.annotation.IntRange; import androidx.annotation.MainThread; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.util.Pair; - -import app.organicmaps.Framework; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.FeatureId; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.location.LocationHelper; +import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Router; +import app.organicmaps.sdk.bookmarks.data.FeatureId; +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.routing.ResultCodes; import app.organicmaps.sdk.routing.RouteMarkData; import app.organicmaps.sdk.routing.RouteMarkType; import app.organicmaps.sdk.routing.RoutePointInfo; @@ -27,16 +26,14 @@ import app.organicmaps.sdk.routing.RoutingLoadPointsListener; import app.organicmaps.sdk.routing.RoutingOptions; import app.organicmaps.sdk.routing.RoutingProgressListener; import app.organicmaps.sdk.routing.TransitRouteInfo; -import app.organicmaps.widget.placepage.CoordinatesFormat; -import app.organicmaps.util.StringUtils; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.sdk.util.log.Logger; import app.organicmaps.util.Utils; -import app.organicmaps.util.concurrency.UiThread; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.widget.placepage.CoordinatesFormat; import java.time.LocalTime; import java.util.concurrent.TimeUnit; - @androidx.annotation.UiThread public class RoutingController { @@ -107,8 +104,7 @@ public class RoutingController private int mRemovingIntermediatePointsTransactionId; @SuppressWarnings("FieldCanBeLocal") - private final RoutingListener mRoutingListener = new RoutingListener() - { + private final RoutingListener mRoutingListener = new RoutingListener() { @MainThread @Override public void onRoutingEvent(final int resultCode, @Nullable final String[] missingMaps) @@ -118,12 +114,11 @@ public class RoutingController mLastMissingMaps = missingMaps; mContainsCachedResult = true; - if (mLastResultCode == ResultCodesHelper.NO_ERROR - || ResultCodesHelper.isMoreMapsNeeded(mLastResultCode)) + if (mLastResultCode == ResultCodes.NO_ERROR || ResultCodesHelper.isMoreMapsNeeded(mLastResultCode)) { onBuiltRoute(); } - else if (mLastResultCode == ResultCodesHelper.HAS_WARNINGS) + else if (mLastResultCode == ResultCodes.HAS_WARNINGS) { onBuiltRoute(); if (mContainer != null) @@ -145,12 +140,14 @@ public class RoutingController mContainer.onBuiltRoute(); } - private final RoutingProgressListener mRoutingProgressListener = progress -> { + private final RoutingProgressListener mRoutingProgressListener = progress -> + { mLastBuildProgress = (int) progress; updateProgress(); }; - private final RoutingLoadPointsListener mRoutingLoadPointsListener = success -> { + private final RoutingLoadPointsListener mRoutingLoadPointsListener = success -> + { if (success) prepare(getStartPoint(), getEndPoint()); }; @@ -162,9 +159,7 @@ public class RoutingController private void processRoutingEvent() { - if (!mContainsCachedResult || - mContainer == null || - mHasContainerSavedState) + if (!mContainsCachedResult || mContainer == null || mHasContainerSavedState) return; mContainsCachedResult = false; @@ -172,13 +167,13 @@ public class RoutingController if (isDrivingOptionsBuildError()) mContainer.onDrivingOptionsWarning(); - if (mLastResultCode == ResultCodesHelper.NO_ERROR || mLastResultCode == ResultCodesHelper.HAS_WARNINGS) + if (mLastResultCode == ResultCodes.NO_ERROR || mLastResultCode == ResultCodes.HAS_WARNINGS) { updatePlan(); return; } - if (mLastResultCode == ResultCodesHelper.CANCELLED) + if (mLastResultCode == ResultCodes.CANCELLED) { setBuildState(BuildState.NONE); updatePlan(); @@ -200,7 +195,8 @@ public class RoutingController private boolean isDrivingOptionsBuildError() { - return !ResultCodesHelper.isMoreMapsNeeded(mLastResultCode) && RoutingOptions.hasAnyOptions() && !isRulerRouterType(); + return !ResultCodesHelper.isMoreMapsNeeded(mLastResultCode) && RoutingOptions.hasAnyOptions() + && !isRulerRouterType(); } private void setState(State newState) @@ -264,7 +260,7 @@ public class RoutingController Framework.nativeSetRouteProgressListener(mRoutingProgressListener); Framework.nativeSetRoutingRecommendationListener(recommendation -> UiThread.run(() -> { if (recommendation == RouteRecommendationType.RebuildAfterPointsLoading) - setStartPoint(LocationHelper.from(context).getMyPosition()); + setStartPoint(MwmApplication.from(context).getLocationHelper().getMyPosition()); })); Framework.nativeSetRoutingLoadPointsListener(mRoutingLoadPointsListener); } @@ -348,12 +344,10 @@ public class RoutingController private void initLastRouteType(@Nullable MapObject startPoint, @Nullable MapObject endPoint) { if (startPoint != null && endPoint != null) - mLastRouterType = Router.getBest(startPoint.getLat(), startPoint.getLon(), - endPoint.getLat(), endPoint.getLon()); + mLastRouterType = Router.getBest(startPoint.getLat(), startPoint.getLon(), endPoint.getLat(), endPoint.getLon()); } - public void prepare(final @Nullable MapObject startPoint, final @Nullable MapObject endPoint, - Router routerType) + public void prepare(final @Nullable MapObject startPoint, final @Nullable MapObject endPoint, Router routerType) { cancel(); setState(State.PREPARE); @@ -441,8 +435,8 @@ public class RoutingController private MapObject toMapObject(@NonNull RouteMarkData point) { return MapObject.createMapObject(FeatureId.EMPTY, point.mIsMyPosition ? MapObject.MY_POSITION : MapObject.POI, - point.mTitle == null ? "" : point.mTitle, - point.mSubtitle == null ? "" : point.mSubtitle, point.mLat, point.mLon); + point.mTitle == null ? "" : point.mTitle, + point.mSubtitle == null ? "" : point.mSubtitle, point.mLat, point.mLon); } public boolean isStopPointAllowed() @@ -593,7 +587,8 @@ public class RoutingController return mBuildState == BuildState.BUILT; } - public void waitForPoiPick(@NonNull RouteMarkType pointType){ + public void waitForPoiPick(@NonNull RouteMarkType pointType) + { mWaitingPoiPickType = pointType; } @@ -775,10 +770,8 @@ public class RoutingController private static void addRoutePoint(@NonNull RouteMarkType type, @NonNull MapObject point) { Pair description = getDescriptionForPoint(point); - Framework.nativeAddRoutePoint(description.first /* title */, description.second /* subtitle */, - type, 0 /* intermediateIndex */, - point.isMyPosition(), - point.getLat(), point.getLon(), + Framework.nativeAddRoutePoint(description.first /* title */, description.second /* subtitle */, type, + 0 /* intermediateIndex */, point.isMyPosition(), point.getLat(), point.getLon(), true /* reorderIntermediatePoints */); } diff --git a/android/app/src/main/java/app/organicmaps/routing/RoutingErrorDialogFragment.java b/android/app/src/main/java/app/organicmaps/routing/RoutingErrorDialogFragment.java index bb5370cbe..dd129000d 100644 --- a/android/app/src/main/java/app/organicmaps/routing/RoutingErrorDialogFragment.java +++ b/android/app/src/main/java/app/organicmaps/routing/RoutingErrorDialogFragment.java @@ -8,18 +8,16 @@ import android.text.TextUtils; import android.util.Pair; import android.view.View; import android.widget.Button; -import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentFactory; import androidx.fragment.app.FragmentManager; - +import com.google.android.material.textview.MaterialTextView; import app.organicmaps.R; -import app.organicmaps.downloader.CountryItem; -import app.organicmaps.downloader.MapManager; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.util.UiUtils; public class RoutingErrorDialogFragment extends BaseRoutingErrorDialogFragment { @@ -40,7 +38,7 @@ public class RoutingErrorDialogFragment extends BaseRoutingErrorDialogFragment if (!TextUtils.isEmpty(titleMessage.first)) { - TextView titleView = new TextView(requireContext()); + MaterialTextView titleView = new MaterialTextView(requireContext()); titleView.setText(titleMessage.first); titleView.setPadding(65, 32, 32, 16); titleView.setTextSize(18); @@ -68,13 +66,14 @@ public class RoutingErrorDialogFragment extends BaseRoutingErrorDialogFragment @Override public void onDismiss(DialogInterface dialog) { - if (mNeedMoreMaps && mCancelled) { + if (mNeedMoreMaps && mCancelled) + { mCancelled = false; /// @todo Actually, should cancel if there is no valid route only. // I didn't realize how to distinguish NEED_MORE_MAPS but valid route is present. // Should refactor RoutingController states. - //RoutingController.get().cancel(); + // RoutingController.get().cancel(); } super.onDismiss(dialog); @@ -103,8 +102,7 @@ public class RoutingErrorDialogFragment extends BaseRoutingErrorDialogFragment long size = 0; for (CountryItem country : mMissingMaps) { - if (country.status != CountryItem.STATUS_PROGRESS && - country.status != CountryItem.STATUS_APPLYING) + if (country.status != CountryItem.STATUS_PROGRESS && country.status != CountryItem.STATUS_APPLYING) { size += country.totalSize; } @@ -112,8 +110,8 @@ public class RoutingErrorDialogFragment extends BaseRoutingErrorDialogFragment MapManager.warnOn3g(requireActivity(), size, () -> { final FragmentManager manager = requireActivity().getSupportFragmentManager(); - RoutingMapsDownloadFragment downloader = RoutingMapsDownloadFragment - .create(manager.getFragmentFactory(), getAppContextOrThrow(), mMapsArray); + RoutingMapsDownloadFragment downloader = + RoutingMapsDownloadFragment.create(manager.getFragmentFactory(), getAppContextOrThrow(), mMapsArray); downloader.show(manager, downloader.getClass().getSimpleName()); mCancelled = false; dismiss(); @@ -153,8 +151,8 @@ public class RoutingErrorDialogFragment extends BaseRoutingErrorDialogFragment Bundle args = new Bundle(); args.putInt(EXTRA_RESULT_CODE, resultCode); args.putStringArray(EXTRA_MISSING_MAPS, missingMaps); - RoutingErrorDialogFragment res = (RoutingErrorDialogFragment) - factory.instantiate(context.getClassLoader(), RoutingErrorDialogFragment.class.getName()); + RoutingErrorDialogFragment res = (RoutingErrorDialogFragment) factory.instantiate( + context.getClassLoader(), RoutingErrorDialogFragment.class.getName()); res.setArguments(args); return res; } diff --git a/android/app/src/main/java/app/organicmaps/routing/RoutingMapsDownloadFragment.java b/android/app/src/main/java/app/organicmaps/routing/RoutingMapsDownloadFragment.java index 976fe7a9d..6be818816 100644 --- a/android/app/src/main/java/app/organicmaps/routing/RoutingMapsDownloadFragment.java +++ b/android/app/src/main/java/app/organicmaps/routing/RoutingMapsDownloadFragment.java @@ -5,17 +5,14 @@ import android.content.DialogInterface; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.FragmentFactory; - import app.organicmaps.R; -import app.organicmaps.downloader.CountryItem; -import app.organicmaps.downloader.MapManager; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.widget.WheelProgressView; -import app.organicmaps.util.UiUtils; - import java.util.HashSet; import java.util.List; import java.util.Set; @@ -115,8 +112,7 @@ public class RoutingMapsDownloadFragment extends BaseRoutingErrorDialogFragment super.onStart(); setCancelable(false); - mSubscribeSlot = MapManager.nativeSubscribe(new MapManager.StorageCallback() - { + mSubscribeSlot = MapManager.nativeSubscribe(new MapManager.StorageCallback() { { update(); } @@ -172,12 +168,13 @@ public class RoutingMapsDownloadFragment extends BaseRoutingErrorDialogFragment } } - public static RoutingMapsDownloadFragment create(@NonNull FragmentFactory factory, @NonNull Context context, String[] missingMaps) + public static RoutingMapsDownloadFragment create(@NonNull FragmentFactory factory, @NonNull Context context, + String[] missingMaps) { Bundle args = new Bundle(); args.putStringArray(EXTRA_MISSING_MAPS, missingMaps); - final RoutingMapsDownloadFragment res = (RoutingMapsDownloadFragment) - factory.instantiate(context.getClassLoader(), RoutingMapsDownloadFragment.class.getName()); + final RoutingMapsDownloadFragment res = (RoutingMapsDownloadFragment) factory.instantiate( + context.getClassLoader(), RoutingMapsDownloadFragment.class.getName()); res.setArguments(args); return res; } diff --git a/android/app/src/main/java/app/organicmaps/routing/RoutingPlanController.java b/android/app/src/main/java/app/organicmaps/routing/RoutingPlanController.java index 418ba01b3..c75af51d8 100644 --- a/android/app/src/main/java/app/organicmaps/routing/RoutingPlanController.java +++ b/android/app/src/main/java/app/organicmaps/routing/RoutingPlanController.java @@ -7,23 +7,21 @@ import android.view.View; import android.widget.CompoundButton; import android.widget.RadioGroup; import android.widget.TextView; - import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.DrawableRes; import androidx.annotation.IdRes; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; -import app.organicmaps.Framework; import app.organicmaps.MwmApplication; import app.organicmaps.R; +import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.Router; import app.organicmaps.sdk.routing.RoutingInfo; import app.organicmaps.sdk.routing.RoutingOptions; import app.organicmaps.sdk.routing.TransitRouteInfo; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.settings.DrivingOptionsActivity; -import app.organicmaps.util.UiUtils; import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener; import app.organicmaps.widget.RoutingToolbarButton; import app.organicmaps.widget.ToolbarController; @@ -48,8 +46,8 @@ public class RoutingPlanController extends ToolbarController @NonNull private final WheelProgressView mProgressRuler; -// @NonNull -// private final WheelProgressView mProgressTaxi; + // @NonNull + // private final WheelProgressView mProgressTaxi; @NonNull private final RoutingBottomMenuController mRoutingBottomMenuController; @@ -66,9 +64,11 @@ public class RoutingPlanController extends ToolbarController @NonNull private final View mDrivingOptionsImage; - private void setupRouterButton(@IdRes int buttonId, final @DrawableRes int iconRes, View.OnClickListener clickListener) + private void setupRouterButton(@IdRes int buttonId, final @DrawableRes int iconRes, + View.OnClickListener clickListener) { - CompoundButton.OnCheckedChangeListener listener = (buttonView, isChecked) -> { + CompoundButton.OnCheckedChangeListener listener = (buttonView, isChecked) -> + { RoutingToolbarButton button = (RoutingToolbarButton) buttonView; button.setIcon(iconRes); if (isChecked) @@ -83,8 +83,7 @@ public class RoutingPlanController extends ToolbarController rb.setOnClickListener(clickListener); } - RoutingPlanController(View root, Activity activity, - ActivityResultLauncher startDrivingOptionsForResult, + RoutingPlanController(View root, Activity activity, ActivityResultLauncher startDrivingOptionsForResult, @NonNull RoutingPlanInplaceController.RoutingPlanListener routingPlanListener, @NonNull RoutingBottomMenuListener listener) { @@ -102,7 +101,7 @@ public class RoutingPlanController extends ToolbarController mProgressTransit = progressFrame.findViewById(R.id.progress_transit); mProgressBicycle = progressFrame.findViewById(R.id.progress_bicycle); mProgressRuler = progressFrame.findViewById(R.id.progress_ruler); -// mProgressTaxi = (WheelProgressView) progressFrame.findViewById(R.id.progress_taxi); + // mProgressTaxi = (WheelProgressView) progressFrame.findViewById(R.id.progress_taxi); mRoutingBottomMenuController = RoutingBottomMenuController.newInstance(requireActivity(), mFrame, listener); @@ -112,14 +111,15 @@ public class RoutingPlanController extends ToolbarController btn.setOnClickListener(v -> DrivingOptionsActivity.start(requireActivity(), startDrivingOptionsForResult)); mDriverOptionsLayoutListener = new SelfTerminatedDrivingOptionsLayoutListener(); - mAnimToggle = MwmApplication.from(activity.getApplicationContext()) - .getResources().getInteger(R.integer.anim_default); + mAnimToggle = + MwmApplication.from(activity.getApplicationContext()).getResources().getInteger(R.integer.anim_default); final View menuFrame = activity.findViewById(R.id.menu_frame); - final PaddingInsetsListener insetsListener = new PaddingInsetsListener.Builder() - .setInsetsTypeMask(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout()) - .setExcludeTop() - .build(); + final PaddingInsetsListener insetsListener = + new PaddingInsetsListener.Builder() + .setInsetsTypeMask(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout()) + .setExcludeTop() + .build(); ViewCompat.setOnApplyWindowInsetsListener(menuFrame, insetsListener); } @@ -139,10 +139,10 @@ public class RoutingPlanController extends ToolbarController { setupRouterButton(R.id.vehicle, R.drawable.ic_car, this::onVehicleModeSelected); setupRouterButton(R.id.pedestrian, R.drawable.ic_pedestrian, this::onPedestrianModeSelected); -// setupRouterButton(R.id.taxi, R.drawable.ic_taxi, this::onTaxiModeSelected); - setupRouterButton(R.id.transit, R.drawable.ic_transit, this::onTransitModeSelected); + // setupRouterButton(R.id.taxi, R.drawable.ic_taxi, this::onTaxiModeSelected); + setupRouterButton(R.id.transit, R.drawable.ic_route_planning_metro_40px, this::onTransitModeSelected); setupRouterButton(R.id.bicycle, R.drawable.ic_bike, this::onBicycleModeSelected); - setupRouterButton(R.id.ruler, R.drawable.ic_ruler_route, this::onRulerModeSelected); + setupRouterButton(R.id.ruler, app.organicmaps.sdk.R.drawable.ic_ruler_route, this::onRulerModeSelected); } private void onTransitModeSelected(@NonNull View v) @@ -195,7 +195,7 @@ public class RoutingPlanController extends ToolbarController final boolean ready = (buildState == RoutingController.BuildState.BUILT); - if (!ready) + if (!ready) { mRoutingBottomMenuController.hideAltitudeChartAndRoutingDetails(); return; @@ -224,42 +224,43 @@ public class RoutingPlanController extends ToolbarController public void updateBuildProgress(int progress, @NonNull Router router) { - UiUtils.invisible(mProgressVehicle, mProgressPedestrian, mProgressTransit, - mProgressBicycle, mProgressRuler); - WheelProgressView progressView; - switch (router) + UiUtils.invisible(mProgressVehicle, mProgressPedestrian, mProgressTransit, mProgressBicycle, mProgressRuler); + WheelProgressView progressView = switch (router) { - case Vehicle: - mRouterTypes.check(R.id.vehicle); - progressView = mProgressVehicle; - break; - case Pedestrian: - mRouterTypes.check(R.id.pedestrian); - progressView = mProgressPedestrian; - break; - //case Taxi: - // { - // mRouterTypes.check(R.id.taxi); - // progressView = mProgressTaxi; - // } - case Transit: - mRouterTypes.check(R.id.transit); - progressView = mProgressTransit; - break; - case Bicycle: - mRouterTypes.check(R.id.bicycle); - progressView = mProgressBicycle; - break; - case Ruler: - mRouterTypes.check(R.id.ruler); - progressView = mProgressRuler; - break; - default: - throw new IllegalArgumentException("unknown router: " + router); - } + case Vehicle -> + { + mRouterTypes.check(R.id.vehicle); + yield mProgressVehicle; + } + case Pedestrian -> + { + mRouterTypes.check(R.id.pedestrian); + yield mProgressPedestrian; + } + // case Taxi: + // { + // mRouterTypes.check(R.id.taxi); + // progressView = mProgressTaxi; + // } + case Transit -> + { + mRouterTypes.check(R.id.transit); + yield mProgressTransit; + } + case Bicycle -> + { + mRouterTypes.check(R.id.bicycle); + yield mProgressBicycle; + } + case Ruler -> + { + mRouterTypes.check(R.id.ruler); + yield mProgressRuler; + } + default -> throw new IllegalArgumentException("unknown router: " + router); + }; - RoutingToolbarButton button = mRouterTypes - .findViewById(mRouterTypes.getCheckedRadioButtonId()); + RoutingToolbarButton button = mRouterTypes.findViewById(mRouterTypes.getCheckedRadioButtonId()); button.progress(); updateProgressLabels(); @@ -317,8 +318,7 @@ public class RoutingPlanController extends ToolbarController boolean hasAnyOptions = RoutingOptions.hasAnyOptions() && !isRulerType(); UiUtils.showIf(hasAnyOptions, mDrivingOptionsImage); TextView title = mDrivingOptionsBtnContainer.findViewById(R.id.driving_options_btn_title); - title.setText(hasAnyOptions ? R.string.change_driving_options_btn - : R.string.define_to_avoid_btn); + title.setText(hasAnyOptions ? R.string.change_driving_options_btn : R.string.define_to_avoid_btn); } public void hideDrivingOptionsView() @@ -334,9 +334,7 @@ public class RoutingPlanController extends ToolbarController return 0; View driverOptionsView = getDrivingOptionsBtnContainer(); - int extraOppositeOffset = UiUtils.isVisible(driverOptionsView) - ? 0 - : driverOptionsView.getHeight(); + int extraOppositeOffset = UiUtils.isVisible(driverOptionsView) ? 0 : driverOptionsView.getHeight(); return frameHeight - extraOppositeOffset; } @@ -344,8 +342,8 @@ public class RoutingPlanController extends ToolbarController private class SelfTerminatedDrivingOptionsLayoutListener implements View.OnLayoutChangeListener { @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, - int oldTop, int oldRight, int oldBottom) + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, + int oldBottom) { mRoutingPlanListener.onRoutingPlanStartAnimate(UiUtils.isVisible(getFrame())); mDrivingOptionsBtnContainer.removeOnLayoutChangeListener(this); diff --git a/android/app/src/main/java/app/organicmaps/routing/RoutingPlanFragment.java b/android/app/src/main/java/app/organicmaps/routing/RoutingPlanFragment.java index 0976a4bb0..5080c6383 100644 --- a/android/app/src/main/java/app/organicmaps/routing/RoutingPlanFragment.java +++ b/android/app/src/main/java/app/organicmaps/routing/RoutingPlanFragment.java @@ -4,10 +4,8 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.MwmActivity; import app.organicmaps.R; import app.organicmaps.base.BaseMwmFragment; @@ -15,7 +13,6 @@ import app.organicmaps.sdk.Router; public class RoutingPlanFragment extends BaseMwmFragment { - private RoutingPlanController mPlanController; @Override @@ -23,7 +20,8 @@ public class RoutingPlanFragment extends BaseMwmFragment { final MwmActivity activity = (MwmActivity) requireActivity(); View res = inflater.inflate(R.layout.fragment_routing, container, false); - mPlanController = new RoutingPlanController(res, activity, activity.startDrivingOptionsForResult, activity, activity); + mPlanController = + new RoutingPlanController(res, activity, activity.startDrivingOptionsForResult, activity, activity); return res; } @@ -57,5 +55,4 @@ public class RoutingPlanFragment extends BaseMwmFragment { mPlanController.showAddFinishFrame(); } - } diff --git a/android/app/src/main/java/app/organicmaps/routing/RoutingPlanInplaceController.java b/android/app/src/main/java/app/organicmaps/routing/RoutingPlanInplaceController.java index d71c97332..06e766475 100644 --- a/android/app/src/main/java/app/organicmaps/routing/RoutingPlanInplaceController.java +++ b/android/app/src/main/java/app/organicmaps/routing/RoutingPlanInplaceController.java @@ -4,14 +4,12 @@ import android.animation.Animator; import android.animation.ValueAnimator; import android.content.Intent; import android.os.Bundle; - import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.MwmActivity; import app.organicmaps.R; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.util.UiUtils; public class RoutingPlanInplaceController extends RoutingPlanController { @@ -26,7 +24,8 @@ public class RoutingPlanInplaceController extends RoutingPlanController @NonNull RoutingPlanListener routingPlanListener, @NonNull RoutingBottomMenuListener listener) { - super(activity.findViewById(R.id.routing_plan_frame), activity, startDrivingOptionsForResult, routingPlanListener, listener); + super(activity.findViewById(R.id.routing_plan_frame), activity, startDrivingOptionsForResult, routingPlanListener, + listener); mRoutingPlanListener = routingPlanListener; } @@ -70,8 +69,7 @@ public class RoutingPlanInplaceController extends RoutingPlanController ValueAnimator animator = ValueAnimator.ofFloat(show ? -getFrame().getHeight() : 0, show ? 0 : -getFrame().getHeight()); animator.addUpdateListener(animation -> getFrame().setTranslationY((Float) animation.getAnimatedValue())); - animator.addListener(new UiUtils.SimpleAnimatorListener() - { + animator.addListener(new UiUtils.SimpleAnimatorListener() { @Override public void onAnimationEnd(Animator animation) { diff --git a/android/app/src/main/java/app/organicmaps/routing/TransitStepAdapter.java b/android/app/src/main/java/app/organicmaps/routing/TransitStepAdapter.java index e5b032fd2..d87b29b18 100644 --- a/android/app/src/main/java/app/organicmaps/routing/TransitStepAdapter.java +++ b/android/app/src/main/java/app/organicmaps/routing/TransitStepAdapter.java @@ -3,13 +3,10 @@ package app.organicmaps.routing; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - import app.organicmaps.R; import app.organicmaps.sdk.routing.TransitStepInfo; - import java.util.ArrayList; import java.util.List; @@ -21,8 +18,8 @@ public class TransitStepAdapter extends RecyclerView.Adapter= drawable.getIntrinsicHeight()) vPad = (clearHeight - drawable.getIntrinsicHeight()) / 2; - int acceptableDrawableHeight = clearHeight >= drawable.getIntrinsicHeight() ? drawable.getIntrinsicHeight() - : clearHeight; + int acceptableDrawableHeight = + clearHeight >= drawable.getIntrinsicHeight() ? drawable.getIntrinsicHeight() : clearHeight; // A transit icon must be squared-shaped. So, if the drawable width is greater than height the // drawable will be squeezed horizontally to make it squared-shape. int acceptableDrawableWidth = drawable.getIntrinsicWidth() > acceptableDrawableHeight - ? acceptableDrawableHeight : drawable.getIntrinsicWidth(); - mDrawableBounds.set(getPaddingStart(), getPaddingTop() + vPad, - acceptableDrawableWidth + getPaddingStart(), + ? acceptableDrawableHeight + : drawable.getIntrinsicWidth(); + mDrawableBounds.set(getPaddingStart(), getPaddingTop() + vPad, acceptableDrawableWidth + getPaddingStart(), getPaddingTop() + vPad + acceptableDrawableHeight); } @@ -184,8 +183,7 @@ public class TransitStepView extends View implements MultilineLayoutManager.Sque { if (getBackground() == null) { - canvas.drawRoundRect(mBackgroundBounds, mBackgroundCornerRadius, mBackgroundCornerRadius, - mBackgroundPaint); + canvas.drawRoundRect(mBackgroundBounds, mBackgroundCornerRadius, mBackgroundCornerRadius, mBackgroundPaint); } if (mDrawable != null) @@ -193,16 +191,15 @@ public class TransitStepView extends View implements MultilineLayoutManager.Sque if (!TextUtils.isEmpty(mText)) { - int yPos = (int) ((getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)) ; - int xPos = mDrawable != null - ? mDrawable.getBounds().right + getPaddingStart() - : (int) ((getWidth() - mTextPaint.measureText(mText)) / 2); + int yPos = (int) ((getHeight() / 2) - ((mTextPaint.descent() + mTextPaint.ascent()) / 2)); + int xPos = mDrawable != null ? mDrawable.getBounds().right + getPaddingStart() + : (int) ((getWidth() - mTextPaint.measureText(mText)) / 2); canvas.drawText(mText, xPos, yPos, mTextPaint); } } - private void drawDrawable(@NonNull Context context, @NonNull TransitStepType type, - @NonNull Drawable drawable, @NonNull Canvas canvas) + private void drawDrawable(@NonNull Context context, @NonNull TransitStepType type, @NonNull Drawable drawable, + @NonNull Canvas canvas) { if (type == TransitStepType.PEDESTRIAN) { diff --git a/android/app/src/main/java/app/organicmaps/sdk/ChoosePositionMode.java b/android/app/src/main/java/app/organicmaps/sdk/ChoosePositionMode.java index 62aaa7da2..baa55016f 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/ChoosePositionMode.java +++ b/android/app/src/main/java/app/organicmaps/sdk/ChoosePositionMode.java @@ -14,7 +14,8 @@ public enum ChoosePositionMode } /** - * @param isBusiness selection area will be bounded by building borders, if its true (eg. true for businesses in buildings). + * @param isBusiness selection area will be bounded by building borders, if its true (eg. true for businesses in + * buildings). * @param applyPosition if true, map will be animated to currently selected object. */ public static void set(@NonNull ChoosePositionMode mode, boolean isBusiness, boolean applyPosition) @@ -29,9 +30,7 @@ public enum ChoosePositionMode private final int mode; - - private static native void nativeSet(int mode, boolean isBusiness, - boolean applyPosition); + private static native void nativeSet(int mode, boolean isBusiness, boolean applyPosition); private static native int nativeGet(); } diff --git a/android/app/src/main/java/app/organicmaps/sdk/DownloadResourcesLegacyActivity.java b/android/app/src/main/java/app/organicmaps/sdk/DownloadResourcesLegacyActivity.java new file mode 100644 index 000000000..58c2558c2 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/DownloadResourcesLegacyActivity.java @@ -0,0 +1,30 @@ +package app.organicmaps.sdk; + +import androidx.annotation.Keep; + +public class DownloadResourcesLegacyActivity +{ + // Error codes, should match the same codes in JNI + public static final int ERR_DOWNLOAD_SUCCESS = 0; + public static final int ERR_DISK_ERROR = -1; + public static final int ERR_NOT_ENOUGH_FREE_SPACE = -2; + public static final int ERR_STORAGE_DISCONNECTED = -3; + public static final int ERR_DOWNLOAD_ERROR = -4; + public static final int ERR_NO_MORE_FILES = -5; + public static final int ERR_FILE_IN_PROGRESS = -6; + + public interface Listener + { + // Called by JNI. + @Keep + void onProgress(int percent); + + // Called by JNI. + @Keep + void onFinish(int errorCode); + } + + public static native int nativeGetBytesToDownload(); + public static native int nativeStartNextFileDownload(Listener listener); + public static native void nativeCancelCurrentFile(); +} diff --git a/android/app/src/main/java/app/organicmaps/Framework.java b/android/app/src/main/java/app/organicmaps/sdk/Framework.java similarity index 85% rename from android/app/src/main/java/app/organicmaps/Framework.java rename to android/app/src/main/java/app/organicmaps/sdk/Framework.java index fabb98bdd..67a8dbc06 100644 --- a/android/app/src/main/java/app/organicmaps/Framework.java +++ b/android/app/src/main/java/app/organicmaps/sdk/Framework.java @@ -1,31 +1,27 @@ -package app.organicmaps; +package app.organicmaps.sdk; import android.graphics.Bitmap; - import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.Size; - -import app.organicmaps.api.ParsedRoutingData; -import app.organicmaps.api.ParsedSearchRequest; -import app.organicmaps.api.RequestType; -import app.organicmaps.bookmarks.data.DistanceAndAzimut; -import app.organicmaps.bookmarks.data.FeatureId; -import app.organicmaps.bookmarks.data.MapObject; +import app.organicmaps.sdk.api.ParsedRoutingData; +import app.organicmaps.sdk.api.ParsedSearchRequest; +import app.organicmaps.sdk.api.RequestType; +import app.organicmaps.sdk.bookmarks.data.DistanceAndAzimut; +import app.organicmaps.sdk.bookmarks.data.FeatureId; +import app.organicmaps.sdk.bookmarks.data.MapObject; import app.organicmaps.sdk.routing.JunctionInfo; import app.organicmaps.sdk.routing.RouteMarkData; import app.organicmaps.sdk.routing.RouteMarkType; import app.organicmaps.sdk.routing.RoutingInfo; -import app.organicmaps.sdk.routing.TransitRouteInfo; -import app.organicmaps.sdk.PlacePageActivationListener; import app.organicmaps.sdk.routing.RoutingListener; import app.organicmaps.sdk.routing.RoutingLoadPointsListener; import app.organicmaps.sdk.routing.RoutingProgressListener; import app.organicmaps.sdk.routing.RoutingRecommendationListener; -import app.organicmaps.settings.SettingsPrefsFragment; -import app.organicmaps.util.Constants; - +import app.organicmaps.sdk.routing.TransitRouteInfo; +import app.organicmaps.sdk.settings.SpeedCameraMode; +import app.organicmaps.sdk.util.Constants; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -63,8 +59,8 @@ public class Framework public static String getHttpGe0Url(double lat, double lon, double zoomLevel, String name) { - return nativeGetGe0Url(lat, lon, zoomLevel, name).replaceFirst( - Constants.Url.SHORT_SHARE_PREFIX, Constants.Url.HTTP_SHARE_PREFIX); + return nativeGetGe0Url(lat, lon, zoomLevel, name) + .replaceFirst(Constants.Url.SHORT_SHARE_PREFIX, Constants.Url.HTTP_SHARE_PREFIX); } /** @@ -74,21 +70,19 @@ public class Framework * @return Bitmap if there's pedestrian or bicycle route and null otherwise. */ @Nullable - public static Bitmap generateRouteAltitudeChart(int width, int height, - @NonNull RouteAltitudeLimits limits) + public static Bitmap generateRouteAltitudeChart(int width, int height, @NonNull RouteAltitudeLimits limits) { if (width <= 0 || height <= 0) return null; - final int[] altitudeChartBits = Framework.nativeGenerateRouteAltitudeChartBits(width, height, - limits); + final int[] altitudeChartBits = Framework.nativeGenerateRouteAltitudeChartBits(width, height, limits); if (altitudeChartBits == null) return null; return Bitmap.createBitmap(altitudeChartBits, width, height, Bitmap.Config.ARGB_8888); } - public static void setSpeedCamerasMode(@NonNull SettingsPrefsFragment.SpeedCameraMode mode) + public static void setSpeedCamerasMode(@NonNull SpeedCameraMode mode) { nativeSetSpeedCamManagerMode(mode.ordinal()); } @@ -102,9 +96,12 @@ public class Framework @Size(2) public static native double[] nativeGetScreenRectCenter(); - public static native DistanceAndAzimut nativeGetDistanceAndAzimuth(double dstMerX, double dstMerY, double srcLat, double srcLon, double north); + public static native DistanceAndAzimut nativeGetDistanceAndAzimuth(double dstMerX, double dstMerY, double srcLat, + double srcLon, double north); - public static native DistanceAndAzimut nativeGetDistanceAndAzimuthFromLatLon(double dstLat, double dstLon, double srcLat, double srcLon, double north); + public static native DistanceAndAzimut nativeGetDistanceAndAzimuthFromLatLon(double dstLat, double dstLon, + double srcLat, double srcLon, + double north); public static native String nativeFormatLatLon(double lat, double lon, int coordFormat); @@ -121,20 +118,20 @@ public class Framework public static native void nativeRemovePlacePageActivationListener(@NonNull PlacePageActivationListener listener); -// @UiThread -// public static native String nativeGetOutdatedCountriesString(); -// -// @UiThread -// @NonNull -// public static native String[] nativeGetOutdatedCountries(); -// -// @UiThread -// @DoAfterUpdate -// public static native int nativeToDoAfterUpdate(); -// -// public static native boolean nativeIsDataVersionChanged(); -// -// public static native void nativeUpdateSavedDataVersion(); + // @UiThread + // public static native String nativeGetOutdatedCountriesString(); + // + // @UiThread + // @NonNull + // public static native String[] nativeGetOutdatedCountries(); + // + // @UiThread + // @DoAfterUpdate + // public static native int nativeToDoAfterUpdate(); + // + // public static native boolean nativeIsDataVersionChanged(); + // + // public static native void nativeUpdateSavedDataVersion(); private static native long nativeGetDataVersion(); @@ -160,12 +157,13 @@ public class Framework public static native ParsedSearchRequest nativeGetParsedSearchRequest(); public static native @Nullable String nativeGetParsedAppName(); public static native @Nullable String nativeGetParsedOAuth2Code(); - @Nullable @Size(2) + @Nullable + @Size(2) public static native double[] nativeGetParsedCenterLatLon(); public static native @Nullable String nativeGetParsedBackUrl(); public static native void nativeDeactivatePopup(); - public static native void nativeDeactivateMapSelectionCircle(); + public static native void nativeDeactivateMapSelectionCircle(boolean restoreViewport); public static native String nativeGetDataFileExt(); @@ -205,7 +203,8 @@ public class Framework public static native JunctionInfo[] nativeGetRouteJunctionPoints(); @Nullable - public static native final int[] nativeGenerateRouteAltitudeChartBits(int width, int height, RouteAltitudeLimits routeAltitudeLimits); + public static native final int[] nativeGenerateRouteAltitudeChartBits(int width, int height, + RouteAltitudeLimits routeAltitudeLimits); // When an end user is going to a turn he gets sound turn instructions. // If C++ part wants the client to pronounce an instruction nativeGenerateTurnNotifications returns @@ -235,14 +234,12 @@ public class Framework public static void addRoutePoint(RouteMarkData point, boolean reorderIntermediatePoints) { - Framework.nativeAddRoutePoint(point.mTitle, point.mSubtitle, point.mPointType, - point.mIntermediateIndex, point.mIsMyPosition, - point.mLat, point.mLon, reorderIntermediatePoints); + Framework.nativeAddRoutePoint(point.mTitle, point.mSubtitle, point.mPointType, point.mIntermediateIndex, + point.mIsMyPosition, point.mLat, point.mLon, reorderIntermediatePoints); } public static native void nativeAddRoutePoint(String title, String subtitle, @NonNull RouteMarkType markType, - int intermediateIndex, boolean isMyPosition, - double lat, double lon, + int intermediateIndex, boolean isMyPosition, double lat, double lon, boolean reorderIntermediatePoints); public static native void nativeRemoveRoutePoints(); diff --git a/android/app/src/main/java/app/organicmaps/Map.java b/android/app/src/main/java/app/organicmaps/sdk/Map.java similarity index 85% rename from android/app/src/main/java/app/organicmaps/Map.java rename to android/app/src/main/java/app/organicmaps/sdk/Map.java index 96d4da028..f319315ee 100644 --- a/android/app/src/main/java/app/organicmaps/Map.java +++ b/android/app/src/main/java/app/organicmaps/sdk/Map.java @@ -1,19 +1,20 @@ -package app.organicmaps; +package app.organicmaps.sdk; import android.content.Context; import android.graphics.Rect; import android.view.MotionEvent; import android.view.Surface; - import androidx.annotation.Nullable; - -import app.organicmaps.display.DisplayType; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.util.Config; -import app.organicmaps.util.ROMUtils; -import app.organicmaps.util.UiUtils; -import app.organicmaps.util.concurrency.UiThread; -import app.organicmaps.util.log.Logger; +import app.organicmaps.BuildConfig; +import app.organicmaps.MwmApplication; +import app.organicmaps.R; +import app.organicmaps.sdk.display.DisplayType; +import app.organicmaps.sdk.location.LocationHelper; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.ROMUtils; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.sdk.util.log.Logger; public final class Map { @@ -168,11 +169,11 @@ public final class Map mRequireResize = false; setupWidgets(context, surfaceFrame.width(), surfaceFrame.height()); - final LocationHelper locationHelper = LocationHelper.from(context); + final LocationHelper locationHelper = MwmApplication.from(context).getLocationHelper(); final boolean firstStart = locationHelper.isInFirstRun(); - if (!nativeCreateEngine(surface, surfaceDpi, firstStart, mLaunchByDeepLink, - BuildConfig.VERSION_CODE, ROMUtils.isCustomROM())) + if (!nativeCreateEngine(surface, surfaceDpi, firstStart, mLaunchByDeepLink, BuildConfig.VERSION_CODE, + ROMUtils.isCustomROM())) { if (mCallbackUnsupported != null) mCallbackUnsupported.report(); @@ -190,7 +191,8 @@ public final class Map mMapRenderingListener.onRenderingCreated(); } - public void onSurfaceChanged(final Context context, final Surface surface, Rect surfaceFrame, boolean isSurfaceCreating) + public void onSurfaceChanged(final Context context, final Surface surface, Rect surfaceFrame, + boolean isSurfaceCreating) { if (isThemeChangingProcess(context)) { @@ -213,7 +215,8 @@ public final class Map public void onSurfaceDestroyed(boolean activityIsChangingConfigurations, boolean isAdded) { - Logger.d(TAG, "mSurfaceCreated = " + mSurfaceCreated + ", mSurfaceAttached = " + mSurfaceAttached + ", isAdded = " + isAdded); + Logger.d(TAG, "mSurfaceCreated = " + mSurfaceCreated + ", mSurfaceAttached = " + mSurfaceAttached + + ", isAdded = " + isAdded); if (!mSurfaceCreated || !mSurfaceAttached || !isAdded) return; @@ -267,7 +270,7 @@ public final class Map nativeResumeSurfaceRendering(); } - boolean isContextCreated() + public boolean isContextCreated() { return mSurfaceCreated; } @@ -300,9 +303,8 @@ public final class Map } else { - nativeOnTouch(actionType, - event.getPointerId(0), event.getX(0), event.getY(0), - event.getPointerId(1), event.getX(1), event.getY(1), pointerIndex); + nativeOnTouch(actionType, event.getPointerId(0), event.getX(0), event.getY(0), event.getPointerId(1), + event.getX(1), event.getY(1), pointerIndex); } } @@ -331,32 +333,30 @@ public final class Map updateBottomWidgetsOffset(context, mBottomWidgetOffsetX, mBottomWidgetOffsetY); if (mDisplayType == DisplayType.Device) { - nativeSetupWidget(WIDGET_SCALE_FPS_LABEL, UiUtils.dimen(context, R.dimen.margin_base), UiUtils.dimen(context, R.dimen.margin_base) * 2, ANCHOR_LEFT_TOP); + nativeSetupWidget(WIDGET_SCALE_FPS_LABEL, UiUtils.dimen(context, R.dimen.margin_base), + UiUtils.dimen(context, R.dimen.margin_base) * 2, ANCHOR_LEFT_TOP); updateCompassOffset(context, mCurrentCompassOffsetX, mCurrentCompassOffsetY, false); } else { - nativeSetupWidget(WIDGET_SCALE_FPS_LABEL, (float) mWidth / 2 + UiUtils.dimen(context, R.dimen.margin_base) * 2, UiUtils.dimen(context, R.dimen.margin_base), ANCHOR_LEFT_TOP); + nativeSetupWidget(WIDGET_SCALE_FPS_LABEL, (float) mWidth / 2 + UiUtils.dimen(context, R.dimen.margin_base) * 2, + UiUtils.dimen(context, R.dimen.margin_base), ANCHOR_LEFT_TOP); updateCompassOffset(context, mWidth, mCurrentCompassOffsetY, true); } } private void updateRulerOffset(final Context context, int offsetX, int offsetY) { - nativeSetupWidget(WIDGET_RULER, - UiUtils.dimen(context, R.dimen.margin_ruler) + offsetX, - mHeight - UiUtils.dimen(context, R.dimen.margin_ruler) - offsetY, - ANCHOR_LEFT_BOTTOM); + nativeSetupWidget(WIDGET_RULER, UiUtils.dimen(context, R.dimen.margin_ruler) + offsetX, + mHeight - UiUtils.dimen(context, R.dimen.margin_ruler) - offsetY, ANCHOR_LEFT_BOTTOM); if (mSurfaceCreated) nativeApplyWidgets(); } private void updateAttributionOffset(final Context context, int offsetX, int offsetY) { - nativeSetupWidget(WIDGET_COPYRIGHT, - UiUtils.dimen(context, R.dimen.margin_ruler) + offsetX, - mHeight - UiUtils.dimen(context, R.dimen.margin_ruler) - offsetY, - ANCHOR_LEFT_BOTTOM); + nativeSetupWidget(WIDGET_COPYRIGHT, UiUtils.dimen(context, R.dimen.margin_ruler) + offsetX, + mHeight - UiUtils.dimen(context, R.dimen.margin_ruler) - offsetY, ANCHOR_LEFT_BOTTOM); if (mSurfaceCreated) nativeApplyWidgets(); } @@ -367,18 +367,14 @@ public final class Map } // Engine - private static native boolean nativeCreateEngine(Surface surface, int density, - boolean firstLaunch, - boolean isLaunchByDeepLink, - int appVersionCode, - boolean isCustomROM); + private static native boolean nativeCreateEngine(Surface surface, int density, boolean firstLaunch, + boolean isLaunchByDeepLink, int appVersionCode, boolean isCustomROM); private static native boolean nativeIsEngineCreated(); private static native void nativeUpdateEngineDpi(int dpi); - private static native void nativeSetRenderingInitializationFinishedListener( - @Nullable MapRenderingListener listener); + private static native void nativeSetRenderingInitializationFinishedListener(@Nullable MapRenderingListener listener); private static native void nativeExecuteMapApiRequest(); @@ -415,5 +411,6 @@ public final class Map private static native void nativeOnScale(double factor, double focusX, double focusY, boolean isAnim); - private static native void nativeOnTouch(int actionType, int id1, float x1, float y1, int id2, float x2, float y2, int maskedPointer); + private static native void nativeOnTouch(int actionType, int id1, float x1, float y1, int id2, float x2, float y2, + int maskedPointer); } diff --git a/android/app/src/main/java/app/organicmaps/MapRenderingListener.java b/android/app/src/main/java/app/organicmaps/sdk/MapRenderingListener.java similarity index 71% rename from android/app/src/main/java/app/organicmaps/MapRenderingListener.java rename to android/app/src/main/java/app/organicmaps/sdk/MapRenderingListener.java index 779e661db..f463e9157 100644 --- a/android/app/src/main/java/app/organicmaps/MapRenderingListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/MapRenderingListener.java @@ -1,4 +1,4 @@ -package app.organicmaps; +package app.organicmaps.sdk; import androidx.annotation.Keep; @@ -11,5 +11,6 @@ public interface MapRenderingListener // Called from JNI. @Keep @SuppressWarnings("unused") - default void onRenderingInitializationFinished() {} + default void onRenderingInitializationFinished() + {} } diff --git a/android/app/src/main/java/app/organicmaps/sdk/OrganicMaps.java b/android/app/src/main/java/app/organicmaps/sdk/OrganicMaps.java index a4fdf61b2..627d0c746 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/OrganicMaps.java +++ b/android/app/src/main/java/app/organicmaps/sdk/OrganicMaps.java @@ -1,28 +1,31 @@ package app.organicmaps.sdk; import android.content.Context; - +import android.content.SharedPreferences; import androidx.annotation.NonNull; import androidx.lifecycle.DefaultLifecycleObserver; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.ProcessLifecycleOwner; - import app.organicmaps.R; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.maplayer.isolines.IsolinesManager; -import app.organicmaps.maplayer.subway.SubwayManager; -import app.organicmaps.maplayer.traffic.TrafficManager; import app.organicmaps.routing.RoutingController; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.downloader.Android7RootCertificateWorkaround; +import app.organicmaps.sdk.editor.OsmOAuth; +import app.organicmaps.sdk.location.LocationHelper; +import app.organicmaps.sdk.location.SensorHelper; +import app.organicmaps.sdk.maplayer.isolines.IsolinesManager; +import app.organicmaps.sdk.maplayer.subway.SubwayManager; +import app.organicmaps.sdk.maplayer.traffic.TrafficManager; import app.organicmaps.sdk.search.SearchEngine; +import app.organicmaps.sdk.sound.TtsPlayer; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.SharedPropertiesUtils; +import app.organicmaps.sdk.util.StorageUtils; +import app.organicmaps.sdk.util.ThemeSwitcher; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.log.Logger; +import app.organicmaps.sdk.util.log.LogsManager; import app.organicmaps.settings.StoragePathManager; -import app.organicmaps.sound.TtsPlayer; -import app.organicmaps.util.Config; -import app.organicmaps.util.SharedPropertiesUtils; -import app.organicmaps.util.StorageUtils; -import app.organicmaps.util.ThemeSwitcher; -import app.organicmaps.util.UiUtils; -import app.organicmaps.util.log.Logger; - import java.io.IOException; public final class OrganicMaps implements DefaultLifecycleObserver @@ -32,12 +35,51 @@ public final class OrganicMaps implements DefaultLifecycleObserver @NonNull private final Context mContext; + @NonNull + private final SharedPreferences mPreferences; + + @NonNull + private final IsolinesManager mIsolinesManager; + @NonNull + private final SubwayManager mSubwayManager; + + @NonNull + private final LocationHelper mLocationHelper; + @NonNull + private final SensorHelper mSensorHelper; + private volatile boolean mFrameworkInitialized; private volatile boolean mPlatformInitialized; + @NonNull + public LocationHelper getLocationHelper() + { + return mLocationHelper; + } + + @NonNull + public SensorHelper getSensorHelper() + { + return mSensorHelper; + } + + @NonNull + public SubwayManager getSubwayManager() + { + return mSubwayManager; + } + + @NonNull + public IsolinesManager getIsolinesManager() + { + return mIsolinesManager; + } + public OrganicMaps(@NonNull Context context) { mContext = context.getApplicationContext(); + mPreferences = mContext.getSharedPreferences(context.getString(app.organicmaps.sdk.R.string.pref_file_name), + Context.MODE_PRIVATE); // Set configuration directory as early as possible. // Other methods may explicitly use Config, which requires settingsDir to be set. @@ -47,7 +89,17 @@ public final class OrganicMaps implements DefaultLifecycleObserver Logger.d(TAG, "Settings path = " + settingsPath); nativeSetSettingsDir(settingsPath); - Config.init(mContext); + Config.init(mContext, mPreferences); + OsmOAuth.init(mPreferences); + SharedPropertiesUtils.init(mPreferences); + LogsManager.INSTANCE.initFileLogging(mContext, mPreferences); + + Android7RootCertificateWorkaround.initializeIfNeeded(mContext); + + mSensorHelper = new SensorHelper(mContext); + mLocationHelper = new LocationHelper(mContext, mSensorHelper); + mIsolinesManager = new IsolinesManager(mContext); + mSubwayManager = new SubwayManager(mContext); } /** @@ -79,6 +131,12 @@ public final class OrganicMaps implements DefaultLifecycleObserver nativeOnTransit(false); } + @NonNull + public SharedPreferences getPreferences() + { + return mPreferences; + } + private void initNativePlatform() throws IOException { if (mPlatformInitialized) @@ -99,15 +157,10 @@ public final class OrganicMaps implements DefaultLifecycleObserver // external storage is damaged or not available (read-only). createPlatformDirectories(writablePath, privatePath, tempPath); - nativeInitPlatform(mContext, - apkPath, - writablePath, - privatePath, - tempPath, - app.organicmaps.BuildConfig.FLAVOR, - app.organicmaps.BuildConfig.BUILD_TYPE, UiUtils.isTablet(mContext)); + nativeInitPlatform(mContext, apkPath, writablePath, privatePath, tempPath, app.organicmaps.BuildConfig.FLAVOR, + app.organicmaps.BuildConfig.BUILD_TYPE, UiUtils.isTablet(mContext)); Config.setStoragePath(writablePath); - Config.setStatisticsEnabled(SharedPropertiesUtils.isStatisticsEnabled(mContext)); + Config.setStatisticsEnabled(SharedPropertiesUtils.isStatisticsEnabled()); mPlatformInitialized = true; Logger.i(TAG, "Platform initialized"); @@ -128,8 +181,8 @@ public final class OrganicMaps implements DefaultLifecycleObserver ThemeSwitcher.INSTANCE.restart(false); RoutingController.get().initialize(mContext); TrafficManager.INSTANCE.initialize(); - SubwayManager.from(mContext).initialize(); - IsolinesManager.from(mContext).initialize(); + mSubwayManager.initialize(); + mIsolinesManager.initialize(); ProcessLifecycleOwner.get().getLifecycle().addObserver(this); Logger.i(TAG, "Framework initialized"); @@ -137,8 +190,7 @@ public final class OrganicMaps implements DefaultLifecycleObserver return true; } - private void createPlatformDirectories(@NonNull String writablePath, - @NonNull String privatePath, + private void createPlatformDirectories(@NonNull String writablePath, @NonNull String privatePath, @NonNull String tempPath) throws IOException { SharedPropertiesUtils.emulateBadExternalStorage(mContext); @@ -162,8 +214,8 @@ public final class OrganicMaps implements DefaultLifecycleObserver private static native void nativeSetSettingsDir(String settingsPath); private static native void nativeInitPlatform(Context context, String apkPath, String writablePath, - String privatePath, String tmpPath, String flavorName, - String buildType, boolean isTablet); + String privatePath, String tmpPath, String flavorName, String buildType, + boolean isTablet); private static native void nativeInitFramework(@NonNull Runnable onComplete); diff --git a/android/app/src/main/java/app/organicmaps/sdk/PlacePageActivationListener.java b/android/app/src/main/java/app/organicmaps/sdk/PlacePageActivationListener.java index 0d7779d18..050cbbe75 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/PlacePageActivationListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/PlacePageActivationListener.java @@ -2,8 +2,7 @@ package app.organicmaps.sdk; import androidx.annotation.Keep; import androidx.annotation.NonNull; - -import app.organicmaps.widget.placepage.PlacePageData; +import app.organicmaps.sdk.widget.placepage.PlacePageData; public interface PlacePageActivationListener { diff --git a/android/app/src/main/java/app/organicmaps/sdk/Router.java b/android/app/src/main/java/app/organicmaps/sdk/Router.java index dcaf1d44f..229ffc3aa 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/Router.java +++ b/android/app/src/main/java/app/organicmaps/sdk/Router.java @@ -48,6 +48,5 @@ public enum Router private static native int nativeGetLastUsed(); - private static native int nativeGetBest(double srcLat, double srcLon, - double dstLat, double dstLon); + private static native int nativeGetBest(double srcLat, double srcLon, double dstLat, double dstLon); } diff --git a/android/app/src/main/java/app/organicmaps/api/ParsedRoutingData.java b/android/app/src/main/java/app/organicmaps/sdk/api/ParsedRoutingData.java similarity index 78% rename from android/app/src/main/java/app/organicmaps/api/ParsedRoutingData.java rename to android/app/src/main/java/app/organicmaps/sdk/api/ParsedRoutingData.java index 485ccdb02..5c398f5dc 100644 --- a/android/app/src/main/java/app/organicmaps/api/ParsedRoutingData.java +++ b/android/app/src/main/java/app/organicmaps/sdk/api/ParsedRoutingData.java @@ -1,7 +1,6 @@ -package app.organicmaps.api; +package app.organicmaps.sdk.api; import androidx.annotation.Keep; - import app.organicmaps.sdk.Router; /** @@ -15,7 +14,8 @@ public class ParsedRoutingData public final RoutePoint[] mPoints; public final Router mRouterType; - public ParsedRoutingData(RoutePoint[] points, int routerType) { + public ParsedRoutingData(RoutePoint[] points, int routerType) + { this.mPoints = points; this.mRouterType = Router.valueOf(routerType); } diff --git a/android/app/src/main/java/app/organicmaps/sdk/api/ParsedSearchRequest.java b/android/app/src/main/java/app/organicmaps/sdk/api/ParsedSearchRequest.java new file mode 100644 index 000000000..f40c58d68 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/api/ParsedSearchRequest.java @@ -0,0 +1,32 @@ +package app.organicmaps.sdk.api; + +import androidx.annotation.Keep; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +/** + * Represents url_scheme::SearchRequest from core. + */ +// Used by JNI. +@Keep +@SuppressWarnings("unused") +public final class ParsedSearchRequest +{ + @NonNull + public final String mQuery; + @Nullable + public final String mLocale; + public final double mLat; + public final double mLon; + public final boolean mIsSearchOnMap; + + public ParsedSearchRequest(@NonNull String query, @Nullable String locale, double lat, double lon, + boolean isSearchOnMap) + { + this.mQuery = query; + this.mLocale = locale; + this.mLat = lat; + this.mLon = lon; + this.mIsSearchOnMap = isSearchOnMap; + } +} diff --git a/android/app/src/main/java/app/organicmaps/api/RequestType.java b/android/app/src/main/java/app/organicmaps/sdk/api/RequestType.java similarity index 80% rename from android/app/src/main/java/app/organicmaps/api/RequestType.java rename to android/app/src/main/java/app/organicmaps/sdk/api/RequestType.java index a60f5dc55..65e4a9b7d 100644 --- a/android/app/src/main/java/app/organicmaps/api/RequestType.java +++ b/android/app/src/main/java/app/organicmaps/sdk/api/RequestType.java @@ -1,12 +1,12 @@ -package app.organicmaps.api; +package app.organicmaps.sdk.api; import androidx.annotation.IntDef; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.SOURCE) -@IntDef({RequestType.INCORRECT, RequestType.MAP, RequestType.ROUTE, RequestType.SEARCH, RequestType.CROSSHAIR, RequestType.OAUTH2, RequestType.MENU, RequestType.SETTINGS}) +@IntDef({RequestType.INCORRECT, RequestType.MAP, RequestType.ROUTE, RequestType.SEARCH, RequestType.CROSSHAIR, + RequestType.OAUTH2, RequestType.MENU, RequestType.SETTINGS}) public @interface RequestType { // Represents url_scheme::ParsedMapApi::UrlType from c++ part. diff --git a/android/app/src/main/java/app/organicmaps/api/RoutePoint.java b/android/app/src/main/java/app/organicmaps/sdk/api/RoutePoint.java similarity index 91% rename from android/app/src/main/java/app/organicmaps/api/RoutePoint.java rename to android/app/src/main/java/app/organicmaps/sdk/api/RoutePoint.java index 0c6f8876b..cdf4c30a0 100644 --- a/android/app/src/main/java/app/organicmaps/api/RoutePoint.java +++ b/android/app/src/main/java/app/organicmaps/sdk/api/RoutePoint.java @@ -1,4 +1,4 @@ -package app.organicmaps.api; +package app.organicmaps.sdk.api; import androidx.annotation.Keep; diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/Bookmark.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Bookmark.java similarity index 94% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/Bookmark.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Bookmark.java index ddb4b22f8..8b8a4705a 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/Bookmark.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Bookmark.java @@ -1,18 +1,16 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import android.annotation.SuppressLint; import android.os.Parcel; - import androidx.annotation.IntRange; import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.os.ParcelCompat; - -import app.organicmaps.Framework; +import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.routing.RoutePointInfo; import app.organicmaps.sdk.search.Popularity; -import app.organicmaps.util.Constants; +import app.organicmaps.sdk.util.Constants; // TODO consider refactoring to remove hack with MapObject unmarshalling itself and Bookmark at the same time. // Used by JNI. @@ -33,8 +31,8 @@ public class Bookmark extends MapObject @OpeningMode int openingMode, @NonNull Popularity popularity, @NonNull String description, @Nullable String[] rawTypes) { - super(featureId, BOOKMARK, title, secondaryTitle, subtitle, address, 0, 0, "", - routePointInfo, openingMode, popularity, description, RoadWarningMarkType.UNKNOWN.ordinal(), rawTypes); + super(featureId, BOOKMARK, title, secondaryTitle, subtitle, address, 0, 0, "", routePointInfo, openingMode, + popularity, description, RoadWarningMarkType.UNKNOWN.ordinal(), rawTypes); mCategoryId = categoryId; mBookmarkId = bookmarkId; diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkCategoriesDataProvider.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkCategoriesDataProvider.java similarity index 88% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkCategoriesDataProvider.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkCategoriesDataProvider.java index 3415aca60..39cdc220b 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkCategoriesDataProvider.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkCategoriesDataProvider.java @@ -1,7 +1,6 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import androidx.annotation.NonNull; - import java.util.List; public interface BookmarkCategoriesDataProvider diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkCategory.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkCategory.java similarity index 83% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkCategory.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkCategory.java index a4cca225d..d4fe68208 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkCategory.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkCategory.java @@ -1,14 +1,12 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.DrawableRes; import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.StringRes; - -import app.organicmaps.R; +import app.organicmaps.sdk.R; // Used by JNI. @Keep @@ -26,9 +24,8 @@ public class BookmarkCategory implements Parcelable private final int mBookmarksCount; private boolean mIsVisible; - public BookmarkCategory(long id, @NonNull String name, @NonNull String annotation, - @NonNull String description, int tracksCount, int bookmarksCount, - boolean isVisible) + public BookmarkCategory(long id, @NonNull String name, @NonNull String annotation, @NonNull String description, + int tracksCount, int bookmarksCount, boolean isVisible) { mId = id; mName = name; @@ -42,8 +39,10 @@ public class BookmarkCategory implements Parcelable @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; BookmarkCategory that = (BookmarkCategory) o; return mId == that.mId; } @@ -51,7 +50,7 @@ public class BookmarkCategory implements Parcelable @Override public int hashCode() { - return (int)(mId ^ (mId >>> 32)); + return (int) (mId ^ (mId >>> 32)); } public long getId() @@ -147,8 +146,7 @@ public class BookmarkCategory implements Parcelable this.mIsVisible = in.readByte() != 0; } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public BookmarkCategory createFromParcel(Parcel source) { @@ -164,10 +162,10 @@ public class BookmarkCategory implements Parcelable public enum AccessRules { - ACCESS_RULES_LOCAL(R.string.not_shared, R.drawable.ic_lock), - ACCESS_RULES_PUBLIC(R.string.public_access, R.drawable.ic_public_inline), - ACCESS_RULES_DIRECT_LINK(R.string.limited_access, R.drawable.ic_link_inline), - ACCESS_RULES_AUTHOR_ONLY(R.string.access_rules_author_only, R.drawable.ic_lock); + ACCESS_RULES_LOCAL(app.organicmaps.R.string.not_shared, R.drawable.ic_lock), + ACCESS_RULES_PUBLIC(app.organicmaps.R.string.public_access, R.drawable.ic_public_inline), + ACCESS_RULES_DIRECT_LINK(app.organicmaps.R.string.limited_access, R.drawable.ic_link_inline), + ACCESS_RULES_AUTHOR_ONLY(app.organicmaps.R.string.access_rules_author_only, R.drawable.ic_lock); private final int mResId; private final int mDrawableResId; diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkInfo.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkInfo.java similarity index 90% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkInfo.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkInfo.java index e5db93b57..4881efb54 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkInfo.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkInfo.java @@ -1,12 +1,11 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import androidx.annotation.IntRange; import androidx.annotation.Keep; import androidx.annotation.NonNull; - -import app.organicmaps.Framework; -import app.organicmaps.util.Distance; -import app.organicmaps.util.GeoUtils; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.util.Distance; +import app.organicmaps.sdk.util.GeoUtils; // Called from JNI. @Keep @@ -61,7 +60,10 @@ public class BookmarkInfo } @NonNull - public String getFeatureType() { return mFeatureType; } + public String getFeatureType() + { + return mFeatureType; + } @NonNull public String getName() diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkManager.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkManager.java similarity index 88% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkManager.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkManager.java index 29fc2e813..ae0fdc7fa 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkManager.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkManager.java @@ -1,10 +1,9 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.provider.OpenableColumns; - import androidx.annotation.IntDef; import androidx.annotation.IntRange; import androidx.annotation.Keep; @@ -12,13 +11,11 @@ import androidx.annotation.MainThread; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; -import app.organicmaps.Framework; -import app.organicmaps.bookmarks.DataChangedListener; -import app.organicmaps.util.KeyValue; -import app.organicmaps.util.StorageUtils; -import app.organicmaps.util.concurrency.UiThread; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.util.KeyValue; +import app.organicmaps.sdk.util.StorageUtils; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.sdk.util.log.Logger; import java.io.File; import java.io.IOException; import java.lang.annotation.Retention; @@ -28,13 +25,13 @@ import java.util.Collections; import java.util.List; @MainThread -public enum BookmarkManager -{ +public enum BookmarkManager { INSTANCE; @Retention(RetentionPolicy.SOURCE) - @IntDef({ SORT_BY_TYPE, SORT_BY_DISTANCE, SORT_BY_TIME, SORT_BY_NAME }) - public @interface SortingType {} + @IntDef({SORT_BY_TYPE, SORT_BY_DISTANCE, SORT_BY_TIME, SORT_BY_NAME}) + public @interface SortingType + {} public static final int SORT_BY_TYPE = 0; public static final int SORT_BY_DISTANCE = 1; @@ -51,8 +48,7 @@ public enum BookmarkManager private static final String TAG = BookmarkManager.class.getSimpleName(); @NonNull - private final BookmarkCategoriesDataProvider mCategoriesCoreDataProvider - = new CoreBookmarkCategoriesDataProvider(); + private final BookmarkCategoriesDataProvider mCategoriesCoreDataProvider = new CoreBookmarkCategoriesDataProvider(); @NonNull private BookmarkCategoriesDataProvider mCurrentDataProvider = mCategoriesCoreDataProvider; @@ -136,8 +132,7 @@ public enum BookmarkManager mSharingListeners.remove(listener); } - public void setElevationActivePointChangedListener( - @Nullable OnElevationActivePointChangedListener listener) + public void setElevationActivePointChangedListener(@Nullable OnElevationActivePointChangedListener listener) { if (listener != null) nativeSetElevationActiveChangedListener(); @@ -202,8 +197,7 @@ public enum BookmarkManager @Keep @SuppressWarnings("unused") @MainThread - public void onBookmarksFileLoaded(boolean success, @NonNull String fileName, - boolean isTemporaryFile) + public void onBookmarksFileLoaded(boolean success, @NonNull String fileName, boolean isTemporaryFile) { // Android could create temporary file with bookmarks in some cases (KML/KMZ file is a blob // in the intent, so we have to create a temporary file on the disk). Here we can delete it. @@ -313,9 +307,15 @@ public enum BookmarkManager return nativeGetTrackIdByPosition(catId, positionInCategory); } - public static void loadBookmarks() { nativeLoadBookmarks(); } + public static void loadBookmarks() + { + nativeLoadBookmarks(); + } - public void deleteCategory(long catId) { nativeDeleteCategory(catId); } + public void deleteCategory(long catId) + { + nativeDeleteCategory(catId); + } public void deleteTrack(long trackId) { @@ -327,14 +327,26 @@ public enum BookmarkManager nativeDeleteBookmark(bmkId); } - public long createCategory(@NonNull String name) { return nativeCreateCategory(name); } + public long createCategory(@NonNull String name) + { + return nativeCreateCategory(name); + } - public void showBookmarkOnMap(long bmkId) { nativeShowBookmarkOnMap(bmkId); } + public void showBookmarkOnMap(long bmkId) + { + nativeShowBookmarkOnMap(bmkId); + } - public void showBookmarkCategoryOnMap(long catId) { nativeShowBookmarkCategoryOnMap(catId); } + public void showBookmarkCategoryOnMap(long catId) + { + nativeShowBookmarkCategoryOnMap(catId); + } @Icon.PredefinedColor - public int getLastEditedColor() { return nativeGetLastEditedColor(); } + public int getLastEditedColor() + { + return nativeGetLastEditedColor(); + } @MainThread public void loadBookmarksFile(@NonNull String path, boolean isTemporaryFile) @@ -374,7 +386,7 @@ public enum BookmarkManager final String lowerCaseFilename = filename.toLowerCase(java.util.Locale.ROOT); // Check that filename contains bookmarks extension. - for (String ext: BOOKMARKS_EXTENSIONS) + for (String ext : BOOKMARKS_EXTENSIONS) { if (lowerCaseFilename.endsWith(ext)) return filename; @@ -435,7 +447,7 @@ public enum BookmarkManager UiThread.run(() -> loadBookmarksFile(tempFile.getAbsolutePath(), true)); return true; } - catch (IOException|SecurityException e) + catch (IOException | SecurityException e) { Logger.e(TAG, "Could not download bookmarks file from " + uri, e); UiThread.run(() -> { @@ -449,7 +461,7 @@ public enum BookmarkManager @WorkerThread public void importBookmarksFiles(@NonNull ContentResolver resolver, @NonNull List uris, @NonNull File tempDir) { - for (Uri uri: uris) + for (Uri uri : uris) importBookmarksFile(resolver, uri, tempDir); } @@ -500,7 +512,10 @@ public enum BookmarkManager return nativeIsUsedCategoryName(name); } - public void prepareForSearch(long catId) { nativePrepareForSearch(catId); } + public void prepareForSearch(long catId) + { + nativePrepareForSearch(catId); + } public boolean areAllCategoriesVisible() { @@ -537,17 +552,26 @@ public enum BookmarkManager nativeSetNotificationsEnabled(enabled); } - public boolean hasLastSortingType(long catId) { return nativeHasLastSortingType(catId); } + public boolean hasLastSortingType(long catId) + { + return nativeHasLastSortingType(catId); + } @SortingType - public int getLastSortingType(long catId) { return nativeGetLastSortingType(catId); } + public int getLastSortingType(long catId) + { + return nativeGetLastSortingType(catId); + } public void setLastSortingType(long catId, @SortingType int sortingType) { nativeSetLastSortingType(catId, sortingType); } - public void resetLastSortingType(long catId) { nativeResetLastSortingType(catId); } + public void resetLastSortingType(long catId) + { + nativeResetLastSortingType(catId); + } @NonNull @SortingType @@ -556,8 +580,7 @@ public enum BookmarkManager return nativeGetAvailableSortingTypes(catId, hasMyPosition); } - public void getSortedCategory(long catId, @SortingType int sortingType, - boolean hasMyPosition, double lat, double lon, + public void getSortedCategory(long catId, @SortingType int sortingType, boolean hasMyPosition, double lat, double lon, long timestamp) { nativeGetSortedCategory(catId, sortingType, hasMyPosition, lat, lon, timestamp); @@ -634,8 +657,7 @@ public enum BookmarkManager nativeSetBookmarkParams(bookmarkId, name, color, descr); } - public void setTrackParams(@IntRange(from = 0) long trackId, @NonNull String name, - int color, @NonNull String descr) + public void setTrackParams(@IntRange(from = 0) long trackId, @NonNull String name, int color, @NonNull String descr) { nativeSetTrackParams(trackId, name, color, descr); } @@ -645,15 +667,13 @@ public enum BookmarkManager nativeChangeTrackColor(trackId, color); } - public void changeBookmarkCategory(@IntRange(from = 0) long oldCatId, - @IntRange(from = 0) long newCatId, + public void changeBookmarkCategory(@IntRange(from = 0) long oldCatId, @IntRange(from = 0) long newCatId, @IntRange(from = 0) long bookmarkId) { nativeChangeBookmarkCategory(oldCatId, newCatId, bookmarkId); } - public void changeTrackCategory(@IntRange(from = 0) long oldCatId, - @IntRange(from = 0) long newCatId, + public void changeTrackCategory(@IntRange(from = 0) long oldCatId, @IntRange(from = 0) long newCatId, @IntRange(from = 0) long trackId) { nativeChangeTrackCategory(oldCatId, newCatId, trackId); @@ -665,8 +685,7 @@ public enum BookmarkManager return nativeGetBookmarkAddress(bookmarkId); } - public void notifyCategoryChanging(@NonNull BookmarkInfo bookmarkInfo, - @IntRange(from = 0) long catId) + public void notifyCategoryChanging(@NonNull BookmarkInfo bookmarkInfo, @IntRange(from = 0) long catId) { if (catId == bookmarkInfo.getCategoryId()) return; @@ -674,8 +693,7 @@ public enum BookmarkManager changeBookmarkCategory(bookmarkInfo.getCategoryId(), catId, bookmarkInfo.getBookmarkId()); } - public void notifyCategoryChanging(@NonNull Track track, - @IntRange(from = 0) long catId) + public void notifyCategoryChanging(@NonNull Track track, @IntRange(from = 0) long catId) { if (catId == track.getCategoryId()) return; @@ -691,38 +709,38 @@ public enum BookmarkManager changeBookmarkCategory(bookmark.getCategoryId(), catId, bookmark.getBookmarkId()); } - public void notifyParametersUpdating(@NonNull BookmarkInfo bookmarkInfo, @NonNull String name, - @Nullable Icon icon, @NonNull String description) + public void notifyParametersUpdating(@NonNull BookmarkInfo bookmarkInfo, @NonNull String name, @Nullable Icon icon, + @NonNull String description) { if (icon == null) icon = bookmarkInfo.getIcon(); - if (!name.equals(bookmarkInfo.getName()) || !icon.equals(bookmarkInfo.getIcon()) || - !description.equals(getBookmarkDescription(bookmarkInfo.getBookmarkId()))) + if (!name.equals(bookmarkInfo.getName()) || !icon.equals(bookmarkInfo.getIcon()) + || !description.equals(getBookmarkDescription(bookmarkInfo.getBookmarkId()))) { setBookmarkParams(bookmarkInfo.getBookmarkId(), name, icon.getColor(), description); } } - public void notifyParametersUpdating(@NonNull Bookmark bookmark, @NonNull String name, - @Nullable Icon icon, @NonNull String description) + public void notifyParametersUpdating(@NonNull Bookmark bookmark, @NonNull String name, @Nullable Icon icon, + @NonNull String description) { if (icon == null) icon = bookmark.getIcon(); - if (!name.equals(bookmark.getName()) || !icon.equals(bookmark.getIcon()) || - !description.equals(getBookmarkDescription(bookmark.getBookmarkId()))) + if (!name.equals(bookmark.getName()) || !icon.equals(bookmark.getIcon()) + || !description.equals(getBookmarkDescription(bookmark.getBookmarkId()))) { - setBookmarkParams(bookmark.getBookmarkId(), name, - icon != null ? icon.getColor() : getLastEditedColor(), description); + setBookmarkParams(bookmark.getBookmarkId(), name, icon != null ? icon.getColor() : getLastEditedColor(), + description); } } - public void notifyParametersUpdating(@NonNull Track track, @NonNull String name, - @Nullable int color, @NonNull String description) + public void notifyParametersUpdating(@NonNull Track track, @NonNull String name, @Nullable int color, + @NonNull String description) { - if (!name.equals(track.getName()) || !(color == track.getColor()) || - !description.equals(getTrackDescription(track.getTrackId()))) + if (!name.equals(track.getName()) || !(color == track.getColor()) + || !description.equals(getTrackDescription(track.getTrackId()))) { setTrackParams(track.getTrackId(), name, color, description); } @@ -730,7 +748,7 @@ public enum BookmarkManager public double getElevationCurPositionDistance(long trackId) { - return nativeGetElevationCurPositionDistance(trackId); + return nativeGetElevationCurPositionDistance(trackId); } public void setElevationActivePoint(long trackId, double distance) @@ -844,9 +862,8 @@ public enum BookmarkManager @SortingType private native int[] nativeGetAvailableSortingTypes(long catId, boolean hasMyPosition); - private native void nativeGetSortedCategory(long catId, @SortingType int sortingType, - boolean hasMyPosition, double lat, double lon, - long timestamp); + private native void nativeGetSortedCategory(long catId, @SortingType int sortingType, boolean hasMyPosition, + double lat, double lon, long timestamp); @NonNull private static native String nativeGetBookmarkName(@IntRange(from = 0) long bookmarkId); @@ -869,21 +886,15 @@ public enum BookmarkManager private static native double nativeGetBookmarkScale(@IntRange(from = 0) long bookmarkId); @NonNull - private static native String nativeEncode2Ge0Url(@IntRange(from = 0) long bookmarkId, - boolean addName); + private static native String nativeEncode2Ge0Url(@IntRange(from = 0) long bookmarkId, boolean addName); - private static native void nativeSetBookmarkParams(@IntRange(from = 0) long bookmarkId, - @NonNull String name, - @Icon.PredefinedColor int color, - @NonNull String descr); + private static native void nativeSetBookmarkParams(@IntRange(from = 0) long bookmarkId, @NonNull String name, + @Icon.PredefinedColor int color, @NonNull String descr); - private static native void nativeChangeTrackColor(@IntRange(from = 0) long trackId, - @Icon.PredefinedColor int color); + private static native void nativeChangeTrackColor(@IntRange(from = 0) long trackId, @Icon.PredefinedColor int color); - private static native void nativeSetTrackParams(@IntRange(from = 0) long trackId, - @NonNull String name, - @Icon.PredefinedColor int color, - @NonNull String descr); + private static native void nativeSetTrackParams(@IntRange(from = 0) long trackId, @NonNull String name, + @Icon.PredefinedColor int color, @NonNull String descr); private static native void nativeChangeBookmarkCategory(@IntRange(from = 0) long oldCatId, @IntRange(from = 0) long newCatId, diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkSharingResult.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkSharingResult.java similarity index 83% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkSharingResult.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkSharingResult.java index 9727fc4a5..7cdd2bd08 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/BookmarkSharingResult.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/BookmarkSharingResult.java @@ -1,9 +1,8 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import androidx.annotation.IntDef; import androidx.annotation.Keep; import androidx.annotation.NonNull; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -13,8 +12,9 @@ import java.lang.annotation.RetentionPolicy; public class BookmarkSharingResult { @Retention(RetentionPolicy.SOURCE) - @IntDef({ SUCCESS, EMPTY_CATEGORY, ARCHIVE_ERROR, FILE_ERROR }) - public @interface Code {} + @IntDef({SUCCESS, EMPTY_CATEGORY, ARCHIVE_ERROR, FILE_ERROR}) + public @interface Code + {} public static final int SUCCESS = 0; public static final int EMPTY_CATEGORY = 1; @@ -33,7 +33,8 @@ public class BookmarkSharingResult @SuppressWarnings("unused") private final String mMimeType; - public BookmarkSharingResult(long[] categoriesIds, @Code int code, @NonNull String sharingPath, @NonNull String mimeType, @NonNull String errorString) + public BookmarkSharingResult(long[] categoriesIds, @Code int code, @NonNull String sharingPath, + @NonNull String mimeType, @NonNull String errorString) { mCategoriesIds = categoriesIds; mCode = code; diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/CacheBookmarkCategoriesDataProvider.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/CacheBookmarkCategoriesDataProvider.java similarity index 83% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/CacheBookmarkCategoriesDataProvider.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/CacheBookmarkCategoriesDataProvider.java index dcf2d20bd..f95ccb37a 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/CacheBookmarkCategoriesDataProvider.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/CacheBookmarkCategoriesDataProvider.java @@ -1,7 +1,6 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import androidx.annotation.NonNull; - import java.util.Arrays; import java.util.List; @@ -11,11 +10,10 @@ class CacheBookmarkCategoriesDataProvider implements BookmarkCategoriesDataProvi @Override public BookmarkCategory getCategoryById(long categoryId) { - BookmarkManager.BookmarkCategoriesCache cache - = BookmarkManager.INSTANCE.getBookmarkCategoriesCache(); + BookmarkManager.BookmarkCategoriesCache cache = BookmarkManager.INSTANCE.getBookmarkCategoriesCache(); List categories = cache.getCategories(); - for (BookmarkCategory category: categories) + for (BookmarkCategory category : categories) if (category.getId() == categoryId) return category; diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/CategoryDataSource.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/CategoryDataSource.java similarity index 78% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/CategoryDataSource.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/CategoryDataSource.java index 48399dd34..6841637cd 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/CategoryDataSource.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/CategoryDataSource.java @@ -1,14 +1,11 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - -import app.organicmaps.content.DataSource; - +import app.organicmaps.sdk.content.DataSource; import java.util.List; -public class CategoryDataSource extends RecyclerView.AdapterDataObserver implements - DataSource +public class CategoryDataSource extends RecyclerView.AdapterDataObserver implements DataSource { @NonNull private BookmarkCategory mCategory; diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/CoreBookmarkCategoriesDataProvider.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/CoreBookmarkCategoriesDataProvider.java similarity index 95% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/CoreBookmarkCategoriesDataProvider.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/CoreBookmarkCategoriesDataProvider.java index 136769594..0c947d821 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/CoreBookmarkCategoriesDataProvider.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/CoreBookmarkCategoriesDataProvider.java @@ -1,7 +1,6 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import androidx.annotation.NonNull; - import java.util.Arrays; import java.util.List; diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/DataChangedListener.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/DataChangedListener.java similarity index 58% rename from android/app/src/main/java/app/organicmaps/bookmarks/DataChangedListener.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/DataChangedListener.java index 07b5c51cf..fc8afa41a 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/DataChangedListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/DataChangedListener.java @@ -1,4 +1,4 @@ -package app.organicmaps.bookmarks; +package app.organicmaps.sdk.bookmarks.data; public interface DataChangedListener { diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/DistanceAndAzimut.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/DistanceAndAzimut.java similarity index 83% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/DistanceAndAzimut.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/DistanceAndAzimut.java index a2abb600c..36a752d8f 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/DistanceAndAzimut.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/DistanceAndAzimut.java @@ -1,8 +1,7 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import androidx.annotation.Keep; - -import app.organicmaps.util.Distance; +import app.organicmaps.sdk.util.Distance; // Used by JNI. @Keep diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/ElevationInfo.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/ElevationInfo.java similarity index 92% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/ElevationInfo.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/ElevationInfo.java index 8693dfe92..c16b78df3 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/ElevationInfo.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/ElevationInfo.java @@ -1,13 +1,10 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.Keep; import androidx.annotation.NonNull; - -import app.organicmaps.widget.placepage.PlacePageData; - +import app.organicmaps.sdk.widget.placepage.PlacePageData; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -30,9 +27,8 @@ public class ElevationInfo implements PlacePageData private final int mDifficulty; private final long mDuration; - public ElevationInfo(long trackId, @NonNull String name, - @NonNull Point[] points, int ascent, int descent, int minAltitude, - int maxAltitude, int difficulty, long duration) + public ElevationInfo(long trackId, @NonNull String name, @NonNull Point[] points, int ascent, int descent, + int minAltitude, int maxAltitude, int difficulty, long duration) { mId = trackId; mName = name; @@ -155,8 +151,7 @@ public class ElevationInfo implements PlacePageData mAltitude = in.readInt(); } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public Point createFromParcel(Parcel in) { @@ -194,8 +189,7 @@ public class ElevationInfo implements PlacePageData } } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public ElevationInfo createFromParcel(Parcel in) { diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/Error.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Error.java similarity index 81% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/Error.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Error.java index b7c2aa9ab..9a3c8a381 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/Error.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Error.java @@ -1,10 +1,8 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.Nullable; - import java.net.HttpURLConnection; public class Error implements Parcelable @@ -46,14 +44,11 @@ public class Error implements Parcelable @Override public String toString() { - return "Error{" + - "mHttpCode=" + mHttpCode + - ", mMessage='" + mMessage + '\'' + - '}'; + return "Error{" + + "mHttpCode=" + mHttpCode + ", mMessage='" + mMessage + '\'' + '}'; } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public Error createFromParcel(Parcel in) { diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/FeatureId.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/FeatureId.java similarity index 80% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/FeatureId.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/FeatureId.java index cafa66568..bdb653908 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/FeatureId.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/FeatureId.java @@ -1,9 +1,8 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; - import androidx.annotation.Keep; import androidx.annotation.NonNull; @@ -13,8 +12,7 @@ import androidx.annotation.NonNull; /// Just creating in JNI and assigning .. public class FeatureId implements Parcelable { - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public FeatureId createFromParcel(Parcel in) { @@ -93,22 +91,25 @@ public class FeatureId implements Parcelable return mFeatureIndex; } - public boolean isRealId() { - return !TextUtils.isEmpty(mMwmName) && - mMwmVersion >= 0 && - mFeatureIndex > 0; + public boolean isRealId() + { + return !TextUtils.isEmpty(mMwmName) && mMwmVersion >= 0 && mFeatureIndex > 0; } @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; FeatureId featureId = (FeatureId) o; - if (mMwmVersion != featureId.mMwmVersion) return false; - if (mFeatureIndex != featureId.mFeatureIndex) return false; + if (mMwmVersion != featureId.mMwmVersion) + return false; + if (mFeatureIndex != featureId.mFeatureIndex) + return false; return mMwmName.equals(featureId.mMwmName); } @@ -124,10 +125,7 @@ public class FeatureId implements Parcelable @Override public String toString() { - return "FeatureId{" + - "mMwmName='" + mMwmName + '\'' + - ", mMwmVersion=" + mMwmVersion + - ", mFeatureIndex=" + mFeatureIndex + - '}'; + return "FeatureId{" + + "mMwmName='" + mMwmName + '\'' + ", mMwmVersion=" + mMwmVersion + ", mFeatureIndex=" + mFeatureIndex + '}'; } } diff --git a/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Icon.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Icon.java new file mode 100644 index 000000000..ffc3e9252 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Icon.java @@ -0,0 +1,184 @@ +package app.organicmaps.sdk.bookmarks.data; + +import android.os.Parcel; +import android.os.Parcelable; +import androidx.annotation.DrawableRes; +import androidx.annotation.IntDef; +import app.organicmaps.sdk.R; +import com.google.common.base.Objects; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +public class Icon implements Parcelable +{ + @Retention(RetentionPolicy.SOURCE) + @IntDef({PREDEFINED_COLOR_NONE, PREDEFINED_COLOR_RED, PREDEFINED_COLOR_BLUE, PREDEFINED_COLOR_PURPLE, + PREDEFINED_COLOR_YELLOW, PREDEFINED_COLOR_PINK, PREDEFINED_COLOR_BROWN, PREDEFINED_COLOR_GREEN, + PREDEFINED_COLOR_ORANGE, PREDEFINED_COLOR_DEEPPURPLE, PREDEFINED_COLOR_LIGHTBLUE, PREDEFINED_COLOR_CYAN, + PREDEFINED_COLOR_TEAL, PREDEFINED_COLOR_LIME, PREDEFINED_COLOR_DEEPORANGE, PREDEFINED_COLOR_GRAY, + PREDEFINED_COLOR_BLUEGRAY}) + @interface PredefinedColor + {} + + static final int PREDEFINED_COLOR_NONE = 0; + static final int PREDEFINED_COLOR_RED = 1; + static final int PREDEFINED_COLOR_BLUE = 2; + static final int PREDEFINED_COLOR_PURPLE = 3; + static final int PREDEFINED_COLOR_YELLOW = 4; + static final int PREDEFINED_COLOR_PINK = 5; + static final int PREDEFINED_COLOR_BROWN = 6; + static final int PREDEFINED_COLOR_GREEN = 7; + static final int PREDEFINED_COLOR_ORANGE = 8; + static final int PREDEFINED_COLOR_DEEPPURPLE = 9; + static final int PREDEFINED_COLOR_LIGHTBLUE = 10; + static final int PREDEFINED_COLOR_CYAN = 11; + static final int PREDEFINED_COLOR_TEAL = 12; + static final int PREDEFINED_COLOR_LIME = 13; + static final int PREDEFINED_COLOR_DEEPORANGE = 14; + static final int PREDEFINED_COLOR_GRAY = 15; + static final int PREDEFINED_COLOR_BLUEGRAY = 16; + + private static int shift(int v, int bitCount) + { + return v << bitCount; + } + private static int toARGB(int r, int g, int b) + { + return shift(255, 24) + shift(r, 16) + shift(g, 8) + b; + } + + /// @note Important! Should be synced with kml/types.hpp/PredefinedColor + /// @todo Values can be taken from Core. + private static final int[] ARGB_COLORS = {toARGB(229, 27, 35), // none + toARGB(229, 27, 35), // red + toARGB(0, 110, 199), // blue + toARGB(156, 39, 176), // purple + toARGB(255, 200, 0), // yellow + toARGB(255, 65, 130), // pink + toARGB(121, 85, 72), // brown + toARGB(56, 142, 60), // green + toARGB(255, 160, 0), // orange + toARGB(102, 57, 191), // deeppurple + toARGB(36, 156, 242), // lightblue + toARGB(20, 190, 205), // cyan + toARGB(0, 165, 140), // teal + toARGB(147, 191, 57), // lime + toARGB(240, 100, 50), // deeporange + toARGB(115, 115, 115), // gray + toARGB(89, 115, 128)}; // bluegray + + static final int BOOKMARK_ICON_TYPE_NONE = 0; + + /// @note Important! Should be synced with kml/types.hpp/BookmarkIcon + /// @todo Can make better: take name-by-type from Core and make a concat: "R.drawable.ic_bookmark_" + name. + // First icon should be "none" <-> BOOKMARK_ICON_TYPE_NONE. + @DrawableRes + private static final int[] TYPE_ICONS = { + R.drawable.ic_bookmark_none, R.drawable.ic_bookmark_hotel, R.drawable.ic_bookmark_animals, + R.drawable.ic_bookmark_buddhism, R.drawable.ic_bookmark_building, R.drawable.ic_bookmark_christianity, + R.drawable.ic_bookmark_entertainment, R.drawable.ic_bookmark_money, R.drawable.ic_bookmark_food, + R.drawable.ic_bookmark_gas, R.drawable.ic_bookmark_judaism, R.drawable.ic_bookmark_medicine, + R.drawable.ic_bookmark_mountain, R.drawable.ic_bookmark_museum, R.drawable.ic_bookmark_islam, + R.drawable.ic_bookmark_park, R.drawable.ic_bookmark_parking, R.drawable.ic_bookmark_shop, + R.drawable.ic_bookmark_sights, R.drawable.ic_bookmark_swim, R.drawable.ic_bookmark_water, + R.drawable.ic_bookmark_bar, R.drawable.ic_bookmark_transport, R.drawable.ic_bookmark_viewpoint, + R.drawable.ic_bookmark_sport, + R.drawable.ic_bookmark_none, // pub + R.drawable.ic_bookmark_none, // art + R.drawable.ic_bookmark_none, // bank + R.drawable.ic_bookmark_none, // cafe + R.drawable.ic_bookmark_none, // pharmacy + R.drawable.ic_bookmark_none, // stadium + R.drawable.ic_bookmark_none, // theatre + R.drawable.ic_bookmark_none, // information + R.drawable.ic_bookmark_none, // ChargingStation + R.drawable.ic_bookmark_none, // BicycleParking + R.drawable.ic_bookmark_none, // BicycleParkingCovered + R.drawable.ic_bookmark_none, // BicycleRental + R.drawable.ic_bookmark_none // FastFood + }; + + @PredefinedColor + private final int mColor; + private final int mType; + + public Icon(@PredefinedColor int color, int type) + { + mColor = color; + mType = type; + } + + @Override + public int describeContents() + { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) + { + dest.writeInt(mColor); + dest.writeInt(mType); + } + + private Icon(Parcel in) + { + mColor = in.readInt(); + mType = in.readInt(); + } + + @PredefinedColor + public int getColor() + { + return mColor; + } + + public int argb() + { + return ARGB_COLORS[mColor]; + } + + public static int getColorPosition(int color) + { + for (int index = 1; index < ARGB_COLORS.length; index++) + { + if (ARGB_COLORS[index] == color) + return index; + } + return -1; + } + + @DrawableRes + public int getResId() + { + return TYPE_ICONS[mType]; + } + + @Override + public boolean equals(Object o) + { + if (this == o) + return true; + if (o instanceof Icon comparedIcon) + return mColor == comparedIcon.mColor && mType == comparedIcon.mType; + return false; + } + + @Override + public int hashCode() + { + return Objects.hashCode(mColor, mType); + } + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator<>() { + public Icon createFromParcel(Parcel in) + { + return new Icon(in); + } + + public Icon[] newArray(int size) + { + return new Icon[size]; + } + }; +} diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/IconClickListener.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/IconClickListener.java similarity index 78% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/IconClickListener.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/IconClickListener.java index 0866fb872..2d7df8321 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/IconClickListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/IconClickListener.java @@ -1,4 +1,4 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import com.google.android.material.imageview.ShapeableImageView; diff --git a/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/KmlFileType.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/KmlFileType.java new file mode 100644 index 000000000..88d3d8746 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/KmlFileType.java @@ -0,0 +1,9 @@ +package app.organicmaps.sdk.bookmarks.data; + +// Need to be in sync with KmlFileType (map/bookmark_helpers.hpp) +public enum KmlFileType +{ + Text, + Binary, + Gpx +} diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/MapObject.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/MapObject.java similarity index 80% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/MapObject.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/MapObject.java index 8da50e0e7..70e12cef7 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/MapObject.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/MapObject.java @@ -1,19 +1,16 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import android.net.Uri; import android.os.Parcel; import android.text.TextUtils; - import androidx.annotation.IntDef; import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.os.ParcelCompat; - import app.organicmaps.sdk.routing.RoutePointInfo; import app.organicmaps.sdk.search.Popularity; -import app.organicmaps.widget.placepage.PlacePageData; - +import app.organicmaps.sdk.widget.placepage.PlacePageData; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -28,10 +25,9 @@ import java.util.Objects; public class MapObject implements PlacePageData { @Retention(RetentionPolicy.SOURCE) - @IntDef({ POI, API_POINT, BOOKMARK, MY_POSITION, SEARCH }) + @IntDef({POI, API_POINT, BOOKMARK, MY_POSITION, SEARCH}) public @interface MapObjectType - { - } + {} public static final int POI = 0; public static final int API_POINT = 1; @@ -40,8 +36,9 @@ public class MapObject implements PlacePageData public static final int SEARCH = 4; @Retention(RetentionPolicy.SOURCE) - @IntDef({ OPENING_MODE_PREVIEW, OPENING_MODE_PREVIEW_PLUS, OPENING_MODE_DETAILS, OPENING_MODE_FULL }) - public @interface OpeningMode {} + @IntDef({OPENING_MODE_PREVIEW, OPENING_MODE_PREVIEW_PLUS, OPENING_MODE_DETAILS, OPENING_MODE_FULL}) + public @interface OpeningMode + {} public static final int OPENING_MODE_PREVIEW = 0; public static final int OPENING_MODE_PREVIEW_PLUS = 1; @@ -69,8 +66,8 @@ public class MapObject implements PlacePageData private final RoutePointInfo mRoutePointInfo; @OpeningMode private final int mOpeningMode; -// @NonNull -// private final Popularity mPopularity; + // @NonNull + // private final Popularity mPopularity; @NonNull private final RoadWarningMarkType mRoadWarningMarkType; @NonNull @@ -79,22 +76,19 @@ public class MapObject implements PlacePageData private List mRawTypes; public MapObject(@NonNull FeatureId featureId, @MapObjectType int mapObjectType, String title, - @Nullable String secondaryTitle, String subtitle, String address, - double lat, double lon, String apiId, @Nullable RoutePointInfo routePointInfo, - @OpeningMode int openingMode, Popularity popularity, @NonNull String description, - int roadWarningType, @Nullable String[] rawTypes) + @Nullable String secondaryTitle, String subtitle, String address, double lat, double lon, + String apiId, @Nullable RoutePointInfo routePointInfo, @OpeningMode int openingMode, + Popularity popularity, @NonNull String description, int roadWarningType, @Nullable String[] rawTypes) { - this(featureId, mapObjectType, title, secondaryTitle, - subtitle, address, lat, lon, new Metadata(), apiId, - routePointInfo, openingMode, popularity, description, - roadWarningType, rawTypes); + this(featureId, mapObjectType, title, secondaryTitle, subtitle, address, lat, lon, new Metadata(), apiId, + routePointInfo, openingMode, popularity, description, roadWarningType, rawTypes); } - public MapObject(@NonNull FeatureId featureId, @MapObjectType int mapObjectType, - String title, @Nullable String secondaryTitle, String subtitle, String address, - double lat, double lon, Metadata metadata, String apiId, - @Nullable RoutePointInfo routePointInfo, @OpeningMode int openingMode, Popularity popularity, - @NonNull String description, int roadWarningType, @Nullable String[] rawTypes) + public MapObject(@NonNull FeatureId featureId, @MapObjectType int mapObjectType, String title, + @Nullable String secondaryTitle, String subtitle, String address, double lat, double lon, + Metadata metadata, String apiId, @Nullable RoutePointInfo routePointInfo, + @OpeningMode int openingMode, Popularity popularity, @NonNull String description, + int roadWarningType, @Nullable String[] rawTypes) { mFeatureId = featureId; mMapObjectType = mapObjectType; @@ -108,7 +102,7 @@ public class MapObject implements PlacePageData mApiId = apiId; mRoutePointInfo = routePointInfo; mOpeningMode = openingMode; - //mPopularity = popularity; + // mPopularity = popularity; mDescription = description; mRoadWarningMarkType = RoadWarningMarkType.values()[roadWarningType]; if (rawTypes != null) @@ -117,7 +111,8 @@ public class MapObject implements PlacePageData protected MapObject(@MapObjectType int type, Parcel source) { - this(Objects.requireNonNull(ParcelCompat.readParcelable(source, FeatureId.class.getClassLoader(), FeatureId.class)), // FeatureId + this(Objects.requireNonNull( + ParcelCompat.readParcelable(source, FeatureId.class.getClassLoader(), FeatureId.class)), // FeatureId type, // MapObjectType source.readString(), // Title source.readString(), // SecondaryTitle @@ -127,13 +122,14 @@ public class MapObject implements PlacePageData source.readDouble(), // Lon ParcelCompat.readParcelable(source, Metadata.class.getClassLoader(), Metadata.class), source.readString(), // ApiId; - ParcelCompat.readParcelable(source, RoutePointInfo.class.getClassLoader(), RoutePointInfo.class), // RoutePointInfo + ParcelCompat.readParcelable(source, RoutePointInfo.class.getClassLoader(), + RoutePointInfo.class), // RoutePointInfo source.readInt(), // mOpeningMode - Objects.requireNonNull(ParcelCompat.readParcelable(source, Popularity.class.getClassLoader(), Popularity.class)), - Objects.requireNonNull(source.readString()), - source.readInt(), + Objects.requireNonNull( + ParcelCompat.readParcelable(source, Popularity.class.getClassLoader(), Popularity.class)), + Objects.requireNonNull(source.readString()), source.readInt(), null // mRawTypes - ); + ); mRawTypes = readRawTypes(source); } @@ -142,11 +138,9 @@ public class MapObject implements PlacePageData public static MapObject createMapObject(@NonNull FeatureId featureId, @MapObjectType int mapObjectType, @NonNull String title, @NonNull String subtitle, double lat, double lon) { - return new MapObject(featureId, mapObjectType, title, - "", subtitle, "", lat, lon, null, - "", null, OPENING_MODE_PREVIEW, - Popularity.defaultInstance(), "", - RoadWarningMarkType.UNKNOWN.ordinal(), new String[0]); + return new MapObject(featureId, mapObjectType, title, "", subtitle, "", lat, lon, null, "", null, + OPENING_MODE_PREVIEW, Popularity.defaultInstance(), "", RoadWarningMarkType.UNKNOWN.ordinal(), + new String[0]); } @NonNull @@ -170,20 +164,20 @@ public class MapObject implements PlacePageData if (this == other) return true; - //noinspection SimplifiableIfStatement + // noinspection SimplifiableIfStatement if (getClass() != other.getClass()) return false; if (mFeatureId.isRealId() && other.getFeatureId().isRealId()) return mFeatureId.equals(other.getFeatureId()); - return Double.doubleToLongBits(mLon) == Double.doubleToLongBits(other.mLon) && - Double.doubleToLongBits(mLat) == Double.doubleToLongBits(other.mLat); + return Double.doubleToLongBits(mLon) == Double.doubleToLongBits(other.mLon) + && Double.doubleToLongBits(mLat) == Double.doubleToLongBits(other.mLat); } public static boolean same(@Nullable MapObject one, @Nullable MapObject another) { - //noinspection SimplifiableIfStatement + // noinspection SimplifiableIfStatement if (one == null && another == null) return true; @@ -341,7 +335,8 @@ public class MapObject implements PlacePageData private static MapObject readFromParcel(Parcel source) { - @MapObjectType int type = source.readInt(); + @MapObjectType + int type = source.readInt(); if (type == BOOKMARK) return new Bookmark(type, source); @@ -371,7 +366,7 @@ public class MapObject implements PlacePageData dest.writeString(mApiId); dest.writeParcelable(mRoutePointInfo, 0); dest.writeInt(mOpeningMode); - //dest.writeParcelable(mPopularity, 0); + // dest.writeParcelable(mPopularity, 0); dest.writeString(mDescription); dest.writeInt(getRoadWarningMarkType().ordinal()); // All collections are deserialized AFTER non-collection and primitive type objects, @@ -382,8 +377,10 @@ public class MapObject implements PlacePageData @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; MapObject mapObject = (MapObject) o; return mFeatureId.equals(mapObject.mFeatureId); @@ -395,8 +392,7 @@ public class MapObject implements PlacePageData return mFeatureId.hashCode(); } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public MapObject createFromParcel(Parcel source) { diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/Metadata.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Metadata.java similarity index 98% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/Metadata.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Metadata.java index d7f6aa7a6..6ba2c3354 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/Metadata.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Metadata.java @@ -1,12 +1,10 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.IntRange; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import java.util.HashMap; import java.util.Map; @@ -23,7 +21,7 @@ public class Metadata implements Parcelable FMD_STARS(5), FMD_OPERATOR(6), // Removed and is not used in the core. Use FMD_WEBSITE instead. - //FMD_URL(7), + // FMD_URL(7), FMD_WEBSITE(8), FMD_INTERNET(9), FMD_ELE(10), @@ -134,8 +132,7 @@ public class Metadata implements Parcelable return metadata; } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public Metadata createFromParcel(Parcel source) { diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/ParcelablePointD.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/ParcelablePointD.java similarity index 92% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/ParcelablePointD.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/ParcelablePointD.java index 36e778b54..82c5541be 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/ParcelablePointD.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/ParcelablePointD.java @@ -1,8 +1,7 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.Keep; // TODO consider removal and usage of platform PointF @@ -40,8 +39,7 @@ public class ParcelablePointD implements Parcelable this.y = y; } - public static final Parcelable.Creator CREATOR = new Parcelable.Creator<>() - { + public static final Parcelable.Creator CREATOR = new Parcelable.Creator<>() { public ParcelablePointD createFromParcel(Parcel in) { return new ParcelablePointD(in); @@ -52,5 +50,4 @@ public class ParcelablePointD implements Parcelable return new ParcelablePointD[size]; } }; - } diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/Result.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Result.java similarity index 79% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/Result.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Result.java index 97095c4b0..4ea21efa7 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/Result.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Result.java @@ -1,8 +1,7 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.Nullable; public class Result implements Parcelable @@ -40,14 +39,11 @@ public class Result implements Parcelable @Override public String toString() { - return "Result{" + - "mFilePath='" + mFilePath + '\'' + - ", mArchiveId='" + mArchiveId + '\'' + - '}'; + return "Result{" + + "mFilePath='" + mFilePath + '\'' + ", mArchiveId='" + mArchiveId + '\'' + '}'; } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public Result createFromParcel(Parcel in) { diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/RoadWarningMarkType.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/RoadWarningMarkType.java similarity index 62% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/RoadWarningMarkType.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/RoadWarningMarkType.java index 23164de84..3dd4d9ab4 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/RoadWarningMarkType.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/RoadWarningMarkType.java @@ -1,4 +1,4 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; public enum RoadWarningMarkType { diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/SortedBlock.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/SortedBlock.java similarity index 68% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/SortedBlock.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/SortedBlock.java index be1ed9e25..d056fa598 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/SortedBlock.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/SortedBlock.java @@ -1,8 +1,7 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import androidx.annotation.Keep; import androidx.annotation.NonNull; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -19,23 +18,34 @@ public class SortedBlock @NonNull private final List mTrackIds; - public SortedBlock(@NonNull String name, @NonNull Long[] bookmarkIds, - @NonNull Long[] trackIds) + public SortedBlock(@NonNull String name, @NonNull Long[] bookmarkIds, @NonNull Long[] trackIds) { mName = name; mBookmarkIds = new ArrayList<>(Arrays.asList(bookmarkIds)); mTrackIds = new ArrayList<>(Arrays.asList(trackIds)); } - public boolean isBookmarksBlock() { return !mBookmarkIds.isEmpty(); } + public boolean isBookmarksBlock() + { + return !mBookmarkIds.isEmpty(); + } @NonNull - public String getName() { return mName; } + public String getName() + { + return mName; + } @SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType") @NonNull - public List getBookmarkIds() { return mBookmarkIds; } + public List getBookmarkIds() + { + return mBookmarkIds; + } @SuppressWarnings("AssignmentOrReturnOfFieldWithMutableType") @NonNull - public List getTrackIds() { return mTrackIds; } + public List getTrackIds() + { + return mTrackIds; + } } diff --git a/android/app/src/main/java/app/organicmaps/bookmarks/data/Track.java b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Track.java similarity index 61% rename from android/app/src/main/java/app/organicmaps/bookmarks/data/Track.java rename to android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Track.java index 8646c700f..1e713ad20 100644 --- a/android/app/src/main/java/app/organicmaps/bookmarks/data/Track.java +++ b/android/app/src/main/java/app/organicmaps/sdk/bookmarks/data/Track.java @@ -1,8 +1,7 @@ -package app.organicmaps.bookmarks.data; +package app.organicmaps.sdk.bookmarks.data; import androidx.annotation.Keep; - -import app.organicmaps.util.Distance; +import app.organicmaps.sdk.util.Distance; // Called from JNI. @Keep @@ -24,15 +23,30 @@ public class Track mColor = color; } - public String getName() { return mName; } + public String getName() + { + return mName; + } - public Distance getLength() { return mLength;} + public Distance getLength() + { + return mLength; + } - public int getColor() { return mColor; } + public int getColor() + { + return mColor; + } - public long getTrackId() { return mTrackId; } + public long getTrackId() + { + return mTrackId; + } - public long getCategoryId() { return mCategoryId; } + public long getCategoryId() + { + return mCategoryId; + } public String getTrackDescription() { diff --git a/android/app/src/main/java/app/organicmaps/content/DataSource.java b/android/app/src/main/java/app/organicmaps/sdk/content/DataSource.java similarity index 76% rename from android/app/src/main/java/app/organicmaps/content/DataSource.java rename to android/app/src/main/java/app/organicmaps/sdk/content/DataSource.java index de246bb6b..1cfe996ea 100644 --- a/android/app/src/main/java/app/organicmaps/content/DataSource.java +++ b/android/app/src/main/java/app/organicmaps/sdk/content/DataSource.java @@ -1,4 +1,4 @@ -package app.organicmaps.content; +package app.organicmaps.sdk.content; import androidx.annotation.NonNull; diff --git a/android/app/src/main/java/app/organicmaps/display/DisplayChangedListener.java b/android/app/src/main/java/app/organicmaps/sdk/display/DisplayChangedListener.java similarity index 87% rename from android/app/src/main/java/app/organicmaps/display/DisplayChangedListener.java rename to android/app/src/main/java/app/organicmaps/sdk/display/DisplayChangedListener.java index ba0c656e9..391effdcc 100644 --- a/android/app/src/main/java/app/organicmaps/display/DisplayChangedListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/display/DisplayChangedListener.java @@ -1,4 +1,4 @@ -package app.organicmaps.display; +package app.organicmaps.sdk.display; import androidx.annotation.NonNull; diff --git a/android/app/src/main/java/app/organicmaps/display/DisplayManager.java b/android/app/src/main/java/app/organicmaps/sdk/display/DisplayManager.java similarity index 91% rename from android/app/src/main/java/app/organicmaps/display/DisplayManager.java rename to android/app/src/main/java/app/organicmaps/sdk/display/DisplayManager.java index 14e810e2b..8fff80abd 100644 --- a/android/app/src/main/java/app/organicmaps/display/DisplayManager.java +++ b/android/app/src/main/java/app/organicmaps/sdk/display/DisplayManager.java @@ -1,15 +1,10 @@ -package app.organicmaps.display; +package app.organicmaps.sdk.display; -import android.content.Context; import android.os.Handler; import android.os.Looper; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - -import app.organicmaps.MwmApplication; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.util.log.Logger; import java.util.Objects; public class DisplayManager @@ -42,13 +37,6 @@ public class DisplayManager @Nullable private DisplayHolder mCar; - @NonNull - public static DisplayManager from(@NonNull Context context) - { - final MwmApplication app = (MwmApplication) context.getApplicationContext(); - return app.getDisplayManager(); - } - public boolean isCarConnected() { return mCar != null; @@ -182,8 +170,7 @@ public class DisplayManager { mHandler.post(() -> firstTask.start(() -> { if (secondTask != null) - mHandler.post(() -> secondTask.start(() -> { - })); + mHandler.post(() -> secondTask.start(() -> {})); })); } } diff --git a/android/app/src/main/java/app/organicmaps/display/DisplayType.java b/android/app/src/main/java/app/organicmaps/sdk/display/DisplayType.java similarity index 54% rename from android/app/src/main/java/app/organicmaps/display/DisplayType.java rename to android/app/src/main/java/app/organicmaps/sdk/display/DisplayType.java index 478e90f25..36fb54463 100644 --- a/android/app/src/main/java/app/organicmaps/display/DisplayType.java +++ b/android/app/src/main/java/app/organicmaps/sdk/display/DisplayType.java @@ -1,4 +1,4 @@ -package app.organicmaps.display; +package app.organicmaps.sdk.display; public enum DisplayType { diff --git a/android/app/src/main/java/app/organicmaps/downloader/Android7RootCertificateWorkaround.java b/android/app/src/main/java/app/organicmaps/sdk/downloader/Android7RootCertificateWorkaround.java similarity index 88% rename from android/app/src/main/java/app/organicmaps/downloader/Android7RootCertificateWorkaround.java rename to android/app/src/main/java/app/organicmaps/sdk/downloader/Android7RootCertificateWorkaround.java index 277d5b622..0409a148a 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/Android7RootCertificateWorkaround.java +++ b/android/app/src/main/java/app/organicmaps/sdk/downloader/Android7RootCertificateWorkaround.java @@ -1,22 +1,19 @@ -package app.organicmaps.downloader; +package app.organicmaps.sdk.downloader; import android.annotation.TargetApi; import android.content.Context; - +import app.organicmaps.sdk.R; +import app.organicmaps.sdk.util.log.Logger; import java.io.InputStream; import java.net.HttpURLConnection; import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; - import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; -import app.organicmaps.R; -import app.organicmaps.util.log.Logger; - // Fix missing root certificates for HTTPS connections on Android 7 and below: // https://community.letsencrypt.org/t/letsencrypt-certificates-fails-on-android-phones-running-android-7-or-older/205686 @TargetApi(24) @@ -27,7 +24,8 @@ public class Android7RootCertificateWorkaround @TargetApi(24) private static SSLSocketFactory mSslSocketFactory; - public static void applyFixIfNeeded(HttpURLConnection connection) { + public static void applyFixIfNeeded(HttpURLConnection connection) + { // Deliberately not checking for null to have an exception from setSSLSocketFactory. if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.N && connection.getURL().getProtocol().equals("https")) @@ -39,8 +37,8 @@ public class Android7RootCertificateWorkaround if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.N) return; - final int[] certificates = new int[]{ - R.raw.isrgrootx1, R.raw.globalsignr4, R.raw.gtsrootr1, R.raw.gtsrootr2, R.raw.gtsrootr3, R.raw.gtsrootr4}; + final int[] certificates = new int[] {R.raw.isrgrootx1, R.raw.globalsignr4, R.raw.gtsrootr1, + R.raw.gtsrootr2, R.raw.gtsrootr3, R.raw.gtsrootr4}; try { diff --git a/android/app/src/main/java/app/organicmaps/downloader/ChunkTask.java b/android/app/src/main/java/app/organicmaps/sdk/downloader/ChunkTask.java similarity index 89% rename from android/app/src/main/java/app/organicmaps/downloader/ChunkTask.java rename to android/app/src/main/java/app/organicmaps/sdk/downloader/ChunkTask.java index 610f41400..353241ece 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/ChunkTask.java +++ b/android/app/src/main/java/app/organicmaps/sdk/downloader/ChunkTask.java @@ -1,15 +1,12 @@ -package app.organicmaps.downloader; +package app.organicmaps.sdk.downloader; import android.os.AsyncTask; import android.util.Base64; - import androidx.annotation.Keep; - -import app.organicmaps.util.Constants; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.Utils; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.util.Constants; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.Utils; +import app.organicmaps.sdk.util.log.Logger; import java.io.BufferedInputStream; import java.io.DataOutputStream; import java.io.IOException; @@ -48,8 +45,7 @@ class ChunkTask extends AsyncTask private static final Executor sExecutors = Executors.newFixedThreadPool(4); - public ChunkTask(long httpCallbackID, String url, long beg, long end, - long expectedFileSize, byte[] postBody) + public ChunkTask(long httpCallbackID, String url, long beg, long end, long expectedFileSize, byte[] postBody) { mHttpCallbackID = httpCallbackID; mUrl = url; @@ -60,7 +56,8 @@ class ChunkTask extends AsyncTask } @Override - protected void onPreExecute() {} + protected void onPreExecute() + {} @Override protected void onPostExecute(Integer httpOrErrorCode) @@ -106,7 +103,8 @@ class ChunkTask extends AsyncTask try { return Long.parseLong(contentRangeValue.substring(slashIndex + 1)); - } catch (final NumberFormatException ex) + } + catch (final NumberFormatException ex) { // Return -1 at the end of function } @@ -184,9 +182,8 @@ class ChunkTask extends AsyncTask if ((isChunk && err != HttpURLConnection.HTTP_PARTIAL) || (!isChunk && err != HttpURLConnection.HTTP_OK)) { // we've set error code so client should be notified about the error - Logger.w(TAG, "Error for " + urlConnection.getURL() + - ": Server replied with code " + err + - ", aborting download. " + Utils.mapPrettyPrint(requestParams)); + Logger.w(TAG, "Error for " + urlConnection.getURL() + ": Server replied with code " + err + + ", aborting download. " + Utils.mapPrettyPrint(requestParams)); return INCONSISTENT_FILE_SIZE; } @@ -201,24 +198,26 @@ class ChunkTask extends AsyncTask if (contentLength != mExpectedFileSize) { // we've set error code so client should be notified about the error - Logger.w(TAG, "Error for " + urlConnection.getURL() + - ": Invalid file size received (" + contentLength + ") while expecting " + mExpectedFileSize + - ". Aborting download."); + Logger.w(TAG, "Error for " + urlConnection.getURL() + ": Invalid file size received (" + contentLength + + ") while expecting " + mExpectedFileSize + ". Aborting download."); return INCONSISTENT_FILE_SIZE; } // @TODO Else display received web page to user - router is redirecting us to some page } return downloadFromStream(new BufferedInputStream(urlConnection.getInputStream(), 128 * Constants.KB)); - } catch (final MalformedURLException ex) + } + catch (final MalformedURLException ex) { Logger.e(TAG, "Invalid url: " + mUrl, ex); return INVALID_URL; - } catch (final IOException ex) + } + catch (final IOException ex) { Logger.d(TAG, "IOException in doInBackground for URL: " + mUrl, ex); return IO_EXCEPTION; - } finally + } + finally { if (urlConnection != null) urlConnection.disconnect(); @@ -238,7 +237,8 @@ class ChunkTask extends AsyncTask { ret = downloadFromStreamImpl(stream, size * Constants.KB); break; - } catch (final IOException ex) + } + catch (final IOException ex) { Logger.e(TAG, "IOException in downloadFromStream for buffer size: " + size, ex); } diff --git a/android/app/src/main/java/app/organicmaps/downloader/CountryItem.java b/android/app/src/main/java/app/organicmaps/sdk/downloader/CountryItem.java similarity index 58% rename from android/app/src/main/java/app/organicmaps/downloader/CountryItem.java rename to android/app/src/main/java/app/organicmaps/sdk/downloader/CountryItem.java index 8f0e27662..f2ba56517 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/CountryItem.java +++ b/android/app/src/main/java/app/organicmaps/sdk/downloader/CountryItem.java @@ -1,12 +1,10 @@ -package app.organicmaps.downloader; +package app.organicmaps.sdk.downloader; import android.text.TextUtils; - import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - -import app.organicmaps.util.StringUtils; +import app.organicmaps.sdk.util.StringUtils; /** * Class representing a single item in countries hierarchy. @@ -20,21 +18,21 @@ public final class CountryItem implements Comparable private static String sRootId; // Must correspond to ItemCategory in MapManager.cpp - static final int CATEGORY_NEAR_ME = 0; - static final int CATEGORY_DOWNLOADED = 1; - static final int CATEGORY_AVAILABLE = 2; - static final int CATEGORY__LAST = CATEGORY_AVAILABLE; + public static final int CATEGORY_NEAR_ME = 0; + public static final int CATEGORY_DOWNLOADED = 1; + public static final int CATEGORY_AVAILABLE = 2; + public static final int CATEGORY__LAST = CATEGORY_AVAILABLE; // Must correspond to NodeStatus in storage_defines.hpp public static final int STATUS_UNKNOWN = 0; - public static final int STATUS_PROGRESS = 1; // Downloading a new mwm or updating an old one. - public static final int STATUS_APPLYING = 2; // Applying downloaded diff for an old mwm. - public static final int STATUS_ENQUEUED = 3; // An mwm is waiting for downloading in the queue. - public static final int STATUS_FAILED = 4; // An error happened while downloading - public static final int STATUS_UPDATABLE = 5; // An update for a downloaded mwm is ready according to counties.txt. - public static final int STATUS_DONE = 6; // Downloaded mwm(s) is up to date. No need to update it. - public static final int STATUS_DOWNLOADABLE = 7; // An mwm can be downloaded but not downloaded yet. - public static final int STATUS_PARTLY = 8; // Leafs of group node has a mix of STATUS_DONE and STATUS_DOWNLOADABLE. + public static final int STATUS_PROGRESS = 1; // Downloading a new mwm or updating an old one. + public static final int STATUS_APPLYING = 2; // Applying downloaded diff for an old mwm. + public static final int STATUS_ENQUEUED = 3; // An mwm is waiting for downloading in the queue. + public static final int STATUS_FAILED = 4; // An error happened while downloading + public static final int STATUS_UPDATABLE = 5; // An update for a downloaded mwm is ready according to counties.txt. + public static final int STATUS_DONE = 6; // Downloaded mwm(s) is up to date. No need to update it. + public static final int STATUS_DOWNLOADABLE = 7; // An mwm can be downloaded but not downloaded yet. + public static final int STATUS_PARTLY = 8; // Leafs of group node has a mix of STATUS_DONE and STATUS_DOWNLOADABLE. // Must correspond to NodeErrorCode in storage_defines.hpp public static final int ERROR_NONE = 0; @@ -71,10 +69,10 @@ public final class CountryItem implements Comparable public long bytesToDownload; // Internal ID for grouping under headers in the list - int headerId; + public int headerId; // Internal field to store search result name @Nullable - String searchResultName; + public String searchResultName; private static void ensureRootIdKnown() { @@ -103,7 +101,7 @@ public final class CountryItem implements Comparable if (other == null || getClass() != other.getClass()) return false; - return id.equals(((CountryItem)other).id); + return id.equals(((CountryItem) other).id); } @Override @@ -153,23 +151,11 @@ public final class CountryItem implements Comparable @Override public String toString() { - return "{ id: \"" + id + - "\", directParentId: \"" + directParentId + - "\", topmostParentId: \"" + topmostParentId + - "\", category: \"" + category + - "\", name: \"" + name + - "\", directParentName: \"" + directParentName + - "\", topmostParentName: \"" + topmostParentName + - "\", present: " + present + - ", status: " + status + - ", errorCode: " + errorCode + - ", headerId: " + headerId + - ", size: " + size + - ", enqueuedSize: " + enqueuedSize + - ", totalSize: " + totalSize + - ", childCount: " + childCount + - ", totalChildCount: " + totalChildCount + - ", progress: " + StringUtils.formatUsingUsLocale("%.2f", progress) + - "% }"; + return "{ id: \"" + id + "\", directParentId: \"" + directParentId + "\", topmostParentId: \"" + topmostParentId + + "\", category: \"" + category + "\", name: \"" + name + "\", directParentName: \"" + directParentName + + "\", topmostParentName: \"" + topmostParentName + "\", present: " + present + ", status: " + status + + ", errorCode: " + errorCode + ", headerId: " + headerId + ", size: " + size + ", enqueuedSize: " + enqueuedSize + + ", totalSize: " + totalSize + ", childCount: " + childCount + ", totalChildCount: " + totalChildCount + + ", progress: " + StringUtils.formatUsingUsLocale("%.2f", progress) + "% }"; } } diff --git a/android/app/src/main/java/app/organicmaps/downloader/ExpandRetryConfirmationListener.java b/android/app/src/main/java/app/organicmaps/sdk/downloader/ExpandRetryConfirmationListener.java similarity index 50% rename from android/app/src/main/java/app/organicmaps/downloader/ExpandRetryConfirmationListener.java rename to android/app/src/main/java/app/organicmaps/sdk/downloader/ExpandRetryConfirmationListener.java index c931f04be..29e05694b 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/ExpandRetryConfirmationListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/downloader/ExpandRetryConfirmationListener.java @@ -1,15 +1,14 @@ -package app.organicmaps.downloader; +package app.organicmaps.sdk.downloader; import androidx.annotation.Nullable; - -import app.organicmaps.util.Utils; +import androidx.core.util.Consumer; class ExpandRetryConfirmationListener implements Runnable { @Nullable - private final Utils.Proc mDialogClickListener; + private final Consumer mDialogClickListener; - ExpandRetryConfirmationListener(@Nullable Utils.Proc dialogClickListener) + ExpandRetryConfirmationListener(@Nullable Consumer dialogClickListener) { mDialogClickListener = dialogClickListener; } @@ -19,6 +18,6 @@ class ExpandRetryConfirmationListener implements Runnable { if (mDialogClickListener == null) return; - mDialogClickListener.invoke(true); + mDialogClickListener.accept(true); } } diff --git a/android/app/src/main/java/app/organicmaps/downloader/MapManager.java b/android/app/src/main/java/app/organicmaps/sdk/downloader/MapManager.java similarity index 76% rename from android/app/src/main/java/app/organicmaps/downloader/MapManager.java rename to android/app/src/main/java/app/organicmaps/sdk/downloader/MapManager.java index 266baa9cd..d98778132 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/MapManager.java +++ b/android/app/src/main/java/app/organicmaps/sdk/downloader/MapManager.java @@ -1,21 +1,18 @@ -package app.organicmaps.downloader; +package app.organicmaps.sdk.downloader; import android.app.Activity; -import android.app.Application; import android.text.TextUtils; - import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.annotation.UiThread; import androidx.appcompat.app.AlertDialog; - +import androidx.core.util.Consumer; import app.organicmaps.R; -import app.organicmaps.util.ConnectionState; -import app.organicmaps.util.Utils; +import app.organicmaps.downloader.DownloaderService; +import app.organicmaps.sdk.util.ConnectionState; import com.google.android.material.dialog.MaterialAlertDialogBuilder; - import java.lang.ref.WeakReference; import java.util.List; @@ -24,7 +21,6 @@ public final class MapManager { // Used by JNI. @Keep - @SuppressWarnings("unused") public static class StorageCallbackData { public final String countryId; @@ -45,12 +41,10 @@ public final class MapManager { // Called from JNI. @Keep - @SuppressWarnings("unused") void onStatusChanged(List data); // Called from JNI. @Keep - @SuppressWarnings("unused") void onProgress(String countryId, long localSize, long remoteSize); } @@ -78,7 +72,7 @@ public final class MapManager } public static void showError(final Activity activity, final StorageCallbackData errorData, - @Nullable final Utils.Proc dialogClickListener) + @Nullable final Consumer dialogClickListener) { if (!nativeIsAutoretryFailed()) return; @@ -87,7 +81,7 @@ public final class MapManager } public static void showErrorDialog(final Activity activity, final StorageCallbackData errorData, - @Nullable final Utils.Proc dialogClickListener) + @Nullable final Consumer dialogClickListener) { if (sCurrentErrorDialog != null) { @@ -97,19 +91,21 @@ public final class MapManager } final AlertDialog dlg = new MaterialAlertDialogBuilder(activity, R.style.MwmTheme_AlertDialog) - .setTitle(R.string.country_status_download_failed) - .setMessage(getErrorCodeStrRes(errorData.errorCode)) - .setNegativeButton(R.string.cancel, (dialog, which) -> { - sCurrentErrorDialog = null; - if (dialogClickListener != null) - dialogClickListener.invoke(false); - }) - .setPositiveButton(R.string.downloader_retry, (dialog, which) -> { - Application app = activity.getApplication(); - ExpandRetryConfirmationListener listener - = new ExpandRetryConfirmationListener(dialogClickListener); - warn3gAndRetry(activity, errorData.countryId, listener); - }).create(); + .setTitle(R.string.country_status_download_failed) + .setMessage(getErrorCodeStrRes(errorData.errorCode)) + .setNegativeButton(R.string.cancel, + (dialog, which) -> { + sCurrentErrorDialog = null; + if (dialogClickListener != null) + dialogClickListener.accept(false); + }) + .setPositiveButton(R.string.downloader_retry, + (dialog, which) -> { + ExpandRetryConfirmationListener listener = + new ExpandRetryConfirmationListener(dialogClickListener); + warn3gAndRetry(activity, errorData.countryId, listener); + }) + .create(); dlg.setCanceledOnTouchOutside(false); dlg.show(); sCurrentErrorDialog = new WeakReference<>(dlg); @@ -172,26 +168,30 @@ public final class MapManager .setTitle(R.string.download_over_mobile_header) .setMessage(R.string.download_over_mobile_message) .setNegativeButton(R.string.cancel, null) - .setPositiveButton(R.string.ok, (dlg, which) -> { - nativeEnableDownloadOn3g(); - onAcceptListener.run(); - }).show(); + .setPositiveButton(R.string.ok, + (dlg, which) -> { + nativeEnableDownloadOn3g(); + onAcceptListener.run(); + }) + .show(); return true; } - static boolean warnOn3gUpdate(Activity activity, @Nullable String countryId, @NonNull final Runnable onAcceptListener) + public static boolean warnOn3gUpdate(Activity activity, @Nullable String countryId, + @NonNull final Runnable onAcceptListener) { - //noinspection SimplifiableIfStatement + // noinspection SimplifiableIfStatement if (TextUtils.isEmpty(countryId) || !notifyNoSpaceToUpdate(activity, countryId)) return warnOn3gInternal(activity, onAcceptListener); return true; } - static boolean warnOn3g(Activity activity, @Nullable String countryId, @NonNull final Runnable onAcceptListener) + public static boolean warnOn3g(Activity activity, @Nullable String countryId, + @NonNull final Runnable onAcceptListener) { - //noinspection SimplifiableIfStatement + // noinspection SimplifiableIfStatement if (TextUtils.isEmpty(countryId) || !notifyNoSpace(activity, countryId)) return warnOn3gInternal(activity, onAcceptListener); @@ -203,7 +203,8 @@ public final class MapManager return !notifyNoSpace(activity, size) && warnOn3gInternal(activity, onAcceptListener); } - public static boolean warn3gAndDownload(Activity activity, final String countryId, @Nullable final Runnable onAcceptListener) + public static boolean warn3gAndDownload(Activity activity, final String countryId, + @Nullable final Runnable onAcceptListener) { return warnOn3g(activity, countryId, () -> { if (onAcceptListener != null) @@ -212,7 +213,8 @@ public final class MapManager }); } - static boolean warn3gAndRetry(Activity activity, final String countryId, @Nullable final Runnable onAcceptListener) + public static boolean warn3gAndRetry(Activity activity, final String countryId, + @Nullable final Runnable onAcceptListener) { return warnOn3g(activity, countryId, () -> { if (onAcceptListener != null) @@ -224,7 +226,8 @@ public final class MapManager /** * Enqueues failed items under given {@code root} node in downloader. */ - public static void retryDownload(@NonNull String countryId) { + public static void retryDownload(@NonNull String countryId) + { DownloaderService.startForegroundService(); nativeRetry(countryId); } @@ -232,7 +235,8 @@ public final class MapManager /** * Enqueues given {@code root} node with its children in downloader. */ - public static void startUpdate(@NonNull String root) { + public static void startUpdate(@NonNull String root) + { DownloaderService.startForegroundService(); nativeUpdate(root); } @@ -240,7 +244,8 @@ public final class MapManager /** * Enqueues the given list of nodes and its children in downloader. */ - public static void startDownload(String... countries) { + public static void startDownload(String... countries) + { DownloaderService.startForegroundService(); for (var countryId : countries) { @@ -251,7 +256,8 @@ public final class MapManager /** * Enqueues given {@code root} node and its children in downloader. */ - public static void startDownload(@NonNull String countryId) { + public static void startDownload(@NonNull String countryId) + { DownloaderService.startForegroundService(); nativeDownload(countryId); } @@ -267,17 +273,20 @@ public final class MapManager public static native boolean nativeMoveFile(String oldFile, String newFile); /** - * Returns {@code true} if there is enough storage space to download specified amount of data. Or {@code false} otherwise. + * Returns {@code true} if there is enough storage space to download specified amount of data. Or {@code false} + * otherwise. */ public static native boolean nativeHasSpaceToDownloadAmount(long bytes); /** - * Returns {@code true} if there is enough storage space to download maps with specified {@code root}. Or {@code false} otherwise. + * Returns {@code true} if there is enough storage space to download maps with specified {@code root}. Or {@code + * false} otherwise. */ public static native boolean nativeHasSpaceToDownloadCountry(String root); /** - * Returns {@code true} if there is enough storage space to update maps with specified {@code root}. Or {@code false} otherwise. + * Returns {@code true} if there is enough storage space to update maps with specified {@code root}. Or {@code false} + * otherwise. */ public static native boolean nativeHasSpaceToUpdate(String root); @@ -295,7 +304,8 @@ public final class MapManager * Retrieves list of country items with its status info. * if {@code root} is {@code null}, list of downloaded countries is returned. */ - public static native void nativeListItems(@Nullable String root, double lat, double lon, boolean hasLocation, boolean myMapsMode, List result); + public static native void nativeListItems(@Nullable String root, double lat, double lon, boolean hasLocation, + boolean myMapsMode, List result); /** * Sets following attributes of the given {@code item}: @@ -372,7 +382,8 @@ public final class MapManager public static native void nativeDelete(String root); /** - * Registers {@code callback} of storage status changed. Returns slot ID which should be used to unsubscribe in {@link #nativeUnsubscribe(int)}. + * Registers {@code callback} of storage status changed. Returns slot ID which should be used to unsubscribe in {@link + * #nativeUnsubscribe(int)}. */ public static native int nativeSubscribe(StorageCallback callback); @@ -398,8 +409,9 @@ public final class MapManager public static native boolean nativeHasUnsavedEditorChanges(String root); /** - * Fills given {@code result} list with intermediate nodes from the root node (including) to the given {@code root} (excluding). - * For instance, for {@code root == "Florida"} the resulting list is filled with values: {@code { "United States of America", "Countries" }}. + * Fills given {@code result} list with intermediate nodes from the root node (including) to the given {@code root} + * (excluding). For instance, for {@code root == "Florida"} the resulting list is filled with values: {@code { "United + * States of America", "Countries" }}. */ public static native void nativeGetPathTo(String root, List result); diff --git a/android/app/src/main/java/app/organicmaps/downloader/UpdateInfo.java b/android/app/src/main/java/app/organicmaps/sdk/downloader/UpdateInfo.java similarity index 84% rename from android/app/src/main/java/app/organicmaps/downloader/UpdateInfo.java rename to android/app/src/main/java/app/organicmaps/sdk/downloader/UpdateInfo.java index f52d3249b..5ced20b0e 100644 --- a/android/app/src/main/java/app/organicmaps/downloader/UpdateInfo.java +++ b/android/app/src/main/java/app/organicmaps/sdk/downloader/UpdateInfo.java @@ -1,4 +1,4 @@ -package app.organicmaps.downloader; +package app.organicmaps.sdk.downloader; import androidx.annotation.Keep; @@ -7,7 +7,6 @@ import androidx.annotation.Keep; */ // Called from JNI. @Keep -@SuppressWarnings("unused") public final class UpdateInfo { public final int filesCount; diff --git a/android/app/src/main/java/app/organicmaps/editor/Editor.java b/android/app/src/main/java/app/organicmaps/sdk/editor/Editor.java similarity index 87% rename from android/app/src/main/java/app/organicmaps/editor/Editor.java rename to android/app/src/main/java/app/organicmaps/sdk/editor/Editor.java index fe84ed490..7bc120164 100644 --- a/android/app/src/main/java/app/organicmaps/editor/Editor.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/Editor.java @@ -1,25 +1,20 @@ -package app.organicmaps.editor; - -import android.content.Context; +package app.organicmaps.sdk.editor; import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Size; import androidx.annotation.WorkerThread; - import app.organicmaps.BuildConfig; -import app.organicmaps.Framework; -import app.organicmaps.bookmarks.data.Metadata; -import app.organicmaps.editor.data.FeatureCategory; -import app.organicmaps.editor.data.Language; -import app.organicmaps.editor.data.LocalizedName; -import app.organicmaps.editor.data.LocalizedStreet; -import app.organicmaps.editor.data.NamesDataSource; - +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.bookmarks.data.Metadata; +import app.organicmaps.sdk.editor.data.FeatureCategory; +import app.organicmaps.sdk.editor.data.Language; +import app.organicmaps.sdk.editor.data.LocalizedName; +import app.organicmaps.sdk.editor.data.LocalizedStreet; +import app.organicmaps.sdk.editor.data.NamesDataSource; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; - /** * Edits active(selected on the map) feature, which is represented as osm::EditableFeature in the core. */ @@ -28,7 +23,8 @@ public final class Editor // Should correspond to core osm::FeatureStatus. @Retention(RetentionPolicy.SOURCE) @IntDef({UNTOUCHED, DELETED, OBSOLETE, MODIFIED, CREATED}) - public @interface FeatureStatus {} + public @interface FeatureStatus + {} public static final int UNTOUCHED = 0; public static final int DELETED = 1; @@ -46,11 +42,10 @@ public final class Editor private static native void nativeInit(); @WorkerThread - public static void uploadChanges(@NonNull Context context) + public static void uploadChanges() { - if (nativeHasSomethingToUpload() && OsmOAuth.isAuthorized(context)) - nativeUploadChanges(OsmOAuth.getAuthToken(context), - BuildConfig.VERSION_NAME, BuildConfig.APPLICATION_ID); + if (nativeHasSomethingToUpload() && OsmOAuth.isAuthorized()) + nativeUploadChanges(OsmOAuth.getAuthToken(), BuildConfig.VERSION_NAME, BuildConfig.APPLICATION_ID); } public static native boolean nativeShouldShowEditPlace(); @@ -127,7 +122,6 @@ public final class Editor } public static native boolean nativeIsNameValid(String name); - public static native boolean nativeHasSomethingToUpload(); @WorkerThread private static native void nativeUploadChanges(String oauthToken, String appVersion, String appId); @@ -152,8 +146,7 @@ public final class Editor @NonNull public static native String[] nativeGetAllCreatableFeatureTypes(@NonNull String lang); @NonNull - public static native String[] nativeSearchCreatableFeatureTypes(@NonNull String query, - @NonNull String lang); + public static native String[] nativeSearchCreatableFeatureTypes(@NonNull String query, @NonNull String lang); /** * Creates new object on the map. Places it in the center of current viewport. @@ -180,7 +173,7 @@ public final class Editor public static native String[] nativeGetSelectedCuisines(); public static native String[] nativeFilterCuisinesKeys(String substr); public static native String[] nativeTranslateCuisines(String[] keys); - public static native void nativeSetSelectedCuisines(String [] keys); + public static native void nativeSetSelectedCuisines(String[] keys); /** * @return properly formatted and appended cuisines string to display in UI. */ diff --git a/android/app/src/main/java/app/organicmaps/editor/OpeningHours.java b/android/app/src/main/java/app/organicmaps/sdk/editor/OpeningHours.java similarity index 76% rename from android/app/src/main/java/app/organicmaps/editor/OpeningHours.java rename to android/app/src/main/java/app/organicmaps/sdk/editor/OpeningHours.java index b196fae91..511839c48 100644 --- a/android/app/src/main/java/app/organicmaps/editor/OpeningHours.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/OpeningHours.java @@ -1,11 +1,11 @@ -package app.organicmaps.editor; +package app.organicmaps.sdk.editor; import androidx.annotation.IntRange; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - -import app.organicmaps.editor.data.Timespan; -import app.organicmaps.editor.data.Timetable; +import app.organicmaps.editor.OhState; +import app.organicmaps.sdk.editor.data.Timespan; +import app.organicmaps.sdk.editor.data.Timetable; public final class OpeningHours { @@ -24,20 +24,16 @@ public final class OpeningHours @NonNull public static native Timetable nativeGetComplementTimetable(Timetable[] timetableSet); - @NonNull - public static native Timetable[] nativeAddTimetable(Timetable[] timetableSet); - - @NonNull - public static native Timetable[] nativeRemoveTimetable(Timetable[] timetableSet, int timetableIndex); - @NonNull public static native Timetable nativeSetIsFullday(Timetable timetable, boolean isFullday); @NonNull - public static native Timetable[] nativeAddWorkingDay(Timetable[] timetables, int timetableIndex, @IntRange(from = 1, to = 7) int day); + public static native Timetable[] nativeAddWorkingDay(Timetable[] timetables, int timetableIndex, + @IntRange(from = 1, to = 7) int day); @NonNull - public static native Timetable[] nativeRemoveWorkingDay(Timetable[] timetables, int timetableIndex, @IntRange(from = 1, to = 7) int day); + public static native Timetable[] nativeRemoveWorkingDay(Timetable[] timetables, int timetableIndex, + @IntRange(from = 1, to = 7) int day); @NonNull public static native Timetable nativeSetOpeningTime(Timetable timetable, Timespan openingTime); diff --git a/android/app/src/main/java/app/organicmaps/sdk/editor/OsmOAuth.java b/android/app/src/main/java/app/organicmaps/sdk/editor/OsmOAuth.java new file mode 100644 index 000000000..e0ea2f329 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/OsmOAuth.java @@ -0,0 +1,164 @@ +package app.organicmaps.sdk.editor; + +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.Size; +import androidx.annotation.WorkerThread; +import androidx.fragment.app.FragmentManager; +import app.organicmaps.sdk.util.NetworkPolicy; + +public final class OsmOAuth +{ + private OsmOAuth() {} + + public enum AuthType + { + OSM("OSM"), + GOOGLE("Google"); + + public final String name; + + AuthType(String name) + { + this.name = name; + } + } + + @SuppressWarnings("NotNullFieldNotInitialized") + @NonNull + private static SharedPreferences mPrefs; + + private static final String PREF_OSM_TOKEN = "OsmToken"; // Unused after migration from OAuth1 to OAuth2 + private static final String PREF_OSM_SECRET = "OsmSecret"; // Unused after migration from OAuth1 to OAuth2 + private static final String PREF_OSM_USERNAME = "OsmUsername"; + private static final String PREF_OSM_CHANGESETS_COUNT = "OsmChangesetsCount"; + private static final String PREF_OSM_OAUTH2_TOKEN = "OsmOAuth2Token"; + + public static final String URL_PARAM_VERIFIER = "oauth_verifier"; + + public static void init(@NonNull SharedPreferences prefs) + { + mPrefs = prefs; + } + + public static boolean isAuthorized() + { + return mPrefs.contains(PREF_OSM_OAUTH2_TOKEN); + } + + public static boolean containsOAuth1Credentials() + { + return mPrefs.contains(PREF_OSM_TOKEN) && mPrefs.contains(PREF_OSM_SECRET); + } + + public static void clearOAuth1Credentials() + { + mPrefs.edit().remove(PREF_OSM_TOKEN).remove(PREF_OSM_SECRET).apply(); + } + + public static String getAuthToken() + { + return mPrefs.getString(PREF_OSM_OAUTH2_TOKEN, ""); + } + + public static String getUsername() + { + return mPrefs.getString(PREF_OSM_USERNAME, ""); + } + + public static Bitmap getProfilePicture() + { + // TODO(HB): load and store image in cache here + return null; + } + + public static void setAuthorization(String oauthToken, String username) + { + mPrefs.edit().putString(PREF_OSM_OAUTH2_TOKEN, oauthToken).putString(PREF_OSM_USERNAME, username).apply(); + } + + public static void clearAuthorization() + { + mPrefs.edit() + .remove(PREF_OSM_TOKEN) + .remove(PREF_OSM_SECRET) + .remove(PREF_OSM_USERNAME) + .remove(PREF_OSM_OAUTH2_TOKEN) + .apply(); + } + + @NonNull + public static String getHistoryUrl() + { + return nativeGetHistoryUrl(getUsername()); + } + + @NonNull + public static String getNotesUrl() + { + return nativeGetNotesUrl(getUsername()); + } + + /* + Returns 5 strings: ServerURL, ClientId, ClientSecret, Scope, RedirectUri + */ + @NonNull + public static native String nativeGetOAuth2Url(); + + /** + * @return string with OAuth2 token + */ + @WorkerThread + @Size(2) + @Nullable + public static native String nativeAuthWithPassword(String login, String password); + + /** + * @return string with OAuth2 token + */ + @WorkerThread + @Nullable + public static native String nativeAuthWithOAuth2Code(String oauth2code); + + @WorkerThread + @Nullable + public static native String nativeGetOsmUsername(String oauthToken); + + @WorkerThread + @Nullable + public static native String nativeGetOsmProfilePictureUrl(String oauthToken); + + @WorkerThread + @NonNull + public static native String nativeGetHistoryUrl(String user); + + @WorkerThread + @NonNull + public static native String nativeGetNotesUrl(String user); + + /** + * @return < 0 if failed to get changesets count. + */ + @WorkerThread + private static native int nativeGetOsmChangesetsCount(String oauthToken); + + @WorkerThread + public static int getOsmChangesetsCount(@NonNull FragmentManager fm) + { + final int[] editsCount = {-1}; + NetworkPolicy.checkNetworkPolicy(fm, policy -> { + if (!policy.canUseNetwork()) + return; + + final String token = getAuthToken(); + editsCount[0] = OsmOAuth.nativeGetOsmChangesetsCount(token); + }); + if (editsCount[0] < 0) + return mPrefs.getInt(PREF_OSM_CHANGESETS_COUNT, 0); + + mPrefs.edit().putInt(PREF_OSM_CHANGESETS_COUNT, editsCount[0]).apply(); + return editsCount[0]; + } +} diff --git a/android/app/src/main/java/app/organicmaps/editor/data/FeatureCategory.java b/android/app/src/main/java/app/organicmaps/sdk/editor/data/FeatureCategory.java similarity index 95% rename from android/app/src/main/java/app/organicmaps/editor/data/FeatureCategory.java rename to android/app/src/main/java/app/organicmaps/sdk/editor/data/FeatureCategory.java index cb845e6ab..9f6dfb624 100644 --- a/android/app/src/main/java/app/organicmaps/editor/data/FeatureCategory.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/data/FeatureCategory.java @@ -1,8 +1,7 @@ -package app.organicmaps.editor.data; +package app.organicmaps.sdk.editor.data; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.NonNull; public class FeatureCategory implements Parcelable @@ -50,8 +49,7 @@ public class FeatureCategory implements Parcelable dest.writeString(mLocalizedTypeName); } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public FeatureCategory createFromParcel(Parcel source) { diff --git a/android/app/src/main/java/app/organicmaps/editor/data/HoursMinutes.java b/android/app/src/main/java/app/organicmaps/sdk/editor/data/HoursMinutes.java similarity index 87% rename from android/app/src/main/java/app/organicmaps/editor/data/HoursMinutes.java rename to android/app/src/main/java/app/organicmaps/sdk/editor/data/HoursMinutes.java index ca5a35a29..56e2b75b3 100644 --- a/android/app/src/main/java/app/organicmaps/editor/data/HoursMinutes.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/data/HoursMinutes.java @@ -1,14 +1,11 @@ -package app.organicmaps.editor.data; +package app.organicmaps.sdk.editor.data; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.IntRange; import androidx.annotation.Keep; import androidx.annotation.NonNull; - -import app.organicmaps.util.StringUtils; - +import app.organicmaps.sdk.util.StringUtils; import java.time.LocalTime; import java.time.format.DateTimeFormatter; @@ -23,8 +20,8 @@ public class HoursMinutes implements Parcelable // 24 hours or even 25 and higher values are used in OSM data and passed here from JNI calls. // Example: 18:00-24:00 - public HoursMinutes(@IntRange(from = 0, to = 24) long hours, - @IntRange(from = 0, to = 59) long minutes, boolean is24HourFormat) + public HoursMinutes(@IntRange(from = 0, to = 24) long hours, @IntRange(from = 0, to = 59) long minutes, + boolean is24HourFormat) { this.hours = hours; this.minutes = minutes; @@ -64,8 +61,7 @@ public class HoursMinutes implements Parcelable dest.writeByte((byte) (m24HourFormat ? 1 : 0)); } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public HoursMinutes createFromParcel(Parcel in) { diff --git a/android/app/src/main/java/app/organicmaps/editor/data/Language.java b/android/app/src/main/java/app/organicmaps/sdk/editor/data/Language.java similarity index 92% rename from android/app/src/main/java/app/organicmaps/editor/data/Language.java rename to android/app/src/main/java/app/organicmaps/sdk/editor/data/Language.java index c3a42004e..fd07444f6 100644 --- a/android/app/src/main/java/app/organicmaps/editor/data/Language.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/data/Language.java @@ -1,4 +1,4 @@ -package app.organicmaps.editor.data; +package app.organicmaps.sdk.editor.data; import androidx.annotation.Keep; import androidx.annotation.NonNull; diff --git a/android/app/src/main/java/app/organicmaps/editor/data/LocalizedName.java b/android/app/src/main/java/app/organicmaps/sdk/editor/data/LocalizedName.java similarity index 72% rename from android/app/src/main/java/app/organicmaps/editor/data/LocalizedName.java rename to android/app/src/main/java/app/organicmaps/sdk/editor/data/LocalizedName.java index 764301721..ac260fcda 100644 --- a/android/app/src/main/java/app/organicmaps/editor/data/LocalizedName.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/data/LocalizedName.java @@ -1,4 +1,4 @@ -package app.organicmaps.editor.data; +package app.organicmaps.sdk.editor.data; import androidx.annotation.Keep; import androidx.annotation.NonNull; @@ -9,9 +9,12 @@ import androidx.annotation.NonNull; public class LocalizedName { public int code; - @NonNull public String name; - @NonNull public String lang; - @NonNull public String langName; + @NonNull + public String name; + @NonNull + public String lang; + @NonNull + public String langName; public LocalizedName(int code, @NonNull String name, @NonNull String lang, @NonNull String langName) { diff --git a/android/app/src/main/java/app/organicmaps/editor/data/LocalizedStreet.java b/android/app/src/main/java/app/organicmaps/sdk/editor/data/LocalizedStreet.java similarity index 90% rename from android/app/src/main/java/app/organicmaps/editor/data/LocalizedStreet.java rename to android/app/src/main/java/app/organicmaps/sdk/editor/data/LocalizedStreet.java index 6be310969..31a23a412 100644 --- a/android/app/src/main/java/app/organicmaps/editor/data/LocalizedStreet.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/data/LocalizedStreet.java @@ -1,4 +1,4 @@ -package app.organicmaps.editor.data; +package app.organicmaps.sdk.editor.data; import androidx.annotation.Keep; import androidx.annotation.NonNull; diff --git a/android/app/src/main/java/app/organicmaps/editor/data/NamesDataSource.java b/android/app/src/main/java/app/organicmaps/sdk/editor/data/NamesDataSource.java similarity index 94% rename from android/app/src/main/java/app/organicmaps/editor/data/NamesDataSource.java rename to android/app/src/main/java/app/organicmaps/sdk/editor/data/NamesDataSource.java index afc6f9a90..c1676112d 100644 --- a/android/app/src/main/java/app/organicmaps/editor/data/NamesDataSource.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/data/NamesDataSource.java @@ -1,4 +1,4 @@ -package app.organicmaps.editor.data; +package app.organicmaps.sdk.editor.data; import androidx.annotation.Keep; diff --git a/android/app/src/main/java/app/organicmaps/editor/data/Timespan.java b/android/app/src/main/java/app/organicmaps/sdk/editor/data/Timespan.java similarity index 91% rename from android/app/src/main/java/app/organicmaps/editor/data/Timespan.java rename to android/app/src/main/java/app/organicmaps/sdk/editor/data/Timespan.java index bbd6c0ce7..4deae058e 100644 --- a/android/app/src/main/java/app/organicmaps/editor/data/Timespan.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/data/Timespan.java @@ -1,4 +1,4 @@ -package app.organicmaps.editor.data; +package app.organicmaps.sdk.editor.data; import androidx.annotation.Keep; diff --git a/android/app/src/main/java/app/organicmaps/editor/data/Timetable.java b/android/app/src/main/java/app/organicmaps/sdk/editor/data/Timetable.java similarity index 85% rename from android/app/src/main/java/app/organicmaps/editor/data/Timetable.java rename to android/app/src/main/java/app/organicmaps/sdk/editor/data/Timetable.java index 27e43cd27..aaac0c6c2 100644 --- a/android/app/src/main/java/app/organicmaps/editor/data/Timetable.java +++ b/android/app/src/main/java/app/organicmaps/sdk/editor/data/Timetable.java @@ -1,4 +1,4 @@ -package app.organicmaps.editor.data; +package app.organicmaps.sdk.editor.data; import androidx.annotation.IntRange; import androidx.annotation.Keep; @@ -14,7 +14,8 @@ public class Timetable public final boolean isFullday; public final int[] weekdays; - public Timetable(@NonNull Timespan workingTime, @NonNull Timespan[] closedHours, boolean isFullday, @NonNull int[] weekdays) + public Timetable(@NonNull Timespan workingTime, @NonNull Timespan[] closedHours, boolean isFullday, + @NonNull int[] weekdays) { this.workingTimespan = workingTime; this.closedTimespans = closedHours; @@ -42,13 +43,11 @@ public class Timetable public String toString() { StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("Working timespan : ").append(workingTimespan).append("\n") - .append("Closed timespans : "); + stringBuilder.append("Working timespan : ").append(workingTimespan).append("\n").append("Closed timespans : "); for (Timespan timespan : closedTimespans) stringBuilder.append(timespan).append(" "); stringBuilder.append("\n"); - stringBuilder.append("Fullday : ").append(isFullday).append("\n") - .append("Weekdays : "); + stringBuilder.append("Fullday : ").append(isFullday).append("\n").append("Weekdays : "); for (int i : weekdays) stringBuilder.append(i); return stringBuilder.toString(); diff --git a/android/app/src/main/java/app/organicmaps/location/AndroidNativeProvider.java b/android/app/src/main/java/app/organicmaps/sdk/location/AndroidNativeProvider.java similarity index 83% rename from android/app/src/main/java/app/organicmaps/location/AndroidNativeProvider.java rename to android/app/src/main/java/app/organicmaps/sdk/location/AndroidNativeProvider.java index 2b171b014..de938d03d 100644 --- a/android/app/src/main/java/app/organicmaps/location/AndroidNativeProvider.java +++ b/android/app/src/main/java/app/organicmaps/sdk/location/AndroidNativeProvider.java @@ -1,24 +1,20 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; -import static app.organicmaps.util.concurrency.UiThread.runLater; +import static app.organicmaps.sdk.util.concurrency.UiThread.runLater; import android.content.Context; import android.location.Location; import android.location.LocationManager; import android.os.Bundle; import android.os.Looper; - import androidx.annotation.NonNull; import androidx.annotation.RequiresPermission; import androidx.core.location.LocationListenerCompat; import androidx.core.location.LocationManagerCompat; import androidx.core.location.LocationRequestCompat; - -import app.organicmaps.MwmApplication; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.util.log.Logger; import java.util.HashSet; import java.util.Set; @@ -43,7 +39,6 @@ class AndroidNativeProvider extends BaseLocationProvider mListener.onLocationDisabled(); } - @Override public void onProviderEnabled(@NonNull String provider) { @@ -68,7 +63,7 @@ class AndroidNativeProvider extends BaseLocationProvider AndroidNativeProvider(@NonNull Context context, @NonNull BaseLocationProvider.Listener listener) { super(listener); - mLocationManager = (LocationManager) MwmApplication.from(context).getSystemService(Context.LOCATION_SERVICE); + mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); mProviders = new HashSet<>(); // This service is always available on all versions of Android if (mLocationManager == null) @@ -84,10 +79,12 @@ class AndroidNativeProvider extends BaseLocationProvider if (!mProviders.isEmpty()) throw new IllegalStateException("Already started"); - final LocationRequestCompat locationRequest = new LocationRequestCompat.Builder(interval) - // The quality is a hint to providers on how they should weigh power vs accuracy tradeoffs. - .setQuality(LocationRequestCompat.QUALITY_HIGH_ACCURACY) - .build(); + final LocationRequestCompat locationRequest = + new LocationRequestCompat + .Builder(interval) + // The quality is a hint to providers on how they should weigh power vs accuracy tradeoffs. + .setQuality(LocationRequestCompat.QUALITY_HIGH_ACCURACY) + .build(); // API 31+ provides `fused` provider which aggregates `gps` and `network` and potentially other sensors as well. // Unfortunately, certain LineageOS ROMs have broken `fused` provider that pretends to be enabled, but in @@ -110,10 +107,10 @@ class AndroidNativeProvider extends BaseLocationProvider for (String provider : mProviders) { - Logger.d(TAG, "Request Android native provider '" + provider - + "' to get locations at this interval = " + interval + " ms"); - LocationManagerCompat.requestLocationUpdates(mLocationManager, provider, locationRequest, - mNativeLocationListener, Looper.myLooper()); + Logger.d(TAG, "Request Android native provider '" + provider + "' to get locations at this interval = " + interval + + " ms"); + LocationManagerCompat.requestLocationUpdates(mLocationManager, provider, locationRequest, mNativeLocationListener, + Looper.myLooper()); } } diff --git a/android/app/src/main/java/app/organicmaps/location/BaseLocationProvider.java b/android/app/src/main/java/app/organicmaps/sdk/location/BaseLocationProvider.java similarity index 96% rename from android/app/src/main/java/app/organicmaps/location/BaseLocationProvider.java rename to android/app/src/main/java/app/organicmaps/sdk/location/BaseLocationProvider.java index cc996b056..1a7ce73ed 100644 --- a/android/app/src/main/java/app/organicmaps/location/BaseLocationProvider.java +++ b/android/app/src/main/java/app/organicmaps/sdk/location/BaseLocationProvider.java @@ -1,11 +1,10 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; import android.app.PendingIntent; import android.location.Location; - import androidx.annotation.NonNull; import androidx.annotation.RequiresPermission; import androidx.annotation.UiThread; diff --git a/android/app/src/main/java/app/organicmaps/location/LocationHelper.java b/android/app/src/main/java/app/organicmaps/sdk/location/LocationHelper.java similarity index 89% rename from android/app/src/main/java/app/organicmaps/location/LocationHelper.java rename to android/app/src/main/java/app/organicmaps/sdk/location/LocationHelper.java index 4cb376f38..7cf9cfdda 100644 --- a/android/app/src/main/java/app/organicmaps/location/LocationHelper.java +++ b/android/app/src/main/java/app/organicmaps/sdk/location/LocationHelper.java @@ -1,4 +1,4 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; @@ -9,7 +9,6 @@ import android.content.Context; import android.location.Location; import android.location.LocationManager; import android.os.Handler; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresPermission; @@ -17,20 +16,18 @@ import androidx.annotation.UiThread; import androidx.core.content.ContextCompat; import androidx.core.location.GnssStatusCompat; import androidx.core.location.LocationManagerCompat; - -import org.chromium.base.ObserverList; - -import app.organicmaps.Framework; -import app.organicmaps.Map; import app.organicmaps.MwmApplication; -import app.organicmaps.bookmarks.data.FeatureId; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.sdk.routing.JunctionInfo; import app.organicmaps.routing.RoutingController; -import app.organicmaps.util.Config; -import app.organicmaps.util.LocationUtils; -import app.organicmaps.util.NetworkPolicy; -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.Map; +import app.organicmaps.sdk.bookmarks.data.FeatureId; +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.routing.JunctionInfo; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.NetworkPolicy; +import app.organicmaps.sdk.util.log.Logger; +import org.chromium.base.ObserverList; public class LocationHelper implements BaseLocationProvider.Listener { @@ -44,6 +41,8 @@ public class LocationHelper implements BaseLocationProvider.Listener @NonNull private final Context mContext; + @NonNull + private final SensorHelper mSensorHelper; private static final String TAG = LocationState.LOCATION_TAG; @@ -62,8 +61,7 @@ public class LocationHelper implements BaseLocationProvider.Listener private Runnable mLocationTimeoutRunnable = this::notifyLocationUpdateTimeout; @NonNull - private final GnssStatusCompat.Callback mGnssStatusCallback = new GnssStatusCompat.Callback() - { + private final GnssStatusCompat.Callback mGnssStatusCallback = new GnssStatusCompat.Callback() { @Override public void onStarted() { @@ -99,15 +97,10 @@ public class LocationHelper implements BaseLocationProvider.Listener } }; - @NonNull - public static LocationHelper from(@NonNull Context context) - { - return MwmApplication.from(context).getLocationHelper(); - } - - public LocationHelper(@NonNull Context context) + public LocationHelper(@NonNull Context context, @NonNull SensorHelper sensorHelper) { mContext = context; + mSensorHelper = sensorHelper; mLocationProvider = LocationProviderFactory.getProvider(mContext, this); mHandler = new Handler(); } @@ -129,7 +122,7 @@ public class LocationHelper implements BaseLocationProvider.Listener if (mMyPosition == null) mMyPosition = MapObject.createMapObject(FeatureId.EMPTY, MapObject.MY_POSITION, "", "", - mSavedLocation.getLatitude(), mSavedLocation.getLongitude()); + mSavedLocation.getLatitude(), mSavedLocation.getLongitude()); return mMyPosition; } @@ -139,7 +132,10 @@ public class LocationHelper implements BaseLocationProvider.Listener * @return {@code null} if no location is saved. */ @Nullable - public Location getSavedLocation() { return mSavedLocation; } + public Location getSavedLocation() + { + return mSavedLocation; + } /** * Indicates about whether a location provider is polling location updates right now or not. @@ -170,13 +166,10 @@ public class LocationHelper implements BaseLocationProvider.Listener return; } - LocationState.nativeLocationUpdated(mSavedLocation.getTime(), - mSavedLocation.getLatitude(), - mSavedLocation.getLongitude(), - mSavedLocation.getAccuracy(), - mSavedLocation.getAltitude(), - mSavedLocation.getSpeed(), - mSavedLocation.getBearing()); + LocationState.nativeLocationUpdated(mSavedLocation.getTime(), mSavedLocation.getLatitude(), + mSavedLocation.getLongitude(), mSavedLocation.getAccuracy(), + mSavedLocation.getAltitude(), mSavedLocation.getSpeed(), + mSavedLocation.getBearing()); } private void notifyLocationUpdateTimeout() @@ -256,8 +249,8 @@ public class LocationHelper implements BaseLocationProvider.Listener public void onFusedLocationUnsupported() { // Try to downgrade to the native provider first and restart the service before notifying the user. - Logger.d(TAG, "provider = " + mLocationProvider.getClass().getSimpleName() + " is not supported," + - " downgrading to use native provider"); + Logger.d(TAG, "provider = " + mLocationProvider.getClass().getSimpleName() + " is not supported," + + " downgrading to use native provider"); mLocationProvider.stop(); mLocationProvider = new AndroidNativeProvider(mContext, this); mActive = true; @@ -279,8 +272,8 @@ public class LocationHelper implements BaseLocationProvider.Listener @UiThread public void onLocationDisabled() { - Logger.d(TAG, "provider = " + mLocationProvider.getClass().getSimpleName() + - " settings = " + LocationUtils.areLocationServicesTurnedOn(mContext)); + Logger.d(TAG, "provider = " + mLocationProvider.getClass().getSimpleName() + + " settings = " + LocationUtils.areLocationServicesTurnedOn(mContext)); stop(); LocationState.nativeOnLocationError(LocationState.ERROR_GPS_OFF); @@ -327,8 +320,7 @@ public class LocationHelper implements BaseLocationProvider.Listener final int mode = Map.isEngineCreated() ? LocationState.getMode() : LocationState.NOT_FOLLOW_NO_POSITION; return switch (mode) { - case LocationState.PENDING_POSITION, LocationState.FOLLOW, LocationState.FOLLOW_AND_ROTATE -> - INTERVAL_FOLLOW_MS; + case LocationState.PENDING_POSITION, LocationState.FOLLOW, LocationState.FOLLOW_AND_ROTATE -> INTERVAL_FOLLOW_MS; case LocationState.NOT_FOLLOW, LocationState.NOT_FOLLOW_NO_POSITION -> INTERVAL_NOT_FOLLOW_MS; default -> throw new IllegalArgumentException("Unsupported location mode: " + mode); }; @@ -372,12 +364,12 @@ public class LocationHelper implements BaseLocationProvider.Listener checkForAgpsUpdates(); if (LocationUtils.checkFineLocationPermission(mContext)) - SensorHelper.from(mContext).start(); + mSensorHelper.start(); final long oldInterval = mInterval; mInterval = calcLocationUpdatesInterval(); - Logger.i(TAG, "provider = " + mLocationProvider.getClass().getSimpleName() + - " mInFirstRun = " + mInFirstRun + " oldInterval = " + oldInterval + " interval = " + mInterval); + Logger.i(TAG, "provider = " + mLocationProvider.getClass().getSimpleName() + " mInFirstRun = " + mInFirstRun + + " oldInterval = " + oldInterval + " interval = " + mInterval); mActive = true; mLocationProvider.start(mInterval); mHandler.postDelayed(mLocationTimeoutRunnable, LOCATION_UPDATE_TIMEOUT_MS); @@ -398,7 +390,7 @@ public class LocationHelper implements BaseLocationProvider.Listener Logger.i(TAG); mLocationProvider.stop(); unsubscribeFromGnssStatusUpdates(); - SensorHelper.from(mContext).stop(); + mSensorHelper.stop(); mHandler.removeCallbacks(mLocationTimeoutRunnable); mActive = false; } @@ -459,7 +451,7 @@ public class LocationHelper implements BaseLocationProvider.Listener return; final LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); LocationManagerCompat.registerGnssStatusCallback(locationManager, ContextCompat.getMainExecutor(mContext), - mGnssStatusCallback); + mGnssStatusCallback); } private void unsubscribeFromGnssStatusUpdates() diff --git a/android/app/src/main/java/app/organicmaps/location/LocationListener.java b/android/app/src/main/java/app/organicmaps/sdk/location/LocationListener.java similarity index 91% rename from android/app/src/main/java/app/organicmaps/location/LocationListener.java rename to android/app/src/main/java/app/organicmaps/sdk/location/LocationListener.java index b05ab8ffb..3eb4bb9aa 100644 --- a/android/app/src/main/java/app/organicmaps/location/LocationListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/location/LocationListener.java @@ -1,8 +1,7 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; import android.app.PendingIntent; import android.location.Location; - import androidx.annotation.NonNull; public interface LocationListener diff --git a/android/app/src/main/java/app/organicmaps/location/LocationState.java b/android/app/src/main/java/app/organicmaps/sdk/location/LocationState.java similarity index 79% rename from android/app/src/main/java/app/organicmaps/location/LocationState.java rename to android/app/src/main/java/app/organicmaps/sdk/location/LocationState.java index 0ee6d3b8d..2478a15cd 100644 --- a/android/app/src/main/java/app/organicmaps/location/LocationState.java +++ b/android/app/src/main/java/app/organicmaps/sdk/location/LocationState.java @@ -1,17 +1,15 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; import androidx.annotation.IntDef; import androidx.annotation.Keep; import androidx.annotation.NonNull; - -import app.organicmaps.Map; - +import app.organicmaps.sdk.Map; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; public final class LocationState { - public static final String LOCATION_TAG = LocationState.class.getPackage().getName(); + public static final String LOCATION_TAG = LocationState.class.getSimpleName(); public interface ModeChangeListener { @@ -22,8 +20,9 @@ public final class LocationState } @Retention(RetentionPolicy.SOURCE) - @IntDef({ PENDING_POSITION, NOT_FOLLOW_NO_POSITION, NOT_FOLLOW, FOLLOW, FOLLOW_AND_ROTATE}) - @interface Value {} + @IntDef({PENDING_POSITION, NOT_FOLLOW_NO_POSITION, NOT_FOLLOW, FOLLOW, FOLLOW_AND_ROTATE}) + @interface Value + {} // These values should correspond to location::EMyPositionMode enum (from platform/location.hpp) public static final int PENDING_POSITION = 0; @@ -34,11 +33,11 @@ public final class LocationState // These constants should correspond to values defined in platform/location.hpp // Leave 0-value as no any error. - //private static final int ERROR_UNKNOWN = 0; - //private static final int ERROR_NOT_SUPPORTED = 1; + // private static final int ERROR_UNKNOWN = 0; + // private static final int ERROR_NOT_SUPPORTED = 1; public static final int ERROR_DENIED = 2; public static final int ERROR_GPS_OFF = 3; - //public static final int ERROR_TIMEOUT = 4; // Unused on Android (only used on Qt) + // public static final int ERROR_TIMEOUT = 4; // Unused on Android (only used on Qt) public static native void nativeSwitchToNextMode(); @Value @@ -49,8 +48,8 @@ public final class LocationState public static native void nativeOnLocationError(int errorCode); - static native void nativeLocationUpdated(long time, double lat, double lon, float accuracy, - double altitude, float speed, float bearing); + static native void nativeLocationUpdated(long time, double lat, double lon, float accuracy, double altitude, + float speed, float bearing); private LocationState() {} diff --git a/android/app/src/main/java/app/organicmaps/location/PlatformSocket.java b/android/app/src/main/java/app/organicmaps/sdk/location/PlatformSocket.java similarity index 92% rename from android/app/src/main/java/app/organicmaps/location/PlatformSocket.java rename to android/app/src/main/java/app/organicmaps/sdk/location/PlatformSocket.java index 406bff5c0..019b0b1cf 100644 --- a/android/app/src/main/java/app/organicmaps/location/PlatformSocket.java +++ b/android/app/src/main/java/app/organicmaps/sdk/location/PlatformSocket.java @@ -1,23 +1,21 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; import android.annotation.SuppressLint; import android.net.SSLCertificateSocketFactory; import android.os.SystemClock; - import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import app.organicmaps.BuildConfig; -import app.organicmaps.util.log.Logger; - -import javax.net.SocketFactory; -import javax.net.ssl.SSLSocketFactory; +import app.organicmaps.sdk.util.log.Logger; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; +import javax.net.SocketFactory; +import javax.net.ssl.SSLSocketFactory; /** * Implements interface that will be used by the core for @@ -132,7 +130,7 @@ class PlatformSocket // Trusting to any ssl certificate factory that will be used in // debug mode, for testing purposes only. if (BuildConfig.DEBUG) - //TODO: implement the custom KeyStore to make the self-signed certificates work + // TODO: implement the custom KeyStore to make the self-signed certificates work return SSLCertificateSocketFactory.getInsecure(0, null); return SSLSocketFactory.getDefault(); @@ -150,10 +148,12 @@ class PlatformSocket { mSocket.close(); Logger.d(TAG, "Socket has been closed: " + this + "\n"); - } catch (IOException e) + } + catch (IOException e) { Logger.e(TAG, "Failed to close socket: " + this + "\n"); - } finally + } + finally { mSocket = null; } @@ -194,19 +194,21 @@ class PlatformSocket Logger.d(TAG, "Read bytes count = " + read + "\n"); readBytes += read; - } catch (SocketTimeoutException e) + } + catch (SocketTimeoutException e) { long readingTime = SystemClock.elapsedRealtime() - startTime; Logger.e(TAG, "Socked timeout has occurred after " + readingTime + " (ms)\n "); if (readingTime > mTimeout) { - Logger.e(TAG, "Socket wrapper timeout has occurred, requested count = " + - (count - readBytes) + ", readBytes = " + readBytes + "\n"); + Logger.e(TAG, "Socket wrapper timeout has occurred, requested count = " + (count - readBytes) + + ", readBytes = " + readBytes + "\n"); break; } } } - } catch (IOException e) + } + catch (IOException e) { Logger.e(TAG, "Failed to read data from socket: " + this + "\n"); } @@ -230,11 +232,13 @@ class PlatformSocket out.write(data, 0, count); Logger.d(TAG, count + " bytes are written\n"); return true; - } catch (SocketTimeoutException e) + } + catch (SocketTimeoutException e) { long writingTime = SystemClock.elapsedRealtime() - startTime; Logger.e(TAG, "Socked timeout has occurred after " + writingTime + " (ms)\n"); - } catch (IOException e) + } + catch (IOException e) { Logger.e(TAG, "Failed to write data to socket: " + this + "\n"); } @@ -270,7 +274,8 @@ class PlatformSocket try { socket.setSoTimeout(millis); - } catch (SocketException e) + } + catch (SocketException e) { Logger.e(TAG, "Failed to set system socket timeout: " + millis + "ms, " + this + "\n"); } @@ -279,10 +284,7 @@ class PlatformSocket @Override public String toString() { - return "PlatformSocket{" + - "mSocket=" + mSocket + - ", mHost='" + mHost + '\'' + - ", mPort=" + mPort + - '}'; + return "PlatformSocket{" + + "mSocket=" + mSocket + ", mHost='" + mHost + '\'' + ", mPort=" + mPort + '}'; } } diff --git a/android/app/src/main/java/app/organicmaps/location/RouteSimulationProvider.java b/android/app/src/main/java/app/organicmaps/sdk/location/RouteSimulationProvider.java similarity index 89% rename from android/app/src/main/java/app/organicmaps/location/RouteSimulationProvider.java rename to android/app/src/main/java/app/organicmaps/sdk/location/RouteSimulationProvider.java index 037c1abb9..329cd319f 100644 --- a/android/app/src/main/java/app/organicmaps/location/RouteSimulationProvider.java +++ b/android/app/src/main/java/app/organicmaps/sdk/location/RouteSimulationProvider.java @@ -1,15 +1,13 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; import android.content.Context; import android.location.Location; import android.os.SystemClock; - import androidx.annotation.NonNull; - import app.organicmaps.sdk.routing.JunctionInfo; -import app.organicmaps.util.LocationUtils; -import app.organicmaps.util.concurrency.UiThread; -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.sdk.util.log.Logger; class RouteSimulationProvider extends BaseLocationProvider { diff --git a/android/app/src/main/java/app/organicmaps/location/SensorHelper.java b/android/app/src/main/java/app/organicmaps/sdk/location/SensorHelper.java similarity index 92% rename from android/app/src/main/java/app/organicmaps/location/SensorHelper.java rename to android/app/src/main/java/app/organicmaps/sdk/location/SensorHelper.java index 57d11c8ed..22ffd9cfc 100644 --- a/android/app/src/main/java/app/organicmaps/location/SensorHelper.java +++ b/android/app/src/main/java/app/organicmaps/sdk/location/SensorHelper.java @@ -1,4 +1,4 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; import android.content.Context; import android.hardware.Sensor; @@ -6,15 +6,11 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.util.Log; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; - -import app.organicmaps.MwmApplication; -import app.organicmaps.util.LocationUtils; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.util.LocationUtils; +import app.organicmaps.sdk.util.log.Logger; import java.util.LinkedHashSet; import java.util.Set; @@ -37,12 +33,6 @@ public class SensorHelper implements SensorEventListener @NonNull private final Set mListeners = new LinkedHashSet<>(); - @NonNull - public static SensorHelper from(@NonNull Context context) - { - return MwmApplication.from(context).getSensorHelper(); - } - @Override public void onSensorChanged(SensorEvent event) { @@ -55,8 +45,7 @@ public class SensorHelper implements SensorEventListener mLastAccuracy = event.accuracy; switch (mLastAccuracy) { - case SensorManager.SENSOR_STATUS_ACCURACY_HIGH: - break; + case SensorManager.SENSOR_STATUS_ACCURACY_HIGH: break; case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM: for (SensorListener listener : mListeners) listener.onCompassCalibrationRecommended(); diff --git a/android/app/src/main/java/app/organicmaps/location/SensorListener.java b/android/app/src/main/java/app/organicmaps/sdk/location/SensorListener.java similarity index 85% rename from android/app/src/main/java/app/organicmaps/location/SensorListener.java rename to android/app/src/main/java/app/organicmaps/sdk/location/SensorListener.java index 92350acd3..712546959 100644 --- a/android/app/src/main/java/app/organicmaps/location/SensorListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/location/SensorListener.java @@ -1,4 +1,4 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; public interface SensorListener { diff --git a/android/app/src/main/java/app/organicmaps/location/TrackRecorder.java b/android/app/src/main/java/app/organicmaps/sdk/location/TrackRecorder.java similarity index 90% rename from android/app/src/main/java/app/organicmaps/location/TrackRecorder.java rename to android/app/src/main/java/app/organicmaps/sdk/location/TrackRecorder.java index a20847ca8..f12e2fe35 100644 --- a/android/app/src/main/java/app/organicmaps/location/TrackRecorder.java +++ b/android/app/src/main/java/app/organicmaps/sdk/location/TrackRecorder.java @@ -1,4 +1,4 @@ -package app.organicmaps.location; +package app.organicmaps.sdk.location; public class TrackRecorder { diff --git a/android/app/src/main/java/app/organicmaps/sdk/maplayer/Mode.java b/android/app/src/main/java/app/organicmaps/sdk/maplayer/Mode.java new file mode 100644 index 000000000..1afdbadf5 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/maplayer/Mode.java @@ -0,0 +1,71 @@ +package app.organicmaps.sdk.maplayer; + +import android.content.Context; +import androidx.annotation.NonNull; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.maplayer.isolines.IsolinesManager; +import app.organicmaps.sdk.maplayer.subway.SubwayManager; +import app.organicmaps.sdk.maplayer.traffic.TrafficManager; +import app.organicmaps.sdk.util.ThemeSwitcher; + +public enum Mode +{ + TRAFFIC { + @Override + public boolean isEnabled(@NonNull Context context) + { + return !SubwayManager.isEnabled() && TrafficManager.INSTANCE.isEnabled(); + } + + @Override + public void setEnabled(@NonNull Context context, boolean isEnabled) + { + TrafficManager.INSTANCE.setEnabled(isEnabled); + } + }, + SUBWAY { + @Override + public boolean isEnabled(@NonNull Context context) + { + return SubwayManager.isEnabled(); + } + + @Override + public void setEnabled(@NonNull Context context, boolean isEnabled) + { + SubwayManager.setEnabled(isEnabled); + } + }, + + ISOLINES { + @Override + public boolean isEnabled(@NonNull Context context) + { + return IsolinesManager.isEnabled(); + } + + @Override + public void setEnabled(@NonNull Context context, boolean isEnabled) + { + IsolinesManager.setEnabled(isEnabled); + } + }, + OUTDOORS { + @Override + public boolean isEnabled(@NonNull Context context) + { + return Framework.nativeIsOutdoorsLayerEnabled(); + } + + @Override + public void setEnabled(@NonNull Context context, boolean isEnabled) + { + Framework.nativeSetOutdoorsLayerEnabled(isEnabled); + ThemeSwitcher.INSTANCE.restart(true); + } + }; + + public abstract boolean isEnabled(@NonNull Context context); + + public abstract void setEnabled(@NonNull Context context, boolean isEnabled); +} diff --git a/android/app/src/main/java/app/organicmaps/maplayer/isolines/IsolinesErrorDialogListener.java b/android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/IsolinesErrorDialogListener.java similarity index 74% rename from android/app/src/main/java/app/organicmaps/maplayer/isolines/IsolinesErrorDialogListener.java rename to android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/IsolinesErrorDialogListener.java index 1e77d6ba4..5fb1ea738 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/isolines/IsolinesErrorDialogListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/IsolinesErrorDialogListener.java @@ -1,4 +1,4 @@ -package app.organicmaps.maplayer.isolines; +package app.organicmaps.sdk.maplayer.isolines; import androidx.annotation.NonNull; diff --git a/android/app/src/main/java/app/organicmaps/maplayer/isolines/IsolinesManager.java b/android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/IsolinesManager.java similarity index 70% rename from android/app/src/main/java/app/organicmaps/maplayer/isolines/IsolinesManager.java rename to android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/IsolinesManager.java index 1957bbae0..e656492b9 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/isolines/IsolinesManager.java +++ b/android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/IsolinesManager.java @@ -1,21 +1,17 @@ -package app.organicmaps.maplayer.isolines; +package app.organicmaps.sdk.maplayer.isolines; -import android.app.Application; import android.content.Context; - import androidx.annotation.NonNull; - -import app.organicmaps.Framework; -import app.organicmaps.MwmApplication; +import app.organicmaps.sdk.Framework; public class IsolinesManager { @NonNull private final OnIsolinesChangedListener mListener; - public IsolinesManager(@NonNull Application application) + public IsolinesManager(@NonNull Context context) { - mListener = new OnIsolinesChangedListener(application); + mListener = new OnIsolinesChangedListener(context); } static public boolean isEnabled() @@ -41,13 +37,6 @@ public class IsolinesManager registerListener(); } - @NonNull - public static IsolinesManager from(@NonNull Context context) - { - MwmApplication app = (MwmApplication) context.getApplicationContext(); - return app.getIsolinesManager(); - } - private static native void nativeAddListener(@NonNull OnIsolinesChangedListener listener); private static native void nativeRemoveListener(@NonNull OnIsolinesChangedListener listener); private static native boolean nativeShouldShowNotification(); diff --git a/android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/IsolinesState.java b/android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/IsolinesState.java new file mode 100644 index 000000000..37cdfe8b6 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/IsolinesState.java @@ -0,0 +1,40 @@ +package app.organicmaps.sdk.maplayer.isolines; + +import android.content.Context; +import android.view.View; +import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import app.organicmaps.R; +import app.organicmaps.util.Utils; + +public enum IsolinesState +{ + DISABLED, + ENABLED, + EXPIREDDATA { + @Override + public void activate(@NonNull Context context, @Nullable View view, @Nullable View viewAbove) + { + if (view != null) + Utils.showSnackbar(context, view, viewAbove, R.string.isolines_activation_error_dialog); + else + Toast.makeText(context, R.string.isolines_activation_error_dialog, Toast.LENGTH_SHORT).show(); + } + }, + NODATA { + @Override + public void activate(@NonNull Context context, @Nullable View view, @Nullable View viewAbove) + { + if (view != null) + Utils.showSnackbar(context, view, viewAbove, R.string.isolines_location_error_dialog); + else + Toast.makeText(context, R.string.isolines_location_error_dialog, Toast.LENGTH_SHORT).show(); + } + }; + + public void activate(@NonNull Context context, @Nullable View viewAbove, @Nullable View view) + { + /* Do nothing by default */ + } +} diff --git a/android/app/src/main/java/app/organicmaps/maplayer/isolines/OnIsolinesChangedListener.java b/android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/OnIsolinesChangedListener.java similarity index 72% rename from android/app/src/main/java/app/organicmaps/maplayer/isolines/OnIsolinesChangedListener.java rename to android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/OnIsolinesChangedListener.java index 54a4fd570..01a6fe614 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/isolines/OnIsolinesChangedListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/maplayer/isolines/OnIsolinesChangedListener.java @@ -1,19 +1,18 @@ -package app.organicmaps.maplayer.isolines; - -import android.app.Application; +package app.organicmaps.sdk.maplayer.isolines; +import android.content.Context; import androidx.annotation.Keep; import androidx.annotation.NonNull; class OnIsolinesChangedListener { @NonNull - private final Application mApp; + private final Context mContext; private IsolinesErrorDialogListener mListener; - OnIsolinesChangedListener(@NonNull Application app) + OnIsolinesChangedListener(@NonNull Context app) { - mApp = app; + mContext = app; } // Called from JNI. @@ -24,7 +23,7 @@ class OnIsolinesChangedListener IsolinesState state = IsolinesState.values()[type]; if (mListener == null) { - state.activate(mApp, null, null); + state.activate(mContext, null, null); return; } diff --git a/android/app/src/main/java/app/organicmaps/maplayer/subway/OnTransitSchemeChangedListener.java b/android/app/src/main/java/app/organicmaps/sdk/maplayer/subway/OnTransitSchemeChangedListener.java similarity index 78% rename from android/app/src/main/java/app/organicmaps/maplayer/subway/OnTransitSchemeChangedListener.java rename to android/app/src/main/java/app/organicmaps/sdk/maplayer/subway/OnTransitSchemeChangedListener.java index 35de4534f..469df3a8a 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/subway/OnTransitSchemeChangedListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/maplayer/subway/OnTransitSchemeChangedListener.java @@ -1,7 +1,6 @@ -package app.organicmaps.maplayer.subway; - -import android.app.Application; +package app.organicmaps.sdk.maplayer.subway; +import android.content.Context; import androidx.annotation.Keep; import androidx.annotation.MainThread; import androidx.annotation.NonNull; @@ -17,9 +16,9 @@ interface OnTransitSchemeChangedListener class Default implements OnTransitSchemeChangedListener { @NonNull - private final Application mContext; + private final Context mContext; - Default(@NonNull Application context) + Default(@NonNull Context context) { mContext = context; } diff --git a/android/app/src/main/java/app/organicmaps/maplayer/subway/SubwayManager.java b/android/app/src/main/java/app/organicmaps/sdk/maplayer/subway/SubwayManager.java similarity index 69% rename from android/app/src/main/java/app/organicmaps/maplayer/subway/SubwayManager.java rename to android/app/src/main/java/app/organicmaps/sdk/maplayer/subway/SubwayManager.java index e2f506261..2a420a15d 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/subway/SubwayManager.java +++ b/android/app/src/main/java/app/organicmaps/sdk/maplayer/subway/SubwayManager.java @@ -1,20 +1,17 @@ -package app.organicmaps.maplayer.subway; +package app.organicmaps.sdk.maplayer.subway; -import android.app.Application; import android.content.Context; - import androidx.annotation.NonNull; - -import app.organicmaps.Framework; -import app.organicmaps.MwmApplication; +import app.organicmaps.sdk.Framework; public class SubwayManager { @NonNull private final OnTransitSchemeChangedListener mSchemeChangedListener; - public SubwayManager(@NonNull Application application) { - mSchemeChangedListener = new OnTransitSchemeChangedListener.Default(application); + public SubwayManager(@NonNull Context context) + { + mSchemeChangedListener = new OnTransitSchemeChangedListener.Default(context); } static public void setEnabled(boolean isEnabled) @@ -41,12 +38,6 @@ public class SubwayManager nativeAddListener(mSchemeChangedListener); } - @NonNull - public static SubwayManager from(@NonNull Context context) - { - MwmApplication app = (MwmApplication) context.getApplicationContext(); - return app.getSubwayManager(); - } private static native void nativeAddListener(@NonNull OnTransitSchemeChangedListener listener); private static native void nativeRemoveListener(@NonNull OnTransitSchemeChangedListener listener); diff --git a/android/app/src/main/java/app/organicmaps/maplayer/subway/TransitSchemeState.java b/android/app/src/main/java/app/organicmaps/sdk/maplayer/subway/TransitSchemeState.java similarity index 50% rename from android/app/src/main/java/app/organicmaps/maplayer/subway/TransitSchemeState.java rename to android/app/src/main/java/app/organicmaps/sdk/maplayer/subway/TransitSchemeState.java index 705b2af16..08bbc95a7 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/subway/TransitSchemeState.java +++ b/android/app/src/main/java/app/organicmaps/sdk/maplayer/subway/TransitSchemeState.java @@ -1,24 +1,21 @@ -package app.organicmaps.maplayer.subway; +package app.organicmaps.sdk.maplayer.subway; import android.content.Context; import android.widget.Toast; - import androidx.annotation.NonNull; - import app.organicmaps.R; enum TransitSchemeState { DISABLED, ENABLED, - NO_DATA - { - @Override - public void activate(@NonNull Context context) - { - Toast.makeText(context, R.string.subway_data_unavailable, Toast.LENGTH_SHORT).show(); - } - }; + NO_DATA { + @Override + public void activate(@NonNull Context context) + { + Toast.makeText(context, R.string.subway_data_unavailable, Toast.LENGTH_SHORT).show(); + } + }; void activate(@NonNull Context context) { diff --git a/android/app/src/main/java/app/organicmaps/maplayer/traffic/TrafficManager.java b/android/app/src/main/java/app/organicmaps/sdk/maplayer/traffic/TrafficManager.java similarity index 89% rename from android/app/src/main/java/app/organicmaps/maplayer/traffic/TrafficManager.java rename to android/app/src/main/java/app/organicmaps/sdk/maplayer/traffic/TrafficManager.java index 9ef1d9fe7..c1b56b445 100644 --- a/android/app/src/main/java/app/organicmaps/maplayer/traffic/TrafficManager.java +++ b/android/app/src/main/java/app/organicmaps/sdk/maplayer/traffic/TrafficManager.java @@ -1,17 +1,14 @@ -package app.organicmaps.maplayer.traffic; +package app.organicmaps.sdk.maplayer.traffic; import androidx.annotation.MainThread; import androidx.annotation.NonNull; - -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.util.log.Logger; import java.util.ArrayList; import java.util.List; @SuppressWarnings("unused") @MainThread -public enum TrafficManager -{ +public enum TrafficManager { INSTANCE; private static final String TAG = TrafficManager.class.getSimpleName(); @@ -57,7 +54,7 @@ public enum TrafficManager Logger.d(TAG, "Disable traffic"); TrafficState.nativeDisable(); } - + public boolean isEnabled() { checkInitialization(); @@ -89,8 +86,10 @@ public enum TrafficManager if (mCallbacks.isEmpty()) { - Logger.w(TAG, "There are no attached callbacks. Invoke the 'detachAll' method " + - "only when it's really needed!", new Throwable()); + Logger.w(TAG, + "There are no attached callbacks. Invoke the 'detachAll' method " + + "only when it's really needed!", + new Throwable()); return; } @@ -125,8 +124,7 @@ public enum TrafficManager public void onTrafficStateChanged(int index) { TrafficState newTrafficState = TrafficState.values()[index]; - Logger.d(TAG, "onTrafficStateChanged current state = " + mState + - " new value = " + newTrafficState); + Logger.d(TAG, "onTrafficStateChanged current state = " + mState + " new value = " + newTrafficState); if (mState == newTrafficState) return; diff --git a/android/app/src/main/java/app/organicmaps/sdk/maplayer/traffic/TrafficState.java b/android/app/src/main/java/app/organicmaps/sdk/maplayer/traffic/TrafficState.java new file mode 100644 index 000000000..328caf609 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/maplayer/traffic/TrafficState.java @@ -0,0 +1,101 @@ +package app.organicmaps.sdk.maplayer.traffic; + +import androidx.annotation.Keep; +import androidx.annotation.MainThread; +import androidx.annotation.NonNull; +import java.util.List; + +@SuppressWarnings("unused") +enum TrafficState { + DISABLED { + @Override + protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) + { + callback.onDisabled(); + } + }, + + ENABLED { + @Override + protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) + { + callback.onEnabled(); + } + }, + + WAITING_DATA { + @Override + protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) + { + callback.onWaitingData(); + } + }, + + OUTDATED { + @Override + protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) + { + callback.onOutdated(); + } + }, + + NO_DATA { + @Override + protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) + { + callback.onNoData(); + } + }, + + NETWORK_ERROR { + @Override + protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) + { + callback.onNetworkError(); + } + }, + + EXPIRED_DATA { + @Override + protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) + { + callback.onExpiredData(); + } + }, + + EXPIRED_APP { + @Override + protected void activateInternal(@NonNull TrafficManager.TrafficCallback callback) + { + callback.onExpiredApp(); + } + }; + + public void activate(@NonNull List trafficCallbacks) + { + for (TrafficManager.TrafficCallback callback : trafficCallbacks) + activateInternal(callback); + } + + protected abstract void activateInternal(@NonNull TrafficManager.TrafficCallback callback); + + interface StateChangeListener + { + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @MainThread + void onTrafficStateChanged(int state); + } + + @MainThread + static native void nativeSetListener(@NonNull StateChangeListener listener); + + static native void nativeRemoveListener(); + + static native void nativeEnable(); + + static native void nativeDisable(); + + static native boolean nativeIsEnabled(); +} diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/CarDirection.java b/android/app/src/main/java/app/organicmaps/sdk/routing/CarDirection.java index 50b4f226a..02f43ccfe 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/routing/CarDirection.java +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/CarDirection.java @@ -1,11 +1,9 @@ package app.organicmaps.sdk.routing; import android.widget.ImageView; - import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; - -import app.organicmaps.R; +import app.organicmaps.sdk.R; /** * IMPORTANT : Order of enum values MUST BE the same as native CarDirection enum. diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/LaneWay.java b/android/app/src/main/java/app/organicmaps/sdk/routing/LaneWay.java index 1758bd831..3fab6e0d6 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/routing/LaneWay.java +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/LaneWay.java @@ -1,8 +1,7 @@ package app.organicmaps.sdk.routing; import androidx.annotation.DrawableRes; - -import app.organicmaps.R; +import app.organicmaps.sdk.R; /** * IMPORTANT : Order of enum values MUST BE the same diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/PedestrianTurnDirection.java b/android/app/src/main/java/app/organicmaps/sdk/routing/PedestrianTurnDirection.java index 1f64cd440..7dfa3f5a6 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/routing/PedestrianTurnDirection.java +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/PedestrianTurnDirection.java @@ -1,11 +1,9 @@ package app.organicmaps.sdk.routing; import android.widget.ImageView; - import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; - -import app.organicmaps.R; +import app.organicmaps.sdk.R; public enum PedestrianTurnDirection { diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/ResultCodes.java b/android/app/src/main/java/app/organicmaps/sdk/routing/ResultCodes.java new file mode 100644 index 000000000..266edcec7 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/ResultCodes.java @@ -0,0 +1,23 @@ +package app.organicmaps.sdk.routing; + +public interface ResultCodes +{ + // Codes correspond to native routing::RouterResultCode in routing/routing_callbacks.hpp + int NO_ERROR = 0; + int CANCELLED = 1; + int NO_POSITION = 2; + int INCONSISTENT_MWM_ROUTE = 3; + int ROUTING_FILE_NOT_EXIST = 4; + int START_POINT_NOT_FOUND = 5; + int END_POINT_NOT_FOUND = 6; + int DIFFERENT_MWM = 7; + int ROUTE_NOT_FOUND = 8; + int NEED_MORE_MAPS = 9; + int INTERNAL_ERROR = 10; + int FILE_TOO_OLD = 11; + int INTERMEDIATE_POINT_NOT_FOUND = 12; + int TRANSIT_ROUTE_NOT_FOUND_NO_NETWORK = 13; + int TRANSIT_ROUTE_NOT_FOUND_TOO_LONG_PEDESTRIAN = 14; + int ROUTE_NOT_FOUND_REDRESS_ROUTE_ERROR = 15; + int HAS_WARNINGS = 16; +} diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/RouteMarkData.java b/android/app/src/main/java/app/organicmaps/sdk/routing/RouteMarkData.java index e9ebb3cb3..9f3a2daa5 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/routing/RouteMarkData.java +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/RouteMarkData.java @@ -23,16 +23,16 @@ public final class RouteMarkData public final double mLat; public final double mLon; - private RouteMarkData(@Nullable String title, @Nullable String subtitle, - int pointType, int intermediateIndex, boolean isVisible, - boolean isMyPosition, boolean isPassed, double lat, double lon) + private RouteMarkData(@Nullable String title, @Nullable String subtitle, int pointType, int intermediateIndex, + boolean isVisible, boolean isMyPosition, boolean isPassed, double lat, double lon) { - this(title, subtitle, RouteMarkType.values()[pointType], intermediateIndex, isVisible, isMyPosition, isPassed, lat, lon); + this(title, subtitle, RouteMarkType.values()[pointType], intermediateIndex, isVisible, isMyPosition, isPassed, lat, + lon); } - public RouteMarkData(@Nullable String title, @Nullable String subtitle, - RouteMarkType pointType, int intermediateIndex, boolean isVisible, - boolean isMyPosition, boolean isPassed, double lat, double lon) + public RouteMarkData(@Nullable String title, @Nullable String subtitle, RouteMarkType pointType, + int intermediateIndex, boolean isVisible, boolean isMyPosition, boolean isPassed, double lat, + double lon) { mTitle = title; mSubtitle = subtitle; @@ -47,9 +47,7 @@ public final class RouteMarkData public boolean equals(RouteMarkData other) { - return mTitle != null && other.mTitle != null && - mTitle.compareTo(other.mTitle) == 0 && - mSubtitle != null && other.mSubtitle != null && - mSubtitle.compareTo(other.mSubtitle) == 0; + return mTitle != null && other.mTitle != null && mTitle.compareTo(other.mTitle) == 0 && mSubtitle != null + && other.mSubtitle != null && mSubtitle.compareTo(other.mSubtitle) == 0; } } diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/RoutePointInfo.java b/android/app/src/main/java/app/organicmaps/sdk/routing/RoutePointInfo.java index 3746ee5ea..c5997f8e1 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/routing/RoutePointInfo.java +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/RoutePointInfo.java @@ -2,7 +2,6 @@ package app.organicmaps.sdk.routing; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.Keep; import androidx.annotation.NonNull; @@ -11,8 +10,7 @@ import androidx.annotation.NonNull; @SuppressWarnings("unused") public final class RoutePointInfo implements Parcelable { - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public RoutePointInfo createFromParcel(Parcel in) { @@ -53,7 +51,7 @@ public final class RoutePointInfo implements Parcelable private RoutePointInfo(@NonNull Parcel in) { - //noinspection WrongConstant + // noinspection WrongConstant this(RouteMarkType.values()[in.readInt()] /* mMarkType */, in.readInt() /* mIntermediateIndex */); } diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/RoutingInfo.java b/android/app/src/main/java/app/organicmaps/sdk/routing/RoutingInfo.java index 842c1c421..b025675d3 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/routing/RoutingInfo.java +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/RoutingInfo.java @@ -1,8 +1,7 @@ package app.organicmaps.sdk.routing; import androidx.annotation.Keep; - -import app.organicmaps.util.Distance; +import app.organicmaps.sdk.util.Distance; // Called from JNI. @Keep @@ -35,10 +34,11 @@ public final class RoutingInfo private final boolean speedCamLimitExceeded; private final boolean shouldPlayWarningSignal; - private RoutingInfo(Distance distToTarget, Distance distToTurn, String currentStreet, String nextStreet, String nextNextStreet, double completionPercent, - int vehicleTurnOrdinal, int vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum, - int totalTime, SingleLaneInfo[] lanes, double speedLimitMps, boolean speedLimitExceeded, - boolean shouldPlayWarningSignal) + private RoutingInfo(Distance distToTarget, Distance distToTurn, String currentStreet, String nextStreet, + String nextNextStreet, double completionPercent, int vehicleTurnOrdinal, + int vehicleNextTurnOrdinal, int pedestrianTurnOrdinal, int exitNum, int totalTime, + SingleLaneInfo[] lanes, double speedLimitMps, boolean speedLimitExceeded, + boolean shouldPlayWarningSignal) { this.distToTarget = distToTarget; this.distToTurn = distToTurn; diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/RoutingOptions.java b/android/app/src/main/java/app/organicmaps/sdk/routing/RoutingOptions.java index 57d58a97b..6c510b27f 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/routing/RoutingOptions.java +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/RoutingOptions.java @@ -1,9 +1,7 @@ package app.organicmaps.sdk.routing; import androidx.annotation.NonNull; - -import app.organicmaps.settings.RoadType; - +import app.organicmaps.sdk.settings.RoadType; import java.util.HashSet; import java.util.Set; diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/TransitRouteInfo.java b/android/app/src/main/java/app/organicmaps/sdk/routing/TransitRouteInfo.java index 12174518f..92dfb3b68 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/routing/TransitRouteInfo.java +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/TransitRouteInfo.java @@ -2,7 +2,6 @@ package app.organicmaps.sdk.routing; import androidx.annotation.Keep; import androidx.annotation.NonNull; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -29,8 +28,8 @@ public final class TransitRouteInfo private final TransitStepInfo[] mSteps; private TransitRouteInfo(@NonNull String totalDistance, @NonNull String totalDistanceUnits, int totalTimeInSec, - @NonNull String totalPedestrianDistance, @NonNull String totalPedestrianDistanceUnits, - int totalPedestrianTimeInSec, @NonNull TransitStepInfo[] steps) + @NonNull String totalPedestrianDistance, @NonNull String totalPedestrianDistanceUnits, + int totalPedestrianTimeInSec, @NonNull TransitStepInfo[] steps) { mTotalDistance = totalDistance; mTotalDistanceUnits = totalDistanceUnits; diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/TransitStepInfo.java b/android/app/src/main/java/app/organicmaps/sdk/routing/TransitStepInfo.java index 38f174654..37baaf870 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/routing/TransitStepInfo.java +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/TransitStepInfo.java @@ -24,8 +24,8 @@ public final class TransitStepInfo private final int mColor; private final int mIntermediateIndex; - private TransitStepInfo(int type, @Nullable String distance, @Nullable String distanceUnits, - int timeInSec, @Nullable String number, int color, int intermediateIndex) + private TransitStepInfo(int type, @Nullable String distance, @Nullable String distanceUnits, int timeInSec, + @Nullable String number, int color, int intermediateIndex) { mType = TransitStepType.values()[type]; mDistance = distance; diff --git a/android/app/src/main/java/app/organicmaps/sdk/routing/TransitStepType.java b/android/app/src/main/java/app/organicmaps/sdk/routing/TransitStepType.java index 5d6cdc9b5..fb5b41b82 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/routing/TransitStepType.java +++ b/android/app/src/main/java/app/organicmaps/sdk/routing/TransitStepType.java @@ -1,18 +1,17 @@ package app.organicmaps.sdk.routing; import androidx.annotation.DrawableRes; - -import app.organicmaps.R; +import app.organicmaps.sdk.R; public enum TransitStepType { // A specific icon for different intermediate points is calculated dynamically in TransitStepView. INTERMEDIATE_POINT(R.drawable.ic_20px_route_planning_walk), PEDESTRIAN(R.drawable.ic_20px_route_planning_walk), - SUBWAY(R.drawable.ic_20px_route_planning_metro), - TRAIN(R.drawable.ic_20px_route_planning_train), - LIGHT_RAIL(R.drawable.ic_20px_route_planning_lightrail), - MONORAIL(R.drawable.ic_20px_route_planning_monorail), + SUBWAY(app.organicmaps.R.drawable.ic_route_planning_metro), + TRAIN(app.organicmaps.R.drawable.ic_route_planning_train), + LIGHT_RAIL(app.organicmaps.R.drawable.ic_route_planning_train), + MONORAIL(app.organicmaps.R.drawable.ic_route_planning_monorail), RULER(R.drawable.ic_ruler_route); @DrawableRes diff --git a/android/app/src/main/java/app/organicmaps/sdk/search/DisplayedCategories.java b/android/app/src/main/java/app/organicmaps/sdk/search/DisplayedCategories.java index 2ad6b7465..ed1c099a4 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/search/DisplayedCategories.java +++ b/android/app/src/main/java/app/organicmaps/sdk/search/DisplayedCategories.java @@ -5,11 +5,6 @@ import androidx.annotation.NonNull; public class DisplayedCategories { @NonNull - public static String[] getKeys() - { - return nativeGetKeys(); - } - - @NonNull - private static native String[] nativeGetKeys(); + public static native String[] nativeGetKeys(); + public static native boolean nativeIsLangSupported(String langCode); } diff --git a/android/app/src/main/java/app/organicmaps/sdk/search/MapSearchListener.java b/android/app/src/main/java/app/organicmaps/sdk/search/MapSearchListener.java index df0bb8aa6..73a14f686 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/search/MapSearchListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/search/MapSearchListener.java @@ -9,8 +9,7 @@ public interface MapSearchListener @Keep @SuppressWarnings("unused") record Result(String countryId, String matchedString) - { - } + {} // Called from JNI. @Keep diff --git a/android/app/src/main/java/app/organicmaps/sdk/search/Popularity.java b/android/app/src/main/java/app/organicmaps/sdk/search/Popularity.java index 0c64bf813..223597243 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/search/Popularity.java +++ b/android/app/src/main/java/app/organicmaps/sdk/search/Popularity.java @@ -2,7 +2,6 @@ package app.organicmaps.sdk.search; import android.os.Parcel; import android.os.Parcelable; - import androidx.annotation.Keep; import androidx.annotation.NonNull; @@ -49,8 +48,7 @@ public class Popularity implements Parcelable this.mType = Type.values()[tmpMPopularity]; } - public static final Creator CREATOR = new Creator<>() - { + public static final Creator CREATOR = new Creator<>() { @Override public Popularity createFromParcel(Parcel source) { diff --git a/android/app/src/main/java/app/organicmaps/sdk/search/SearchEngine.java b/android/app/src/main/java/app/organicmaps/sdk/search/SearchEngine.java index 582e5a2ca..7c199a19a 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/search/SearchEngine.java +++ b/android/app/src/main/java/app/organicmaps/sdk/search/SearchEngine.java @@ -1,22 +1,17 @@ package app.organicmaps.sdk.search; import android.content.Context; - import androidx.annotation.MainThread; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.util.Language; +import app.organicmaps.sdk.util.concurrency.UiThread; +import java.nio.charset.StandardCharsets; import org.chromium.base.ObserverList; -import app.organicmaps.Framework; -import app.organicmaps.util.Language; -import app.organicmaps.util.concurrency.UiThread; - -import java.nio.charset.StandardCharsets; - -public enum SearchEngine implements SearchListener, - MapSearchListener, - BookmarkSearchListener +public enum SearchEngine implements SearchListener, MapSearchListener, + BookmarkSearchListener { INSTANCE; @@ -27,34 +22,29 @@ public enum SearchEngine implements SearchListener, @Override public void onResultsUpdate(@NonNull final SearchResult[] results, final long timestamp) { - UiThread.run( - () -> - { - for (SearchListener listener : mListeners) - listener.onResultsUpdate(results, timestamp); - }); + UiThread.run(() -> { + for (SearchListener listener : mListeners) + listener.onResultsUpdate(results, timestamp); + }); } @Override public void onResultsEnd(final long timestamp) { - UiThread.run( - () -> - { - for (SearchListener listener : mListeners) - listener.onResultsEnd(timestamp); - }); + UiThread.run(() -> { + for (SearchListener listener : mListeners) + listener.onResultsEnd(timestamp); + }); } @Override - public void onMapSearchResults(@NonNull final MapSearchListener.Result[] results, final long timestamp, final boolean isLast) + public void onMapSearchResults(@NonNull final MapSearchListener.Result[] results, final long timestamp, + final boolean isLast) { - UiThread.run( - () -> - { - for (MapSearchListener listener : mMapListeners) - listener.onMapSearchResults(results, timestamp, isLast); - }); + UiThread.run(() -> { + for (MapSearchListener listener : mMapListeners) + listener.onMapSearchResults(results, timestamp, isLast); + }); } @Override @@ -114,31 +104,31 @@ public enum SearchEngine implements SearchListener, * @return whether search was actually started. */ @MainThread - public boolean search(@NonNull Context context, @NonNull String query, boolean isCategory, - long timestamp, boolean hasLocation, double lat, double lon) + public boolean search(@NonNull Context context, @NonNull String query, boolean isCategory, long timestamp, + boolean hasLocation, double lat, double lon) { - return nativeRunSearch(query.getBytes(StandardCharsets.UTF_8), isCategory, - Language.getKeyboardLocale(context), timestamp, hasLocation, lat, lon); + return nativeRunSearch(query.getBytes(StandardCharsets.UTF_8), isCategory, Language.getKeyboardLocale(context), + timestamp, hasLocation, lat, lon); } @MainThread - public void searchInteractive(@NonNull String query, boolean isCategory, @NonNull String locale, - long timestamp, boolean isMapAndTable, boolean hasLocation, double lat, double lon) + public void searchInteractive(@NonNull String query, boolean isCategory, @NonNull String locale, long timestamp, + boolean isMapAndTable, boolean hasLocation, double lat, double lon) { - nativeRunInteractiveSearch(query.getBytes(StandardCharsets.UTF_8), isCategory, - locale, timestamp, isMapAndTable, hasLocation, lat, lon); + nativeRunInteractiveSearch(query.getBytes(StandardCharsets.UTF_8), isCategory, locale, timestamp, isMapAndTable, + hasLocation, lat, lon); } @MainThread - public void searchInteractive(@NonNull String query, boolean isCategory, @NonNull String locale, - long timestamp, boolean isMapAndTable) + public void searchInteractive(@NonNull String query, boolean isCategory, @NonNull String locale, long timestamp, + boolean isMapAndTable) { searchInteractive(query, isCategory, locale, timestamp, isMapAndTable, false, 0, 0); } @MainThread - public void searchInteractive(@NonNull Context context, @NonNull String query, boolean isCategory, - long timestamp, boolean isMapAndTable) + public void searchInteractive(@NonNull Context context, @NonNull String query, boolean isCategory, long timestamp, + boolean isMapAndTable) { searchInteractive(query, isCategory, Language.getKeyboardLocale(context), timestamp, isMapAndTable, false, 0, 0); } @@ -146,8 +136,7 @@ public enum SearchEngine implements SearchListener, @MainThread public static void searchMaps(@NonNull Context context, @NonNull String query, long timestamp) { - nativeRunSearchMaps(query.getBytes(StandardCharsets.UTF_8), Language.getKeyboardLocale(context), - timestamp); + nativeRunSearchMaps(query.getBytes(StandardCharsets.UTF_8), Language.getKeyboardLocale(context), timestamp); } @MainThread @@ -201,6 +190,12 @@ public enum SearchEngine implements SearchListener, nativeShowResult(index); } + @MainThread + public void updateViewportWithLastResults() + { + nativeUpdateViewportWithLastResults(); + } + public void initialize() { nativeInit(); @@ -211,16 +206,14 @@ public enum SearchEngine implements SearchListener, /** * @param bytes utf-8 formatted bytes of query. */ - private static native boolean nativeRunSearch(byte[] bytes, boolean isCategory, - String language, long timestamp, boolean hasLocation, - double lat, double lon); + private static native boolean nativeRunSearch(byte[] bytes, boolean isCategory, String language, long timestamp, + boolean hasLocation, double lat, double lon); /** * @param bytes utf-8 formatted query bytes */ - private static native void nativeRunInteractiveSearch(byte[] bytes, boolean isCategory, - String language, long timestamp, - boolean isMapAndTable, boolean hasLocation, + private static native void nativeRunInteractiveSearch(byte[] bytes, boolean isCategory, String language, + long timestamp, boolean isMapAndTable, boolean hasLocation, double lat, double lon); /** @@ -237,4 +230,6 @@ public enum SearchEngine implements SearchListener, private static native void nativeCancelEverywhereSearch(); private static native void nativeCancelAllSearches(); + + private static native void nativeUpdateViewportWithLastResults(); } diff --git a/android/app/src/main/java/app/organicmaps/sdk/search/SearchListener.java b/android/app/src/main/java/app/organicmaps/sdk/search/SearchListener.java index 171ce9975..c7a629ee2 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/search/SearchListener.java +++ b/android/app/src/main/java/app/organicmaps/sdk/search/SearchListener.java @@ -15,7 +15,8 @@ public interface SearchListener // Called by JNI. @Keep @SuppressWarnings("unused") - default void onResultsUpdate(@NonNull SearchResult[] results, long timestamp) {} + default void onResultsUpdate(@NonNull SearchResult[] results, long timestamp) + {} /** * @param timestamp Timestamp of search request. @@ -23,5 +24,6 @@ public interface SearchListener // Called by JNI. @Keep @SuppressWarnings("unused") - default void onResultsEnd(long timestamp) {} + default void onResultsEnd(long timestamp) + {} } diff --git a/android/app/src/main/java/app/organicmaps/sdk/search/SearchRecents.java b/android/app/src/main/java/app/organicmaps/sdk/search/SearchRecents.java index e11e528e7..8a4294c63 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/search/SearchRecents.java +++ b/android/app/src/main/java/app/organicmaps/sdk/search/SearchRecents.java @@ -2,11 +2,8 @@ package app.organicmaps.sdk.search; import android.content.Context; import android.text.TextUtils; - import androidx.annotation.NonNull; - -import app.organicmaps.util.Language; - +import app.organicmaps.sdk.util.Language; import java.util.ArrayList; import java.util.List; diff --git a/android/app/src/main/java/app/organicmaps/sdk/search/SearchResult.java b/android/app/src/main/java/app/organicmaps/sdk/search/SearchResult.java index 2fdcf6861..61b00df7c 100644 --- a/android/app/src/main/java/app/organicmaps/sdk/search/SearchResult.java +++ b/android/app/src/main/java/app/organicmaps/sdk/search/SearchResult.java @@ -7,12 +7,10 @@ import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; import android.text.style.StyleSpan; - import androidx.annotation.Keep; import androidx.annotation.NonNull; - -import app.organicmaps.bookmarks.data.FeatureId; -import app.organicmaps.util.Distance; +import app.organicmaps.sdk.bookmarks.data.FeatureId; +import app.organicmaps.sdk.util.Distance; /** * Class instances are created from native code. @@ -31,8 +29,7 @@ public class SearchResult public static final int OPEN_NOW_YES = 1; public static final int OPEN_NOW_NO = 2; - public static final SearchResult EMPTY = new SearchResult("", "", 0, 0, - new int[]{}, new int[]{}); + public static final SearchResult EMPTY = new SearchResult("", "", 0, 0, new int[] {}, new int[] {}); // Used by JNI. @Keep @@ -51,9 +48,8 @@ public class SearchResult public final int minutesUntilClosed; public final boolean hasPopularityHigherPriority; - public Description(FeatureId featureId, String featureType, String region, Distance distance, - String description, int openNow, int minutesUntilOpen, int minutesUntilClosed, - boolean hasPopularityHigherPriority) + public Description(FeatureId featureId, String featureType, String region, Distance distance, String description, + int openNow, int minutesUntilOpen, int minutesUntilClosed, boolean hasPopularityHigherPriority) { this.featureId = featureId; this.localizedFeatureType = featureType; @@ -75,14 +71,16 @@ public class SearchResult public final int type; public final Description description; - // Consecutive pairs of indexes (each pair contains : start index, length), specifying highlighted matches of original query in result + // Consecutive pairs of indexes (each pair contains : start index, length), specifying highlighted matches of original + // query in result public final int[] highlightRanges; public final int[] descHighlightRanges; @NonNull private final Popularity mPopularity; - public SearchResult(String name, String suggestion, double lat, double lon, int[] highlightRanges, int[] descHighlightRanges) + public SearchResult(String name, String suggestion, double lat, double lon, int[] highlightRanges, + int[] descHighlightRanges) { this.name = name; this.suggestion = suggestion; @@ -156,5 +154,4 @@ public class SearchResult return builder; } - } diff --git a/android/app/src/main/java/app/organicmaps/settings/MapLanguageCode.java b/android/app/src/main/java/app/organicmaps/sdk/settings/MapLanguageCode.java similarity index 79% rename from android/app/src/main/java/app/organicmaps/settings/MapLanguageCode.java rename to android/app/src/main/java/app/organicmaps/sdk/settings/MapLanguageCode.java index 385d6d8dd..a712790b7 100644 --- a/android/app/src/main/java/app/organicmaps/settings/MapLanguageCode.java +++ b/android/app/src/main/java/app/organicmaps/sdk/settings/MapLanguageCode.java @@ -1,4 +1,4 @@ -package app.organicmaps.settings; +package app.organicmaps.sdk.settings; public class MapLanguageCode { diff --git a/android/app/src/main/java/app/organicmaps/settings/RoadType.java b/android/app/src/main/java/app/organicmaps/sdk/settings/RoadType.java similarity index 65% rename from android/app/src/main/java/app/organicmaps/settings/RoadType.java rename to android/app/src/main/java/app/organicmaps/sdk/settings/RoadType.java index ebe4a69a6..e74f08aed 100644 --- a/android/app/src/main/java/app/organicmaps/settings/RoadType.java +++ b/android/app/src/main/java/app/organicmaps/sdk/settings/RoadType.java @@ -1,4 +1,4 @@ -package app.organicmaps.settings; +package app.organicmaps.sdk.settings; public enum RoadType { diff --git a/android/app/src/main/java/app/organicmaps/sdk/settings/SpeedCameraMode.java b/android/app/src/main/java/app/organicmaps/sdk/settings/SpeedCameraMode.java new file mode 100644 index 000000000..badf5e6d8 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/settings/SpeedCameraMode.java @@ -0,0 +1,8 @@ +package app.organicmaps.sdk.settings; + +public enum SpeedCameraMode +{ + AUTO, + ALWAYS, + NEVER +} diff --git a/android/app/src/main/java/app/organicmaps/settings/UnitLocale.java b/android/app/src/main/java/app/organicmaps/sdk/settings/UnitLocale.java similarity index 96% rename from android/app/src/main/java/app/organicmaps/settings/UnitLocale.java rename to android/app/src/main/java/app/organicmaps/sdk/settings/UnitLocale.java index caeb9407d..c1c298f35 100644 --- a/android/app/src/main/java/app/organicmaps/settings/UnitLocale.java +++ b/android/app/src/main/java/app/organicmaps/sdk/settings/UnitLocale.java @@ -1,4 +1,4 @@ -package app.organicmaps.settings; +package app.organicmaps.sdk.settings; import java.util.Locale; diff --git a/android/app/src/main/java/app/organicmaps/sound/AudioFocusManager.java b/android/app/src/main/java/app/organicmaps/sdk/sound/AudioFocusManager.java similarity index 72% rename from android/app/src/main/java/app/organicmaps/sound/AudioFocusManager.java rename to android/app/src/main/java/app/organicmaps/sdk/sound/AudioFocusManager.java index babffb24d..56685670d 100644 --- a/android/app/src/main/java/app/organicmaps/sound/AudioFocusManager.java +++ b/android/app/src/main/java/app/organicmaps/sdk/sound/AudioFocusManager.java @@ -1,15 +1,14 @@ -package app.organicmaps.sound; +package app.organicmaps.sdk.sound; + +import static android.media.AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK; import android.content.Context; import android.media.AudioAttributes; import android.media.AudioFocusRequest; import android.media.AudioManager; import android.os.Build; - import androidx.annotation.Nullable; -import static android.media.AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK; - public class AudioFocusManager { @Nullable @@ -27,12 +26,12 @@ public class AudioFocusManager if (Build.VERSION.SDK_INT < 26) mOnFocusChange = focusGain -> {}; else - mAudioFocusRequest = new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK).setAudioAttributes( - new AudioAttributes.Builder() - .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) - .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) - .build() - ).build(); + mAudioFocusRequest = new AudioFocusRequest.Builder(AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) + .setAudioAttributes(new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) + .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) + .build()) + .build(); } public boolean requestAudioFocus() @@ -43,7 +42,8 @@ public class AudioFocusManager { isMusicActive = mAudioManager.isMusicActive(); if (Build.VERSION.SDK_INT < 26) - mAudioManager.requestAudioFocus(mOnFocusChange, AudioManager.STREAM_VOICE_CALL, AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); + mAudioManager.requestAudioFocus(mOnFocusChange, AudioManager.STREAM_VOICE_CALL, + AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK); else mAudioManager.requestAudioFocus(mAudioFocusRequest); } diff --git a/android/app/src/main/java/app/organicmaps/sound/LanguageData.java b/android/app/src/main/java/app/organicmaps/sdk/sound/LanguageData.java similarity index 90% rename from android/app/src/main/java/app/organicmaps/sound/LanguageData.java rename to android/app/src/main/java/app/organicmaps/sdk/sound/LanguageData.java index 6cf8b6281..3dd5d992a 100644 --- a/android/app/src/main/java/app/organicmaps/sound/LanguageData.java +++ b/android/app/src/main/java/app/organicmaps/sdk/sound/LanguageData.java @@ -1,7 +1,6 @@ -package app.organicmaps.sound; +package app.organicmaps.sdk.sound; import android.speech.tts.TextToSpeech; - import java.util.Locale; /** @@ -10,7 +9,8 @@ import java.util.Locale; */ public class LanguageData { - static class NotAvailableException extends Exception { + static class NotAvailableException extends Exception + { NotAvailableException(Locale locale) { super("Locale \"" + locale + "\" is not supported by current TTS engine"); @@ -54,9 +54,7 @@ public class LanguageData { // Chinese is a special case String country = locale.getCountry(); - return "TW".equals(country) || - "MO".equals(country) || - "HK".equals(country); + return "TW".equals(country) || "MO".equals(country) || "HK".equals(country); } return true; diff --git a/android/app/src/main/java/app/organicmaps/sound/MediaPlayerWrapper.java b/android/app/src/main/java/app/organicmaps/sdk/sound/MediaPlayerWrapper.java similarity index 98% rename from android/app/src/main/java/app/organicmaps/sound/MediaPlayerWrapper.java rename to android/app/src/main/java/app/organicmaps/sdk/sound/MediaPlayerWrapper.java index 224309589..401e9394d 100644 --- a/android/app/src/main/java/app/organicmaps/sound/MediaPlayerWrapper.java +++ b/android/app/src/main/java/app/organicmaps/sdk/sound/MediaPlayerWrapper.java @@ -1,9 +1,8 @@ -package app.organicmaps.sound; +package app.organicmaps.sdk.sound; import android.content.Context; import android.media.MediaPlayer; import android.os.AsyncTask; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RawRes; diff --git a/android/app/src/main/java/app/organicmaps/sound/TtsPlayer.java b/android/app/src/main/java/app/organicmaps/sdk/sound/TtsPlayer.java similarity index 86% rename from android/app/src/main/java/app/organicmaps/sound/TtsPlayer.java rename to android/app/src/main/java/app/organicmaps/sdk/sound/TtsPlayer.java index b6eb5b3f9..0fc8a9b6c 100644 --- a/android/app/src/main/java/app/organicmaps/sound/TtsPlayer.java +++ b/android/app/src/main/java/app/organicmaps/sdk/sound/TtsPlayer.java @@ -1,4 +1,4 @@ -package app.organicmaps.sound; +package app.organicmaps.sdk.sound; import android.content.Context; import android.content.res.Resources; @@ -10,15 +10,12 @@ import android.provider.Settings; import android.speech.tts.TextToSpeech; import android.speech.tts.UtteranceProgressListener; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.util.Config; -import app.organicmaps.util.concurrency.UiThread; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.sdk.util.log.Logger; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -31,12 +28,11 @@ import java.util.Locale; * During loading each item in this list is marked as {@code downloaded} or {@code not downloaded}, * unsupported voices are excluded. *

- * At startup we check whether currently selected language is in our list of supported voices and its data is downloaded. - * If not, we check system default locale. If failed, the same check is made for English language. - * Finally, if mentioned checks fail we manually disable TTS, so the user must go to the settings and select - * preferred voice language by hand. - *

- * If no core supported languages can be used by the system, TTS is locked down and can not be enabled and used. + * At startup we check whether currently selected language is in our list of supported voices and its data is + * downloaded. If not, we check system default locale. If failed, the same check is made for English language. Finally, + * if mentioned checks fail we manually disable TTS, so the user must go to the settings and select preferred voice + * language by hand.

If no core supported languages can be used by the system, TTS is locked down and can not be + * enabled and used. */ public enum TtsPlayer { @@ -48,7 +44,7 @@ public enum TtsPlayer private static final int TTS_SPEAK_DELAY_MILLIS = 50; public static Runnable sOnReloadCallback = null; - + private ContentObserver mTtsEngineObserver; private TextToSpeech mTts; private boolean mInitializing; @@ -167,12 +163,14 @@ public enum TtsPlayer mTts.setSpeechRate(SPEECH_RATE); mTts.setOnUtteranceProgressListener(new UtteranceProgressListener() { @Override - public void onStart(String utteranceId) { + public void onStart(String utteranceId) + { mAudioFocusManager.requestAudioFocus(); } @Override - public void onDone(String utteranceId) { + public void onDone(String utteranceId) + { mAudioFocusManager.releaseAudioFocus(); } @@ -184,7 +182,8 @@ public enum TtsPlayer } @Override - public void onError(String utteranceId, int errorCode) { + public void onError(String utteranceId, int errorCode) + { mAudioFocusManager.releaseAudioFocus(); } }); @@ -198,24 +197,24 @@ public enum TtsPlayer } })); - if (mTtsEngineObserver == null) { + if (mTtsEngineObserver == null) + { mTtsEngineObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { @Override - public void onChange(boolean selfChange) { + public void onChange(boolean selfChange) + { Logger.d(TAG, "System TTS engine changed – reloading TTS engine"); mReloadTriggered = true; - if (mTts != null) { + if (mTts != null) + { mTts.shutdown(); mTts = null; } initialize(mContext); } }; - mContext.getContentResolver().registerContentObserver( - Settings.Secure.getUriFor("tts_default_synth"), - false, - mTtsEngineObserver - ); + mContext.getContentResolver().registerContentObserver(Settings.Secure.getUriFor("tts_default_synth"), false, + mTtsEngineObserver); } } @@ -231,7 +230,8 @@ public enum TtsPlayer { boolean isMusicActive = mAudioFocusManager.requestAudioFocus(); if (isMusicActive) - delayHandler.postDelayed(() -> mTts.speak(textToSpeak, TextToSpeech.QUEUE_ADD, mParams, textToSpeak), TTS_SPEAK_DELAY_MILLIS); + delayHandler.postDelayed( + () -> mTts.speak(textToSpeak, TextToSpeech.QUEUE_ADD, mParams, textToSpeak), TTS_SPEAK_DELAY_MILLIS); else mTts.speak(textToSpeak, TextToSpeech.QUEUE_ADD, mParams, textToSpeak); } @@ -286,7 +286,7 @@ public enum TtsPlayer private boolean getUsableLanguages(List outList) { - Resources resources = MwmApplication.from(mContext).getResources(); + Resources resources = mContext.getResources(); String[] codes = resources.getStringArray(R.array.tts_languages_supported); String[] names = resources.getStringArray(R.array.tts_language_names); @@ -296,7 +296,8 @@ public enum TtsPlayer { outList.add(new LanguageData(codes[i], names[i], mTts)); } - catch (LanguageData.NotAvailableException ignored) { + catch (LanguageData.NotAvailableException ignored) + { Logger.w(TAG, "Failed to get usable languages " + ignored.getMessage()); } catch (IllegalArgumentException e) diff --git a/android/app/src/main/java/app/organicmaps/traffxml/AndroidConsumer.java b/android/app/src/main/java/app/organicmaps/sdk/traffxml/AndroidConsumer.java similarity index 96% rename from android/app/src/main/java/app/organicmaps/traffxml/AndroidConsumer.java rename to android/app/src/main/java/app/organicmaps/sdk/traffxml/AndroidConsumer.java index 1b8b19878..b83e845b3 100644 --- a/android/app/src/main/java/app/organicmaps/traffxml/AndroidConsumer.java +++ b/android/app/src/main/java/app/organicmaps/sdk/traffxml/AndroidConsumer.java @@ -4,12 +4,12 @@ * Relicensed to CoMaps by the original author. */ -package app.organicmaps.traffxml; +package app.organicmaps.sdk.traffxml; import java.util.List; -import app.organicmaps.traffxml.Version; -import app.organicmaps.traffxml.AndroidTransport; +import app.organicmaps.sdk.traffxml.Version; +import app.organicmaps.sdk.traffxml.AndroidTransport; import android.content.BroadcastReceiver; import android.content.ComponentName; diff --git a/android/app/src/main/java/app/organicmaps/traffxml/AndroidTransport.java b/android/app/src/main/java/app/organicmaps/sdk/traffxml/AndroidTransport.java similarity index 99% rename from android/app/src/main/java/app/organicmaps/traffxml/AndroidTransport.java rename to android/app/src/main/java/app/organicmaps/sdk/traffxml/AndroidTransport.java index abb69d965..93c1f4b0c 100644 --- a/android/app/src/main/java/app/organicmaps/traffxml/AndroidTransport.java +++ b/android/app/src/main/java/app/organicmaps/sdk/traffxml/AndroidTransport.java @@ -4,7 +4,7 @@ * Relicensed to CoMaps by the original author. */ -package app.organicmaps.traffxml; +package app.organicmaps.sdk.traffxml; public class AndroidTransport { /** diff --git a/android/app/src/main/java/app/organicmaps/traffxml/SourceImpl.java b/android/app/src/main/java/app/organicmaps/sdk/traffxml/SourceImpl.java similarity index 97% rename from android/app/src/main/java/app/organicmaps/traffxml/SourceImpl.java rename to android/app/src/main/java/app/organicmaps/sdk/traffxml/SourceImpl.java index 9ef6e55e8..6fa6a18c4 100644 --- a/android/app/src/main/java/app/organicmaps/traffxml/SourceImpl.java +++ b/android/app/src/main/java/app/organicmaps/sdk/traffxml/SourceImpl.java @@ -1,4 +1,4 @@ -package app.organicmaps.traffxml; +package app.organicmaps.sdk.traffxml; import android.content.BroadcastReceiver; import android.content.Context; diff --git a/android/app/src/main/java/app/organicmaps/traffxml/SourceImplV0_7.java b/android/app/src/main/java/app/organicmaps/sdk/traffxml/SourceImplV0_7.java similarity index 97% rename from android/app/src/main/java/app/organicmaps/traffxml/SourceImplV0_7.java rename to android/app/src/main/java/app/organicmaps/sdk/traffxml/SourceImplV0_7.java index 981e2affc..cff6d0d75 100644 --- a/android/app/src/main/java/app/organicmaps/traffxml/SourceImplV0_7.java +++ b/android/app/src/main/java/app/organicmaps/sdk/traffxml/SourceImplV0_7.java @@ -1,4 +1,4 @@ -package app.organicmaps.traffxml; +package app.organicmaps.sdk.traffxml; import java.util.ArrayList; import java.util.List; @@ -10,7 +10,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.util.log.Logger; /** * Implementation for a TraFF 0.7 source. diff --git a/android/app/src/main/java/app/organicmaps/traffxml/SourceImplV0_8.java b/android/app/src/main/java/app/organicmaps/sdk/traffxml/SourceImplV0_8.java similarity index 99% rename from android/app/src/main/java/app/organicmaps/traffxml/SourceImplV0_8.java rename to android/app/src/main/java/app/organicmaps/sdk/traffxml/SourceImplV0_8.java index 753875ec1..2518525ea 100644 --- a/android/app/src/main/java/app/organicmaps/traffxml/SourceImplV0_8.java +++ b/android/app/src/main/java/app/organicmaps/sdk/traffxml/SourceImplV0_8.java @@ -1,4 +1,4 @@ -package app.organicmaps.traffxml; +package app.organicmaps.sdk.traffxml; import android.Manifest; import android.content.Context; @@ -8,7 +8,7 @@ import android.content.IntentFilter.MalformedMimeTypeException; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.util.log.Logger; /** * Implementation for a TraFF 0.8 source. diff --git a/android/app/src/main/java/app/organicmaps/traffxml/Version.java b/android/app/src/main/java/app/organicmaps/sdk/traffxml/Version.java similarity index 90% rename from android/app/src/main/java/app/organicmaps/traffxml/Version.java rename to android/app/src/main/java/app/organicmaps/sdk/traffxml/Version.java index 8f3587ea0..c2603b2ec 100644 --- a/android/app/src/main/java/app/organicmaps/traffxml/Version.java +++ b/android/app/src/main/java/app/organicmaps/sdk/traffxml/Version.java @@ -4,7 +4,7 @@ * Relicensed to CoMaps by the original author. */ -package app.organicmaps.traffxml; +package app.organicmaps.sdk.traffxml; /** * Constants for versions. diff --git a/android/app/src/main/java/app/organicmaps/util/BatteryState.java b/android/app/src/main/java/app/organicmaps/sdk/util/BatteryState.java similarity index 83% rename from android/app/src/main/java/app/organicmaps/util/BatteryState.java rename to android/app/src/main/java/app/organicmaps/sdk/util/BatteryState.java index e1d819988..f6fe33387 100644 --- a/android/app/src/main/java/app/organicmaps/util/BatteryState.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/BatteryState.java @@ -1,17 +1,13 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.BatteryManager; - import androidx.annotation.IntDef; import androidx.annotation.IntRange; import androidx.annotation.Keep; import androidx.annotation.NonNull; - -import app.organicmaps.MwmApplication; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -22,8 +18,9 @@ public final class BatteryState public static final byte CHARGING_STATUS_UNPLUGGED = 2; @Retention(RetentionPolicy.SOURCE) - @IntDef({ CHARGING_STATUS_UNKNOWN, CHARGING_STATUS_PLUGGED, CHARGING_STATUS_UNPLUGGED }) - public @interface ChargingStatus {} + @IntDef({CHARGING_STATUS_UNKNOWN, CHARGING_STATUS_PLUGGED, CHARGING_STATUS_UNPLUGGED}) + public @interface ChargingStatus + {} private BatteryState() {} @@ -33,7 +30,7 @@ public final class BatteryState IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); // Because it's a sticky intent, you don't need to register a BroadcastReceiver // by simply calling registerReceiver passing in null - Intent batteryStatus = MwmApplication.from(context).registerReceiver(null, filter); + Intent batteryStatus = context.getApplicationContext().registerReceiver(null, filter); if (batteryStatus == null) return new State(0, CHARGING_STATUS_UNKNOWN); @@ -43,13 +40,13 @@ public final class BatteryState // Called from JNI. @Keep @SuppressWarnings("unused") - @IntRange(from=0, to=100) + @IntRange(from = 0, to = 100) public static int getLevel(@NonNull Context context) { return getState(context).getLevel(); } - @IntRange(from=0, to=100) + @IntRange(from = 0, to = 100) private static int getLevel(@NonNull Intent batteryStatus) { return batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, 0); @@ -82,19 +79,19 @@ public final class BatteryState public static final class State { - @IntRange(from=0, to=100) + @IntRange(from = 0, to = 100) private final int mLevel; @ChargingStatus private final int mChargingStatus; - public State(@IntRange(from=0, to=100) int level, @ChargingStatus int chargingStatus) + public State(@IntRange(from = 0, to = 100) int level, @ChargingStatus int chargingStatus) { mLevel = level; mChargingStatus = chargingStatus; } - @IntRange(from=0, to=100) + @IntRange(from = 0, to = 100) public int getLevel() { return mLevel; diff --git a/android/app/src/main/java/app/organicmaps/util/ClientCertTLSSocketFactory.java b/android/app/src/main/java/app/organicmaps/sdk/util/ClientCertTLSSocketFactory.java similarity index 97% rename from android/app/src/main/java/app/organicmaps/util/ClientCertTLSSocketFactory.java rename to android/app/src/main/java/app/organicmaps/sdk/util/ClientCertTLSSocketFactory.java index 43abb72c0..c9e0f7054 100644 --- a/android/app/src/main/java/app/organicmaps/util/ClientCertTLSSocketFactory.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/ClientCertTLSSocketFactory.java @@ -1,13 +1,11 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import java.io.ByteArrayInputStream; import java.io.InputStream; import java.security.KeyStore; import java.security.SecureRandom; - import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; diff --git a/android/app/src/main/java/app/organicmaps/util/Config.java b/android/app/src/main/java/app/organicmaps/sdk/util/Config.java similarity index 92% rename from android/app/src/main/java/app/organicmaps/util/Config.java rename to android/app/src/main/java/app/organicmaps/sdk/util/Config.java index 06fcb6c85..e700cf11a 100644 --- a/android/app/src/main/java/app/organicmaps/util/Config.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/Config.java @@ -1,17 +1,20 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.content.Context; import android.content.SharedPreferences; import android.os.Build; - import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; import app.organicmaps.BuildConfig; -import app.organicmaps.MwmApplication; import app.organicmaps.R; +import app.organicmaps.util.ThemeUtils; public final class Config { + @SuppressWarnings("NotNullFieldNotInitialized") + @NonNull + private static SharedPreferences mPrefs; + private static final String KEY_APP_STORAGE = "StoragePath"; private static final String KEY_DOWNLOADER_AUTO = "AutoDownloadEnabled"; @@ -229,8 +232,8 @@ public final class Config public static String getCurrentUiTheme(@NonNull Context context) { // This is the actual map theme, only set to theme_default/night - String defaultTheme = MwmApplication.from(context).getString(R.string.theme_default); - String res = getString(KEY_MISC_UI_THEME, defaultTheme); + final String defaultTheme = context.getString(R.string.theme_default); + final String res = getString(KEY_MISC_UI_THEME, defaultTheme); if (ThemeUtils.isValidTheme(context, res)) return res; @@ -250,9 +253,10 @@ public final class Config public static String getUiThemeSettings(@NonNull Context context) { // This is the default theme *mode*, eg. auto/dark/nav_auto/light. - String defaultSetting = MwmApplication.from(context).getString(R.string.theme_nav_auto); - String res = getString(KEY_MISC_UI_THEME_SETTINGS, defaultSetting); - if (ThemeUtils.isValidTheme(context, res) || ThemeUtils.isAutoTheme(context, res) || ThemeUtils.isNavAutoTheme(context, res)) + final String defaultSetting = context.getString(R.string.theme_nav_auto); + final String res = getString(KEY_MISC_UI_THEME_SETTINGS, defaultSetting); + if (ThemeUtils.isValidTheme(context, res) || ThemeUtils.isAutoTheme(context, res) + || ThemeUtils.isNavAutoTheme(context, res)) return res; return defaultSetting; @@ -392,25 +396,25 @@ public final class Config { final String url = getString(KEY_DONATE_URL); // Enable donations by default if not Google or Huawei. Replace comaps.app/donate/ with localized page. - if ((url.isEmpty() && !BuildConfig.FLAVOR.equals("google") && !BuildConfig.FLAVOR.equals("huawei")) || - url.endsWith("comaps.app/donate/")) + if ((url.isEmpty() && !BuildConfig.FLAVOR.equals("google") && !BuildConfig.FLAVOR.equals("huawei")) + || url.endsWith("comaps.app/donate/")) return context.getString(R.string.app_site_url) + "donate/"; return url; } - public static void init(@NonNull Context context) + public static void init(@NonNull Context context, @NonNull SharedPreferences prefs) { PreferenceManager.setDefaultValues(context, R.xml.prefs_main, false); - final SharedPreferences prefs = MwmApplication.prefs(context); - final SharedPreferences.Editor editor = prefs.edit(); + mPrefs = prefs; + final SharedPreferences.Editor editor = mPrefs.edit(); // Update counters. - final int launchNumber = prefs.getInt(KEY_APP_LAUNCH_NUMBER, 0); + final int launchNumber = mPrefs.getInt(KEY_APP_LAUNCH_NUMBER, 0); editor.putInt(KEY_APP_LAUNCH_NUMBER, launchNumber + 1); editor.putLong(KEY_APP_LAST_SESSION_TIMESTAMP, System.currentTimeMillis()); editor.putInt(KEY_APP_LAST_INSTALL_VERSION_CODE, BuildConfig.VERSION_CODE); - if (launchNumber == 0 || prefs.getInt(KEY_APP_FIRST_INSTALL_VERSION_CODE, 0) == 0) + if (launchNumber == 0 || mPrefs.getInt(KEY_APP_FIRST_INSTALL_VERSION_CODE, 0) == 0) editor.putInt(KEY_APP_FIRST_INSTALL_VERSION_CODE, BuildConfig.VERSION_CODE); // Clean up legacy counters. @@ -433,15 +437,12 @@ public final class Config public static boolean isFirstLaunch(@NonNull Context context) { - return !MwmApplication.prefs(context).getBoolean(KEY_MISC_FIRST_START_DIALOG_SEEN, false); + return !mPrefs.getBoolean(KEY_MISC_FIRST_START_DIALOG_SEEN, false); } public static void setFirstStartDialogSeen(@NonNull Context context) { - MwmApplication.prefs(context) - .edit() - .putBoolean(KEY_MISC_FIRST_START_DIALOG_SEEN, true) - .apply(); + mPrefs.edit().putBoolean(KEY_MISC_FIRST_START_DIALOG_SEEN, true).apply(); } public static boolean isSearchHistoryEnabled() @@ -515,7 +516,6 @@ public final class Config { setBool(Keys.STREETS, enabled); } - } private static native boolean nativeHasConfigValue(String name); diff --git a/android/app/src/main/java/app/organicmaps/util/ConnectionState.java b/android/app/src/main/java/app/organicmaps/sdk/util/ConnectionState.java similarity index 92% rename from android/app/src/main/java/app/organicmaps/util/ConnectionState.java rename to android/app/src/main/java/app/organicmaps/sdk/util/ConnectionState.java index 07af068c1..6cac6f44d 100644 --- a/android/app/src/main/java/app/organicmaps/util/ConnectionState.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/ConnectionState.java @@ -1,11 +1,10 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; -import static app.organicmaps.util.ConnectionState.Type.NONE; +import static app.organicmaps.sdk.util.ConnectionState.Type.NONE; import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; - import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -62,8 +61,7 @@ public enum ConnectionState @Nullable public NetworkInfo getActiveNetwork() { - ConnectivityManager manager = - ((ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE)); + ConnectivityManager manager = ((ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE)); if (manager == null) return null; diff --git a/android/app/src/main/java/app/organicmaps/util/Constants.java b/android/app/src/main/java/app/organicmaps/sdk/util/Constants.java similarity index 98% rename from android/app/src/main/java/app/organicmaps/util/Constants.java rename to android/app/src/main/java/app/organicmaps/sdk/util/Constants.java index 2efb04472..d8d49111f 100644 --- a/android/app/src/main/java/app/organicmaps/util/Constants.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/Constants.java @@ -1,4 +1,4 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import app.organicmaps.BuildConfig; diff --git a/android/app/src/main/java/app/organicmaps/util/DateUtils.java b/android/app/src/main/java/app/organicmaps/sdk/util/DateUtils.java similarity index 89% rename from android/app/src/main/java/app/organicmaps/util/DateUtils.java rename to android/app/src/main/java/app/organicmaps/sdk/util/DateUtils.java index 82a8c4775..028c9015f 100644 --- a/android/app/src/main/java/app/organicmaps/util/DateUtils.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/DateUtils.java @@ -1,18 +1,14 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.content.Context; - import androidx.annotation.Keep; import androidx.annotation.NonNull; - import java.text.DateFormat; import java.util.Locale; public final class DateUtils { - private DateUtils() - { - } + private DateUtils() {} @NonNull public static DateFormat getShortDateFormatter() diff --git a/android/app/src/main/java/app/organicmaps/util/Distance.java b/android/app/src/main/java/app/organicmaps/sdk/util/Distance.java similarity index 98% rename from android/app/src/main/java/app/organicmaps/util/Distance.java rename to android/app/src/main/java/app/organicmaps/sdk/util/Distance.java index 0848fb9bf..a846e16ff 100644 --- a/android/app/src/main/java/app/organicmaps/util/Distance.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/Distance.java @@ -1,11 +1,9 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.content.Context; - import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.StringRes; - import app.organicmaps.R; // Used by JNI. diff --git a/android/app/src/main/java/app/organicmaps/util/GeoUtils.java b/android/app/src/main/java/app/organicmaps/sdk/util/GeoUtils.java similarity index 75% rename from android/app/src/main/java/app/organicmaps/util/GeoUtils.java rename to android/app/src/main/java/app/organicmaps/sdk/util/GeoUtils.java index 8155ec9ae..7b7318aff 100644 --- a/android/app/src/main/java/app/organicmaps/util/GeoUtils.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/GeoUtils.java @@ -1,8 +1,7 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import androidx.annotation.NonNull; - -import app.organicmaps.bookmarks.data.ParcelablePointD; +import app.organicmaps.sdk.bookmarks.data.ParcelablePointD; public class GeoUtils { diff --git a/android/app/src/main/java/app/organicmaps/util/HttpClient.java b/android/app/src/main/java/app/organicmaps/sdk/util/HttpClient.java similarity index 90% rename from android/app/src/main/java/app/organicmaps/util/HttpClient.java rename to android/app/src/main/java/app/organicmaps/sdk/util/HttpClient.java index 256f76d41..9c10ebd6d 100644 --- a/android/app/src/main/java/app/organicmaps/util/HttpClient.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/HttpClient.java @@ -22,16 +22,13 @@ * SOFTWARE. *******************************************************************************/ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.text.TextUtils; - import androidx.annotation.Keep; import androidx.annotation.NonNull; - -import app.organicmaps.downloader.Android7RootCertificateWorkaround; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.downloader.Android7RootCertificateWorkaround; +import app.organicmaps.sdk.util.log.Logger; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayOutputStream; @@ -77,11 +74,11 @@ public final class HttpClient // NullPointerException, MalformedUrlException, IOException // Redirects from http to https or vice versa are not supported by Android implementation. // There is also a nasty bug on Androids before 4.4: - // if you send any request with Content-Length set, and it is redirected, and your instance is set to automatically follow redirects, - // then next (internal) GET request to redirected location will incorrectly have have all headers set from the previous request, - // including Content-Length, Content-Type etc. This leads to unexpected hangs and timeout errors, because some servers are - // correctly trying to wait for the body if Content-Length is set. - // It shows in logs like this: + // if you send any request with Content-Length set, and it is redirected, and your instance is set to + // automatically follow redirects, then next (internal) GET request to redirected location will incorrectly have + // have all headers set from the previous request, including Content-Length, Content-Type etc. This leads to + // unexpected hangs and timeout errors, because some servers are correctly trying to wait for the body if + // Content-Length is set. It shows in logs like this: // // java.net.SocketTimeoutException: Read timed out // at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_read(Native Method) @@ -127,7 +124,8 @@ public final class HttpClient final File file = new File(p.inputFilePath); connection.setFixedLengthStreamingMode((int) file.length()); final BufferedInputStream istream = new BufferedInputStream(new FileInputStream(file), STREAM_BUFFER_SIZE); - final BufferedOutputStream ostream = new BufferedOutputStream(connection.getOutputStream(), STREAM_BUFFER_SIZE); + final BufferedOutputStream ostream = + new BufferedOutputStream(connection.getOutputStream(), STREAM_BUFFER_SIZE); final byte[] buffer = new byte[STREAM_BUFFER_SIZE]; int bytesRead; while ((bytesRead = istream.read(buffer, 0, STREAM_BUFFER_SIZE)) > 0) @@ -141,8 +139,8 @@ public final class HttpClient } // GET data from the server or receive response body p.httpResponseCode = connection.getResponseCode(); - Logger.d(TAG, "Received HTTP " + p.httpResponseCode + " from server, content encoding = " + - connection.getContentEncoding() + ", for request = " + Utils.makeUrlSafe(p.url)); + Logger.d(TAG, "Received HTTP " + p.httpResponseCode + " from server, content encoding = " + + connection.getContentEncoding() + ", for request = " + Utils.makeUrlSafe(p.url)); if (p.httpResponseCode >= 300 && p.httpResponseCode < 400) p.receivedUrl = connection.getHeaderField("Location"); @@ -158,8 +156,8 @@ public final class HttpClient if (header.getKey() == null || header.getValue() == null) continue; - p.headers.add(new KeyValue(StringUtils.toLowerCase(header.getKey()), TextUtils.join(", ", - header.getValue()))); + p.headers.add( + new KeyValue(StringUtils.toLowerCase(header.getKey()), TextUtils.join(", ", header.getValue()))); } } else @@ -182,7 +180,8 @@ public final class HttpClient // gzip encoding is transparently enabled and we can't use Content-Length for // body reading if server has gzipped it. int bytesRead; - while ((bytesRead = istream.read(buffer, 0, STREAM_BUFFER_SIZE)) > 0) { + while ((bytesRead = istream.read(buffer, 0, STREAM_BUFFER_SIZE)) > 0) + { // Read everything if Content-Length is not known in advance. ostream.write(buffer, 0, bytesRead); } diff --git a/android/app/src/main/java/app/organicmaps/util/KeyValue.java b/android/app/src/main/java/app/organicmaps/sdk/util/KeyValue.java similarity index 89% rename from android/app/src/main/java/app/organicmaps/util/KeyValue.java rename to android/app/src/main/java/app/organicmaps/sdk/util/KeyValue.java index 50cf3859e..cdde4abe9 100644 --- a/android/app/src/main/java/app/organicmaps/util/KeyValue.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/KeyValue.java @@ -1,8 +1,8 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import androidx.annotation.Keep; import androidx.annotation.NonNull; - +import java.io.Serial; import java.io.Serializable; // Used from JNI. @@ -10,6 +10,7 @@ import java.io.Serializable; @SuppressWarnings("unused") public final class KeyValue implements Serializable { + @Serial private static final long serialVersionUID = -3079360274128509979L; @NonNull private final String mKey; diff --git a/android/app/src/main/java/app/organicmaps/util/Language.java b/android/app/src/main/java/app/organicmaps/sdk/util/Language.java similarity index 91% rename from android/app/src/main/java/app/organicmaps/util/Language.java rename to android/app/src/main/java/app/organicmaps/sdk/util/Language.java index 4a367ded7..e814eb4d3 100644 --- a/android/app/src/main/java/app/organicmaps/util/Language.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/Language.java @@ -1,13 +1,11 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.content.Context; import android.text.TextUtils; import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodSubtype; - import androidx.annotation.Keep; import androidx.annotation.NonNull; - import java.util.Locale; public class Language @@ -40,8 +38,7 @@ public class Language @NonNull public static String getKeyboardLocale(@NonNull Context context) { - InputMethodManager imm = (InputMethodManager) context - .getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); if (imm == null) return getDefaultLocale(); diff --git a/android/app/src/main/java/app/organicmaps/util/LocationUtils.java b/android/app/src/main/java/app/organicmaps/sdk/util/LocationUtils.java similarity index 98% rename from android/app/src/main/java/app/organicmaps/util/LocationUtils.java rename to android/app/src/main/java/app/organicmaps/sdk/util/LocationUtils.java index 735b427ef..85d947ec9 100644 --- a/android/app/src/main/java/app/organicmaps/util/LocationUtils.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/LocationUtils.java @@ -1,4 +1,4 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.Manifest.permission.ACCESS_FINE_LOCATION; @@ -10,7 +10,6 @@ import android.location.LocationManager; import android.os.Build; import android.provider.Settings; import android.view.Surface; - import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; @@ -107,7 +106,7 @@ public class LocationUtils try { return Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE) - != Settings.Secure.LOCATION_MODE_OFF; + != Settings.Secure.LOCATION_MODE_OFF; } catch (Settings.SettingNotFoundException e) { diff --git a/android/app/src/main/java/app/organicmaps/util/NetworkPolicy.java b/android/app/src/main/java/app/organicmaps/sdk/util/NetworkPolicy.java similarity index 54% rename from android/app/src/main/java/app/organicmaps/util/NetworkPolicy.java rename to android/app/src/main/java/app/organicmaps/sdk/util/NetworkPolicy.java index 8583fb320..fc0f4ac0c 100644 --- a/android/app/src/main/java/app/organicmaps/util/NetworkPolicy.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/NetworkPolicy.java @@ -1,11 +1,9 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentManager; - import app.organicmaps.widget.StackedButtonDialogFragment; - import java.util.concurrent.TimeUnit; @Keep @@ -15,81 +13,73 @@ public final class NetworkPolicy { ASK, - ALWAYS() - { - @Override - public void check(@NonNull FragmentManager fragmentManager, - @NonNull NetworkPolicyListener listener, boolean isDialogAllowed) - { - boolean nowInRoaming = ConnectionState.INSTANCE.isInRoaming(); - boolean acceptedInRoaming = Config.getMobileDataRoaming(); + ALWAYS() { + @Override + public void check(@NonNull FragmentManager fragmentManager, @NonNull NetworkPolicyListener listener, + boolean isDialogAllowed) + { + boolean nowInRoaming = ConnectionState.INSTANCE.isInRoaming(); + boolean acceptedInRoaming = Config.getMobileDataRoaming(); - if (nowInRoaming && !acceptedInRoaming) - showDialog(fragmentManager, listener); - else - listener.onResult(new NetworkPolicy(true)); - } - }, + if (nowInRoaming && !acceptedInRoaming) + showDialog(fragmentManager, listener); + else + listener.onResult(new NetworkPolicy(true)); + } + }, - NEVER() - { - @Override - public void check(@NonNull FragmentManager fragmentManager, - @NonNull NetworkPolicyListener listener, boolean isDialogAllowed) - { - if (isDialogAllowed) - showDialog(fragmentManager, listener); - else - listener.onResult(new NetworkPolicy(false)); - } - }, + NEVER() { + @Override + public void check(@NonNull FragmentManager fragmentManager, @NonNull NetworkPolicyListener listener, + boolean isDialogAllowed) + { + if (isDialogAllowed) + showDialog(fragmentManager, listener); + else + listener.onResult(new NetworkPolicy(false)); + } + }, + NOT_TODAY() { + @Override + public void check(@NonNull FragmentManager fragmentManager, @NonNull NetworkPolicyListener listener, + boolean isDialogAllowed) + { + if (isDialogAllowed) + showDialog(fragmentManager, listener); + else + showDialogIfNeeded(fragmentManager, listener, new NetworkPolicy(false)); + } + }, - NOT_TODAY() - { - @Override - public void check(@NonNull FragmentManager fragmentManager, - @NonNull NetworkPolicyListener listener, boolean isDialogAllowed) - { - if (isDialogAllowed) - showDialog(fragmentManager, listener); - else - showDialogIfNeeded(fragmentManager, listener, new NetworkPolicy(false)); - } - }, + TODAY() { + @Override + public void check(@NonNull FragmentManager fragmentManager, @NonNull NetworkPolicyListener listener, + boolean isDialogAllowed) + { + boolean nowInRoaming = ConnectionState.INSTANCE.isInRoaming(); + boolean acceptedInRoaming = Config.getMobileDataRoaming(); - TODAY() - { - @Override - public void check(@NonNull FragmentManager fragmentManager, - @NonNull NetworkPolicyListener listener, boolean isDialogAllowed) - { - boolean nowInRoaming = ConnectionState.INSTANCE.isInRoaming(); - boolean acceptedInRoaming = Config.getMobileDataRoaming(); + if (nowInRoaming && !acceptedInRoaming) + showDialog(fragmentManager, listener); + else + showDialogIfNeeded(fragmentManager, listener, new NetworkPolicy(true)); + } + }; - if (nowInRoaming && !acceptedInRoaming) - showDialog(fragmentManager, listener); - else - showDialogIfNeeded(fragmentManager, listener, new NetworkPolicy(true)); - } - }; - - public void check(@NonNull FragmentManager fragmentManager, - @NonNull final NetworkPolicyListener listener, + public void check(@NonNull FragmentManager fragmentManager, @NonNull final NetworkPolicyListener listener, boolean isDialogAllowed) { showDialog(fragmentManager, listener); } } - public static final int NONE = -1; private static final String TAG_NETWORK_POLICY = "network_policy"; public static void checkNetworkPolicy(@NonNull FragmentManager fragmentManager, - @NonNull final NetworkPolicyListener listener, - boolean isDialogAllowed) + @NonNull final NetworkPolicyListener listener, boolean isDialogAllowed) { if (ConnectionState.INSTANCE.isWifiConnected()) { @@ -140,8 +130,7 @@ public final class NetworkPolicy } private static void showDialogIfNeeded(@NonNull FragmentManager fragmentManager, - @NonNull NetworkPolicyListener listener, - @NonNull NetworkPolicy policy) + @NonNull NetworkPolicyListener listener, @NonNull NetworkPolicy policy) { if (isToday()) { @@ -151,11 +140,10 @@ public final class NetworkPolicy showDialog(fragmentManager, listener); } - private static void showDialog(@NonNull FragmentManager fragmentManager, - @NonNull NetworkPolicyListener listener) + private static void showDialog(@NonNull FragmentManager fragmentManager, @NonNull NetworkPolicyListener listener) { - StackedButtonDialogFragment dialog = (StackedButtonDialogFragment) fragmentManager - .findFragmentByTag(TAG_NETWORK_POLICY); + StackedButtonDialogFragment dialog = + (StackedButtonDialogFragment) fragmentManager.findFragmentByTag(TAG_NETWORK_POLICY); if (dialog != null) dialog.dismiss(); diff --git a/android/app/src/main/java/app/organicmaps/util/PowerManagment.java b/android/app/src/main/java/app/organicmaps/sdk/util/PowerManagment.java similarity index 85% rename from android/app/src/main/java/app/organicmaps/util/PowerManagment.java rename to android/app/src/main/java/app/organicmaps/sdk/util/PowerManagment.java index 2a443d8b5..7fd1daeb5 100644 --- a/android/app/src/main/java/app/organicmaps/util/PowerManagment.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/PowerManagment.java @@ -1,4 +1,7 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; + +import static app.organicmaps.sdk.util.Constants.Vendor.HUAWEI; +import static app.organicmaps.sdk.util.Constants.Vendor.XIAOMI; import android.content.ComponentName; import android.content.Context; @@ -6,19 +9,13 @@ import android.content.Intent; import android.os.Build; import android.os.PowerManager; import android.provider.Settings; - import androidx.annotation.IntDef; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import app.organicmaps.Framework; - +import app.organicmaps.sdk.Framework; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import static app.organicmaps.util.Constants.Vendor.HUAWEI; -import static app.organicmaps.util.Constants.Vendor.XIAOMI; - public final class PowerManagment { public static final String POWER_MANAGEMENT_TAG = PowerManagment.class.getName(); @@ -32,10 +29,9 @@ public final class PowerManagment public static final int AUTO = 4; @Retention(RetentionPolicy.SOURCE) - @IntDef({ NONE, NORMAL, MEDIUM, HIGH, AUTO }) + @IntDef({NONE, NORMAL, MEDIUM, HIGH, AUTO}) public @interface SchemeType - { - } + {} @SchemeType public static int getScheme() @@ -54,15 +50,13 @@ public final class PowerManagment { final String XIAOMI_SETTING_NAME = "POWER_SAVE_MODE_OPEN"; final int XIAOMI_SETTING_VALUE = 1; - return Settings.System.getInt(context.getContentResolver(), XIAOMI_SETTING_NAME, -1) - == XIAOMI_SETTING_VALUE; + return Settings.System.getInt(context.getContentResolver(), XIAOMI_SETTING_NAME, -1) == XIAOMI_SETTING_VALUE; } else if (HUAWEI.equalsIgnoreCase(Build.MANUFACTURER)) { final String HUAWEI_SETTING_NAME = "SmartModeStatus"; final int HUAWEI_SETTING_VALUE = 4; - return Settings.System.getInt(context.getContentResolver(), HUAWEI_SETTING_NAME, -1) - == HUAWEI_SETTING_VALUE; + return Settings.System.getInt(context.getContentResolver(), HUAWEI_SETTING_NAME, -1) == HUAWEI_SETTING_VALUE; } final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); @@ -78,8 +72,7 @@ public final class PowerManagment if (XIAOMI.equalsIgnoreCase(Build.MANUFACTURER)) { final Intent intent = new Intent(); - intent.setComponent(new ComponentName("com.miui.securitycenter", - "com.miui.powercenter.PowerMainActivity")); + intent.setComponent(new ComponentName("com.miui.securitycenter", "com.miui.powercenter.PowerMainActivity")); if (Utils.isIntentSupported(context, intent)) return intent; } diff --git a/android/app/src/main/java/app/organicmaps/util/ROMUtils.java b/android/app/src/main/java/app/organicmaps/sdk/util/ROMUtils.java similarity index 85% rename from android/app/src/main/java/app/organicmaps/util/ROMUtils.java rename to android/app/src/main/java/app/organicmaps/sdk/util/ROMUtils.java index 7a0ac7ba8..3d5cc4465 100644 --- a/android/app/src/main/java/app/organicmaps/util/ROMUtils.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/ROMUtils.java @@ -1,7 +1,6 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.util.Log; - import java.lang.reflect.Method; public class ROMUtils @@ -26,9 +25,9 @@ public class ROMUtils // Check common custom ROM properties String[] customROMIndicators = { - "ro.modversion", - "ro.cm.version", // LineageOS/CyanogenMod-specific - "ro.lineage.build.version", // LineageOS + "ro.modversion", + "ro.cm.version", // LineageOS/CyanogenMod-specific + "ro.lineage.build.version", // LineageOS }; for (String prop : customROMIndicators) diff --git a/android/app/src/main/java/app/organicmaps/util/SecureStorage.java b/android/app/src/main/java/app/organicmaps/sdk/util/SecureStorage.java similarity index 94% rename from android/app/src/main/java/app/organicmaps/util/SecureStorage.java rename to android/app/src/main/java/app/organicmaps/sdk/util/SecureStorage.java index 426002008..67a3b247e 100644 --- a/android/app/src/main/java/app/organicmaps/util/SecureStorage.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/SecureStorage.java @@ -1,12 +1,11 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.content.Context; import android.content.SharedPreferences; - import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import app.organicmaps.util.log.Logger; +import app.organicmaps.sdk.util.log.Logger; public final class SecureStorage { diff --git a/android/app/src/main/java/app/organicmaps/sdk/util/SharedPropertiesUtils.java b/android/app/src/main/java/app/organicmaps/sdk/util/SharedPropertiesUtils.java new file mode 100644 index 000000000..6a28b6163 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/util/SharedPropertiesUtils.java @@ -0,0 +1,78 @@ +package app.organicmaps.sdk.util; + +import static app.organicmaps.sdk.util.Config.KEY_PREF_STATISTICS; + +import android.content.Context; +import android.content.SharedPreferences; +import androidx.annotation.NonNull; +import app.organicmaps.R; +import app.organicmaps.sdk.maplayer.Mode; +import java.io.IOException; +import java.util.Locale; + +public final class SharedPropertiesUtils +{ + private static final String PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING = "ShowEmulateBadStorageSetting"; + private static final String PREFS_SHOULD_SHOW_LAYER_MARKER_FOR = "ShouldShowGuidesLayerMarkerFor"; + + @SuppressWarnings("NotNullFieldNotInitialized") + @NonNull + private static SharedPreferences mPrefs; + + // Utils class + private SharedPropertiesUtils() + { + throw new IllegalStateException("Try instantiate utility class SharedPropertiesUtils"); + } + + public static void init(@NonNull SharedPreferences prefs) + { + mPrefs = prefs; + } + + public static boolean isStatisticsEnabled() + { + return mPrefs.getBoolean(KEY_PREF_STATISTICS, true); + } + + public static void setShouldShowEmulateBadStorageSetting(boolean show) + { + mPrefs.edit().putBoolean(PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING, show).apply(); + } + + public static boolean shouldShowEmulateBadStorageSetting() + { + return mPrefs.getBoolean(PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING, false); + } + + /** + * @param context context + * @throws IOException if "Emulate bad storage" is enabled in preferences + */ + public static void emulateBadExternalStorage(@NonNull Context context) throws IOException + { + final String key = context.getString(R.string.pref_emulate_bad_external_storage); + if (mPrefs.getBoolean(key, false)) + { + // Emulate one time only -> reset setting to run normally next time. + mPrefs.edit().putBoolean(key, false).apply(); + throw new IOException("Bad external storage error injection"); + } + } + + public static boolean shouldShowNewMarkerForLayerMode(@NonNull Mode mode) + { + return switch (mode) + { + case SUBWAY, TRAFFIC, ISOLINES -> false; + default -> mPrefs.getBoolean(PREFS_SHOULD_SHOW_LAYER_MARKER_FOR + mode.name().toLowerCase(Locale.ENGLISH), true); + }; + } + + public static void setLayerMarkerShownForLayerMode(@NonNull Mode mode) + { + mPrefs.edit() + .putBoolean(PREFS_SHOULD_SHOW_LAYER_MARKER_FOR + mode.name().toLowerCase(Locale.ENGLISH), false) + .apply(); + } +} diff --git a/android/app/src/main/java/app/organicmaps/util/StorageUtils.java b/android/app/src/main/java/app/organicmaps/sdk/util/StorageUtils.java similarity index 86% rename from android/app/src/main/java/app/organicmaps/util/StorageUtils.java rename to android/app/src/main/java/app/organicmaps/sdk/util/StorageUtils.java index 7c40483e9..15eb6fbbc 100644 --- a/android/app/src/main/java/app/organicmaps/util/StorageUtils.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/StorageUtils.java @@ -1,4 +1,4 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.app.Activity; import android.content.ContentResolver; @@ -7,15 +7,12 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.net.Uri; import android.provider.DocumentsContract; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.FileProvider; import androidx.documentfile.provider.DocumentFile; - import app.organicmaps.BuildConfig; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.util.log.Logger; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -27,7 +24,6 @@ import java.util.ArrayList; import java.util.Queue; import java.util.concurrent.LinkedBlockingQueue; - public class StorageUtils { private static final String TAG = StorageUtils.class.getSimpleName(); @@ -154,18 +150,10 @@ public class StorageUtils @NonNull public static Uri getUriForFilePath(@NonNull Context context, @NonNull String path) { - return FileProvider.getUriForFile(context.getApplicationContext(), - BuildConfig.FILE_PROVIDER_AUTHORITY, new File(path)); + return FileProvider.getUriForFile(context.getApplicationContext(), BuildConfig.FILE_PROVIDER_AUTHORITY, + new File(path)); } - /** - * Copy data from a URI into a local file. - * @param resolver content resolver - * @param from a source URI. - * @param to a destination file - * @return true on success and false if the provider recently crashed. - * @throws IOException - if I/O error occurs. - */ static private boolean copyFile(InputStream from, OutputStream to) throws IOException { if (from == null || to == null) @@ -178,7 +166,17 @@ public class StorageUtils return true; } - public static boolean copyFile(@NonNull ContentResolver resolver, @NonNull Uri from, @NonNull File to) throws IOException + + /** + * Copy data from a URI into a local file. + * @param resolver content resolver + * @param from a source URI. + * @param to a destination file + * @return true on success and false if the provider recently crashed. + * @throws IOException - if I/O error occurs. + */ + public static boolean copyFile(@NonNull ContentResolver resolver, @NonNull Uri from, @NonNull File to) + throws IOException { try (InputStream in = resolver.openInputStream(from)) { @@ -189,7 +187,9 @@ public class StorageUtils } } - public static boolean copyFile(@NonNull ContentResolver resolver,@NonNull Uri from,@NonNull Uri to) throws IOException { + public static boolean copyFile(@NonNull ContentResolver resolver, @NonNull Uri from, @NonNull Uri to) + throws IOException + { try (InputStream in = resolver.openInputStream(from)) { try (OutputStream out = resolver.openOutputStream(to)) @@ -273,7 +273,8 @@ public class StorageUtils } removeEmptyDirectories(dir); return true; - } catch (Exception e) + } + catch (Exception e) { e.printStackTrace(); return false; @@ -281,8 +282,7 @@ public class StorageUtils } @FunctionalInterface - public interface UriVisitor - { + public interface UriVisitor { void visit(Uri uri); } @@ -291,20 +291,22 @@ public class StorageUtils * @param contentResolver contentResolver instance * @param rootUri root URI to scan */ - public static void listContentProviderFilesRecursively(ContentResolver contentResolver, Uri rootUri, UriVisitor filter) + public static void listContentProviderFilesRecursively(ContentResolver contentResolver, Uri rootUri, + UriVisitor filter) { - Uri rootDir = DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, DocumentsContract.getTreeDocumentId(rootUri)); + Uri rootDir = + DocumentsContract.buildChildDocumentsUriUsingTree(rootUri, DocumentsContract.getTreeDocumentId(rootUri)); Queue directories = new LinkedBlockingQueue<>(); directories.add(rootDir); while (!directories.isEmpty()) { Uri dir = directories.remove(); - try (Cursor cur = contentResolver.query(dir, new String[]{ - DocumentsContract.Document.COLUMN_DOCUMENT_ID, - DocumentsContract.Document.COLUMN_DISPLAY_NAME, - DocumentsContract.Document.COLUMN_MIME_TYPE - }, null, null, null)) + try (Cursor cur = contentResolver.query(dir, + new String[] {DocumentsContract.Document.COLUMN_DOCUMENT_ID, + DocumentsContract.Document.COLUMN_DISPLAY_NAME, + DocumentsContract.Document.COLUMN_MIME_TYPE}, + null, null, null)) { while (cur.moveToNext()) { @@ -328,16 +330,11 @@ public class StorageUtils } } - public static boolean copyFileToDocumentFile( - @NonNull Activity activity, - @NonNull File sourceFile, - @NonNull DocumentFile targetFile - ) + public static boolean copyFileToDocumentFile(@NonNull Activity activity, @NonNull File sourceFile, + @NonNull DocumentFile targetFile) { - try ( - InputStream in = new FileInputStream(sourceFile); - OutputStream out = activity.getContentResolver().openOutputStream(targetFile.getUri()) - ) + try (InputStream in = new FileInputStream(sourceFile); + OutputStream out = activity.getContentResolver().openOutputStream(targetFile.getUri())) { if (out == null) { @@ -353,7 +350,8 @@ public class StorageUtils out.flush(); return true; - } catch (IOException e) + } + catch (IOException e) { Logger.e(TAG, "Failed to copy file from " + sourceFile.getAbsolutePath() + " to " + targetFile.getUri(), e); return false; @@ -372,7 +370,8 @@ public class StorageUtils file.delete(); } dir.delete(); - } catch (Exception e) + } + catch (Exception e) { Logger.e(TAG, "Failed to delete directory: " + dir.getUri(), e); } @@ -393,7 +392,8 @@ public class StorageUtils return true; } } - } catch (Exception e) + } + catch (Exception e) { Logger.e(TAG, "Failed to check if folder is writable: " + folderPath, e); } diff --git a/android/app/src/main/java/app/organicmaps/util/StringUtils.java b/android/app/src/main/java/app/organicmaps/sdk/util/StringUtils.java similarity index 85% rename from android/app/src/main/java/app/organicmaps/util/StringUtils.java rename to android/app/src/main/java/app/organicmaps/sdk/util/StringUtils.java index 00129f810..1512c6898 100644 --- a/android/app/src/main/java/app/organicmaps/util/StringUtils.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/StringUtils.java @@ -1,15 +1,11 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.content.Context; import android.text.Editable; import android.text.TextWatcher; import android.util.Pair; - import androidx.annotation.NonNull; - -import app.organicmaps.MwmApplication; import app.organicmaps.R; - import java.text.NumberFormat; import java.util.Locale; @@ -38,7 +34,8 @@ public class StringUtils * @param fraction a double value, that represents a fraction of a whole * @return correct string representation of percent for different locales */ - public static String formatPercent(double fraction) { + public static String formatPercent(double fraction) + { NumberFormat percentFormat = NumberFormat.getPercentInstance(); percentFormat.setMaximumFractionDigits(2); return percentFormat.format(fraction); @@ -72,21 +69,22 @@ public class StringUtils { if (size < Constants.GB) { - int value = (int)((float)size / Constants.MB + 0.5f); + int value = (int) ((float) size / Constants.MB + 0.5f); if (value == 0) value = 1; - return formatUsingUsLocale("%1$d %2$s", value, MwmApplication.from(context).getString(R.string.mb)); + return formatUsingUsLocale("%1$d %2$s", value, context.getString(R.string.mb)); } float value = ((float) size / Constants.GB); - return formatUsingSystemLocale("%1$.1f %2$s", value, MwmApplication.from(context).getString(R.string.gb)); + return formatUsingSystemLocale("%1$.1f %2$s", value, context.getString(R.string.gb)); } public static boolean isRtl() { Locale defLocale = Locale.getDefault(); - return Character.getDirectionality(defLocale.getDisplayName(defLocale).charAt(0)) == Character.DIRECTIONALITY_RIGHT_TO_LEFT; + return Character.getDirectionality(defLocale.getDisplayName(defLocale).charAt(0)) + == Character.DIRECTIONALITY_RIGHT_TO_LEFT; } @NonNull @@ -104,13 +102,16 @@ public class StringUtils public static class SimpleTextWatcher implements TextWatcher { @Override - public void beforeTextChanged(CharSequence s, int start, int count, int after) { } + public void beforeTextChanged(CharSequence s, int start, int count, int after) + {} @Override - public void onTextChanged(CharSequence s, int start, int before, int count) { } + public void onTextChanged(CharSequence s, int start, int before, int count) + {} @Override - public void afterTextChanged(Editable s) { } + public void afterTextChanged(Editable s) + {} } private StringUtils() {} diff --git a/android/app/src/main/java/app/organicmaps/util/ThemeSwitcher.java b/android/app/src/main/java/app/organicmaps/sdk/util/ThemeSwitcher.java similarity index 92% rename from android/app/src/main/java/app/organicmaps/util/ThemeSwitcher.java rename to android/app/src/main/java/app/organicmaps/sdk/util/ThemeSwitcher.java index b90dddc03..0acd89688 100644 --- a/android/app/src/main/java/app/organicmaps/util/ThemeSwitcher.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/ThemeSwitcher.java @@ -1,25 +1,22 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.app.Activity; import android.app.UiModeManager; import android.content.Context; import android.location.Location; import android.os.Build; - import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatDelegate; - -import java.util.Calendar; - -import app.organicmaps.Framework; import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.display.DisplayManager; import app.organicmaps.downloader.DownloaderStatusIcon; -import app.organicmaps.location.LocationHelper; import app.organicmaps.routing.RoutingController; +import app.organicmaps.sdk.Framework; import app.organicmaps.sdk.MapStyle; -import app.organicmaps.util.concurrency.UiThread; +import app.organicmaps.sdk.display.DisplayManager; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.util.ThemeUtils; +import java.util.Calendar; public enum ThemeSwitcher { @@ -28,8 +25,7 @@ public enum ThemeSwitcher private static final long CHECK_INTERVAL_MS = 30 * 60 * 1000; private static boolean mRendererActive = false; - private final Runnable mAutoThemeChecker = new Runnable() - { + private final Runnable mAutoThemeChecker = new Runnable() { @Override public void run() { @@ -138,7 +134,7 @@ public enum ThemeSwitcher { // Because of the distinct behavior in auto theme, Android Auto employs its own mechanism for theme switching. // For the Android Auto theme switcher, please consult the app.organicmaps.car.util.ThemeUtils module. - if (DisplayManager.from(mContext).isCarDisplayUsed()) + if (MwmApplication.from(mContext).getDisplayManager().isCarDisplayUsed()) return; // If rendering is not active we can mark map style, because all graphics // will be recreated after rendering activation. @@ -151,13 +147,14 @@ public enum ThemeSwitcher /** * Determine light/dark theme based on time and location, * or fall back to time-based (06:00-18:00) when there's no location fix + * * @return theme_light/dark string */ private String calcAutoTheme() { String defaultTheme = mContext.getResources().getString(R.string.theme_default); String nightTheme = mContext.getResources().getString(R.string.theme_night); - Location last = LocationHelper.from(mContext).getSavedLocation(); + Location last = MwmApplication.from(mContext).getLocationHelper().getSavedLocation(); boolean day; if (last != null) diff --git a/android/app/src/main/java/app/organicmaps/util/UiUtils.java b/android/app/src/main/java/app/organicmaps/sdk/util/UiUtils.java similarity index 80% rename from android/app/src/main/java/app/organicmaps/util/UiUtils.java rename to android/app/src/main/java/app/organicmaps/sdk/util/UiUtils.java index 97c985990..a38891899 100644 --- a/android/app/src/main/java/app/organicmaps/util/UiUtils.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/UiUtils.java @@ -1,4 +1,4 @@ -package app.organicmaps.util; +package app.organicmaps.sdk.util; import android.animation.Animator; import android.app.Activity; @@ -18,7 +18,6 @@ import android.view.Window; import android.view.WindowManager; import android.widget.Button; import android.widget.TextView; - import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.AnyRes; import androidx.annotation.AttrRes; @@ -34,12 +33,11 @@ import androidx.core.view.WindowCompat; import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsControllerCompat; import androidx.recyclerview.widget.RecyclerView; -import app.organicmaps.MwmApplication; import app.organicmaps.R; - +import app.organicmaps.util.ThemeUtils; +import app.organicmaps.util.WindowInsetUtils; import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.textfield.TextInputLayout; - import java.util.Objects; public final class UiUtils @@ -55,23 +53,28 @@ public final class UiUtils public static class SimpleAnimatorListener implements Animator.AnimatorListener { @Override - public void onAnimationStart(Animator animation) {} + public void onAnimationStart(Animator animation) + {} @Override - public void onAnimationEnd(Animator animation) {} + public void onAnimationEnd(Animator animation) + {} @Override - public void onAnimationCancel(Animator animation) {} + public void onAnimationCancel(Animator animation) + {} @Override - public void onAnimationRepeat(Animator animation) {} + public void onAnimationRepeat(Animator animation) + {} } - public static void waitLayout(final View view, @NonNull final ViewTreeObserver.OnGlobalLayoutListener callback) { + public static void waitLayout(final View view, @NonNull final ViewTreeObserver.OnGlobalLayoutListener callback) + { view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { + public void onGlobalLayout() + { // viewTreeObserver can be dead(isAlive() == false), we should get a new one here. view.getViewTreeObserver().removeOnGlobalLayoutListener(this); callback.onGlobalLayout(); @@ -196,12 +199,13 @@ public final class UiUtils public static void showHomeUpButton(MaterialToolbar toolbar) { - toolbar.setNavigationIcon(ThemeUtils.getResource(toolbar.getContext(), androidx.appcompat.R.attr.homeAsUpIndicator)); + toolbar.setNavigationIcon( + ThemeUtils.getResource(toolbar.getContext(), androidx.appcompat.R.attr.homeAsUpIndicator)); } public static boolean isTablet(@NonNull Context context) { - return MwmApplication.from(context).getResources().getBoolean(R.bool.tabletLayout); + return context.getResources().getBoolean(R.bool.tabletLayout); } public static int dimen(@NonNull Context context, @DimenRes int id) @@ -220,20 +224,21 @@ public final class UiUtils public static void updateRedButton(Button button) { - button.setTextColor(ThemeUtils.getColor(button.getContext(), button.isEnabled() ? R.attr.redButtonTextColor - : R.attr.redButtonTextColorDisabled)); + button.setTextColor(ThemeUtils.getColor( + button.getContext(), button.isEnabled() ? R.attr.redButtonTextColor : R.attr.redButtonTextColorDisabled)); } public static void setInputError(@NonNull TextInputLayout layout, @StringRes int error) { setInputError(layout, error == 0 ? null : layout.getContext().getString(error)); } - + public static void setInputError(@NonNull TextInputLayout layout, String error) { layout.getEditText().setError(error); - layout.getEditText().setTextColor(error == null ? ThemeUtils.getColor(layout.getContext(), android.R.attr.textColorPrimary) - : ContextCompat.getColor(layout.getContext(), R.color.base_red)); + layout.getEditText().setTextColor(error == null + ? ThemeUtils.getColor(layout.getContext(), android.R.attr.textColorPrimary) + : ContextCompat.getColor(layout.getContext(), R.color.base_red)); } public static void setFullscreen(@NonNull Activity activity, boolean fullscreen) @@ -277,9 +282,10 @@ public final class UiUtils } else { - @ColorInt final int color = isLight - ? ResourcesCompat.getColor(activity.getResources(), R.color.bg_statusbar_translucent, null) - : Color.TRANSPARENT; + @ColorInt + final int color = + isLight ? ResourcesCompat.getColor(activity.getResources(), R.color.bg_statusbar_translucent, null) + : Color.TRANSPARENT; window.setStatusBarColor(color); } } @@ -287,19 +293,16 @@ public final class UiUtils public static void setViewInsetsPaddingBottom(View view, WindowInsetsCompat windowInsets) { final Insets systemInsets = windowInsets.getInsets(WindowInsetUtils.TYPE_SAFE_DRAWING); - view.setPaddingRelative(view.getPaddingStart(), view.getPaddingTop(), - view.getPaddingEnd(), systemInsets.bottom); + view.setPaddingRelative(view.getPaddingStart(), view.getPaddingTop(), view.getPaddingEnd(), systemInsets.bottom); } public static void setViewInsetsPaddingNoBottom(View view, WindowInsetsCompat windowInsets) { final Insets systemInsets = windowInsets.getInsets(WindowInsetUtils.TYPE_SAFE_DRAWING); - view.setPadding(systemInsets.left, systemInsets.top, - systemInsets.right, view.getPaddingBottom()); + view.setPadding(systemInsets.left, systemInsets.top, systemInsets.right, view.getPaddingBottom()); } - public static void setupNavigationIcon(@NonNull MaterialToolbar toolbar, - @NonNull View.OnClickListener listener) + public static void setupNavigationIcon(@NonNull MaterialToolbar toolbar, @NonNull View.OnClickListener listener) { View customNavigationButton = toolbar.findViewById(R.id.back); if (customNavigationButton != null) @@ -341,29 +344,27 @@ public final class UiUtils } } - public static void expandTouchAreaForView(@NonNull final View view, final int top, final int left, - final int bottom, final int right) + public static void expandTouchAreaForView(@NonNull final View view, final int top, final int left, final int bottom, + final int right) { final View parent = (View) view.getParent(); - parent.post(() -> - { - Rect rect = new Rect(); - view.getHitRect(rect); - rect.top -= top; - rect.left -= left; - rect.right += right; - rect.bottom += bottom; - parent.setTouchDelegate(new TouchDelegate(rect, view)); - }); + parent.post(() -> { + Rect rect = new Rect(); + view.getHitRect(rect); + rect.top -= top; + rect.left -= left; + rect.right += right; + rect.bottom += bottom; + parent.setTouchDelegate(new TouchDelegate(rect, view)); + }); } public static void showRecyclerItemView(boolean show, @NonNull View view) { if (show) { - view.setLayoutParams(new RecyclerView.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); + view.setLayoutParams( + new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); UiUtils.show(view); } else diff --git a/android/app/src/main/java/app/organicmaps/sdk/util/Utils.java b/android/app/src/main/java/app/organicmaps/sdk/util/Utils.java new file mode 100644 index 000000000..481db78b6 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/util/Utils.java @@ -0,0 +1,343 @@ +package app.organicmaps.sdk.util; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.os.Build; +import android.text.TextUtils; +import android.text.format.DateUtils; +import android.view.View; +import android.widget.Toast; +import androidx.annotation.Keep; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import app.organicmaps.BuildConfig; +import app.organicmaps.sdk.util.log.Logger; +import java.io.Closeable; +import java.io.IOException; +import java.text.DecimalFormatSymbols; +import java.util.Currency; +import java.util.Locale; +import java.util.Map; + +@Keep +public class Utils +{ + private static final String TAG = Utils.class.getSimpleName(); + + @StringRes + private static final int INVALID_ID = 0; + + static String makeUrlSafe(@NonNull final String url) + { + return url.replaceAll("(token|password|key)=([^&]+)", "***"); + } + + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @Nullable + public static String getCurrencyCode() + { + Locale[] locales = {Locale.getDefault(), Locale.US}; + for (Locale locale : locales) + { + Currency currency = getCurrencyForLocale(locale); + if (currency != null) + return currency.getCurrencyCode(); + } + return null; + } + + @Nullable + private static Currency getCurrencyForLocale(@NonNull Locale locale) + { + try + { + return Currency.getInstance(locale); + } + catch (Throwable e) + { + Logger.e(TAG, "Failed to obtain a currency for locale: " + locale, e); + return null; + } + } + + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @NonNull + public static String getCountryCode() + { + return Locale.getDefault().getCountry(); + } + + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @NonNull + public static String getLanguageCode() + { + return Locale.getDefault().getLanguage(); + } + + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @NonNull + public static String getDecimalSeparator() + { + return String.valueOf(DecimalFormatSymbols.getInstance().getDecimalSeparator()); + } + + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @NonNull + public static String getGroupingSeparator() + { + return String.valueOf(DecimalFormatSymbols.getInstance().getGroupingSeparator()); + } + + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @NonNull + public static String getCurrencySymbol(@NonNull String currencyCode) + { + try + { + return Currency.getInstance(currencyCode).getSymbol(Locale.getDefault()); + } + catch (Throwable e) + { + Logger.e(TAG, "Failed to obtain currency symbol by currency code = " + currencyCode, e); + } + + return currencyCode; + } + + /** + * Returns a string value for the specified key. If the value is not found then its key will be + * returned. + * + * @return string value or its key if there is no string for the specified key. + */ + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @NonNull + public static String getStringValueByKey(@NonNull Context context, @NonNull String key) + { + try + { + return context.getString(getStringIdByKey(context, key)); + } + catch (Resources.NotFoundException e) + { + Logger.e(TAG, "Failed to get value for string '" + key + "'", e); + } + return key; + } + + @StringRes + @SuppressLint("DiscouragedApi") + public static int getStringIdByKey(@NonNull Context context, @NonNull String key) + { + try + { + Resources res = context.getResources(); + @StringRes + int nameId = res.getIdentifier(key, "string", context.getPackageName()); + if (nameId == INVALID_ID || nameId == View.NO_ID) + throw new Resources.NotFoundException("String id '" + key + "' is not found"); + return nameId; + } + catch (RuntimeException e) + { + Logger.e(TAG, "Failed to get string with id '" + key + "'", e); + if (BuildConfig.BUILD_TYPE.equals("debug") || BuildConfig.BUILD_TYPE.equals("beta")) + { + Toast.makeText(context, "Add string id for '" + key + "'!", Toast.LENGTH_LONG).show(); + } + } + return INVALID_ID; + } + + /** + * Returns a name for a new bookmark created off the current GPS location. + * The name includes current time and date in locale-specific format. + * + * @return bookmark name with time and date. + */ + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @NonNull + public static String getMyPositionBookmarkName(@NonNull Context context) + { + return DateUtils.formatDateTime( + context, System.currentTimeMillis(), + DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR); + } + + // Called from JNI. + @NonNull + @Keep + @SuppressWarnings("unused") + public static String getDeviceName() + { + return Build.MANUFACTURER; + } + + // Called from JNI. + @NonNull + @Keep + @SuppressWarnings("unused") + public static String getDeviceModel() + { + return Build.MODEL; + } + + // Called from JNI. + @NonNull + @Keep + @SuppressWarnings("unused") + public static String getVersion() + { + return BuildConfig.VERSION_NAME; + } + + // Called from JNI. + @Keep + @SuppressWarnings("unused") + public static int getIntVersion() + { + // Please sync with getVersion() in build.gradle + // - % 100000000 removes prefix for special markets, e.g Huawei. + // - / 100 removes the number of commits in the current day. + return (BuildConfig.VERSION_CODE % 1_00_00_00_00) / 100; + } + + @NonNull + public static String getTagValueLocalized(@NonNull Context context, @Nullable String tagKey, @Nullable String value) + { + if (TextUtils.isEmpty(tagKey) || TextUtils.isEmpty(value)) + return ""; + + return getLocalizedFeatureType(context, tagKey + "-" + value); + } + + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @NonNull + public static String getLocalizedFeatureType(@NonNull Context context, @Nullable String type) + { + if (TextUtils.isEmpty(type)) + return ""; + + String key = "type." + type.replace('-', '.').replace(':', '_'); + return getLocalizedFeatureByKey(context, key); + } + + @NonNull + private static String getLocalizedFeatureByKey(@NonNull Context context, @NonNull String key) + { + return getStringValueByKey(context, key); + } + + // Called from JNI. + @Keep + @SuppressWarnings("unused") + @NonNull + public static String getLocalizedBrand(@NonNull Context context, @Nullable String brand) + { + if (TextUtils.isEmpty(brand)) + return ""; + + try + { + @StringRes + int nameId = context.getResources().getIdentifier("brand." + brand, "string", context.getPackageName()); + if (nameId == INVALID_ID || nameId == View.NO_ID) + return brand; + return context.getString(nameId); + } + catch (Resources.NotFoundException ignored) + {} + return brand; + } + + public static void closeSafely(@NonNull Closeable... closeable) + { + for (Closeable each : closeable) + { + if (each != null) + { + try + { + each.close(); + } + catch (IOException e) + { + Logger.e(TAG, "Failed to close '" + each + "'", e); + } + } + } + } + + public static String mapPrettyPrint(Map map) + { + if (map == null) + return "[null]"; + if (map.isEmpty()) + return "[]"; + + String joined = ""; + for (final K key : map.keySet()) + { + final String keyVal = key + "=" + map.get(key); + if (!joined.isEmpty()) + joined = TextUtils.join(",", new Object[] {joined, keyVal}); + else + joined = keyVal; + } + + return "[" + joined + "]"; + } + + @SuppressWarnings("deprecated") + private static @Nullable ResolveInfo resolveActivity(@NonNull PackageManager pm, @NonNull Intent intent, int flags) + { + return pm.resolveActivity(intent, flags); + } + + public static boolean isIntentSupported(@NonNull Context context, @NonNull Intent intent) + { + final PackageManager pm = context.getPackageManager(); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) + return resolveActivity(pm, intent, 0) != null; + return pm.resolveActivity(intent, PackageManager.ResolveInfoFlags.of(0)) != null; + } + + @SuppressWarnings("deprecation") + private static ApplicationInfo getApplicationInfoOld(@NonNull PackageManager manager, @NonNull String packageName, + int flags) throws PackageManager.NameNotFoundException + { + return manager.getApplicationInfo(packageName, flags); + } + + public static ApplicationInfo getApplicationInfo(@NonNull PackageManager manager, @NonNull String packageName, + int flags) throws PackageManager.NameNotFoundException + { + if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) + return getApplicationInfoOld(manager, packageName, flags); + return manager.getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags)); + } +} diff --git a/android/app/src/main/java/app/organicmaps/util/concurrency/ThreadPool.java b/android/app/src/main/java/app/organicmaps/sdk/util/concurrency/ThreadPool.java similarity index 79% rename from android/app/src/main/java/app/organicmaps/util/concurrency/ThreadPool.java rename to android/app/src/main/java/app/organicmaps/sdk/util/concurrency/ThreadPool.java index 216310432..bb78f16e3 100644 --- a/android/app/src/main/java/app/organicmaps/util/concurrency/ThreadPool.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/concurrency/ThreadPool.java @@ -1,4 +1,4 @@ -package app.organicmaps.util.concurrency; +package app.organicmaps.sdk.util.concurrency; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; @@ -12,11 +12,10 @@ public class ThreadPool private final ThreadPoolExecutor mStorage; private final ThreadPoolExecutor mWorker; - private static ThreadPoolExecutor create(int poolSize, int allowedTime) { - ThreadPoolExecutor res = new ThreadPoolExecutor(poolSize, poolSize, allowedTime, TimeUnit.SECONDS, - new LinkedBlockingQueue<>()); + ThreadPoolExecutor res = + new ThreadPoolExecutor(poolSize, poolSize, allowedTime, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); res.allowCoreThreadTimeOut(true); return res; } diff --git a/android/app/src/main/java/app/organicmaps/util/concurrency/UiThread.java b/android/app/src/main/java/app/organicmaps/sdk/util/concurrency/UiThread.java similarity index 97% rename from android/app/src/main/java/app/organicmaps/util/concurrency/UiThread.java rename to android/app/src/main/java/app/organicmaps/sdk/util/concurrency/UiThread.java index 21177b1d0..b51d8420c 100644 --- a/android/app/src/main/java/app/organicmaps/util/concurrency/UiThread.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/concurrency/UiThread.java @@ -1,8 +1,7 @@ -package app.organicmaps.util.concurrency; +package app.organicmaps.sdk.util.concurrency; import android.os.Handler; import android.os.Looper; - import androidx.annotation.Keep; public class UiThread diff --git a/android/app/src/main/java/app/organicmaps/util/log/Logger.java b/android/app/src/main/java/app/organicmaps/sdk/util/log/Logger.java similarity index 94% rename from android/app/src/main/java/app/organicmaps/util/log/Logger.java rename to android/app/src/main/java/app/organicmaps/sdk/util/log/Logger.java index ebe6b90f7..2058e4cb2 100644 --- a/android/app/src/main/java/app/organicmaps/util/log/Logger.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/log/Logger.java @@ -1,13 +1,10 @@ -package app.organicmaps.util.log; +package app.organicmaps.sdk.util.log; import android.util.Log; - import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import app.organicmaps.BuildConfig; -import net.jcip.annotations.ThreadSafe; - import java.io.File; import java.io.FileWriter; import java.io.IOException; @@ -15,6 +12,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; +import net.jcip.annotations.ThreadSafe; @ThreadSafe public final class Logger @@ -94,7 +92,8 @@ public final class Logger final StackTraceElement[] stackTrace = new Throwable().getStackTrace(); // Skip the chain of Logger.x() -> Logger.log() calls. int f = 0; - for (; f < stackTrace.length && stackTrace[f].getClassName().equals(Logger.class.getName()); f++); + for (; f < stackTrace.length && stackTrace[f].getClassName().equals(Logger.class.getName()); f++) + ; // The stack trace should have at least one non-logger frame, but who wants to crash here if it doesn't? if (f == stackTrace.length) return "Unknown"; @@ -147,16 +146,11 @@ public final class Logger { switch (level) { - case Log.VERBOSE: - return 'V'; - case Log.DEBUG: - return 'D'; - case Log.INFO: - return 'I'; - case Log.WARN: - return 'W'; - case Log.ERROR: - return 'E'; + case Log.VERBOSE: return 'V'; + case Log.DEBUG: return 'D'; + case Log.INFO: return 'I'; + case Log.WARN: return 'W'; + case Log.ERROR: return 'E'; } assert false : "Unknown log level " + level; return '_'; diff --git a/android/app/src/main/java/app/organicmaps/util/log/LogsManager.java b/android/app/src/main/java/app/organicmaps/sdk/util/log/LogsManager.java similarity index 71% rename from android/app/src/main/java/app/organicmaps/util/log/LogsManager.java rename to android/app/src/main/java/app/organicmaps/sdk/util/log/LogsManager.java index 1fa9907c0..fbcf1155b 100644 --- a/android/app/src/main/java/app/organicmaps/util/log/LogsManager.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/log/LogsManager.java @@ -1,8 +1,7 @@ -package app.organicmaps.util.log; +package app.organicmaps.sdk.util.log; import android.Manifest; import android.app.ActivityManager; -import android.app.Application; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; @@ -13,20 +12,14 @@ import android.net.NetworkCapabilities; import android.os.Build; import android.os.Debug; import android.util.Log; - import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.content.ContextCompat; - import app.organicmaps.BuildConfig; -import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.util.ROMUtils; -import app.organicmaps.util.StringUtils; - -import net.jcip.annotations.ThreadSafe; - +import app.organicmaps.sdk.util.ROMUtils; +import app.organicmaps.sdk.util.StringUtils; import java.io.File; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -34,11 +27,12 @@ import java.util.Date; import java.util.Locale; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import net.jcip.annotations.ThreadSafe; /** * By default uses Android's system logger. * After an initFileLogging() call can use a custom file logging implementation. - * + *

* Its important to have only system logging here to avoid infinite loop * (Logger calls getEnabledLogsFolder() in preparation to write). */ @@ -48,7 +42,7 @@ public final class LogsManager public interface OnZipCompletedListener { // Called from the logger thread. - public void onCompleted(final boolean success, @Nullable final String zipPath); + void onCompleted(final boolean success, @Nullable final String zipPath); } private final static String TAG = LogsManager.class.getSimpleName(); @@ -57,7 +51,9 @@ public final class LogsManager final static ExecutorService EXECUTOR = Executors.newSingleThreadExecutor(); @Nullable - private Application mApplication; + private Context mApplicationContext; + @Nullable + private SharedPreferences mPrefs; private boolean mIsFileLoggingEnabled = false; @Nullable private String mLogsFolder; @@ -67,13 +63,13 @@ public final class LogsManager Log.i(LogsManager.TAG, "Logging started"); } - public synchronized void initFileLogging(@NonNull Application application) + public synchronized void initFileLogging(@NonNull Context context, @NonNull SharedPreferences prefs) { Log.i(TAG, "Init file logging"); - mApplication = application; + mApplicationContext = context.getApplicationContext(); + mPrefs = prefs; - final SharedPreferences prefs = MwmApplication.prefs(mApplication); - mIsFileLoggingEnabled = prefs.getBoolean(mApplication.getString(R.string.pref_enable_logging), false); + mIsFileLoggingEnabled = mPrefs.getBoolean(mApplicationContext.getString(R.string.pref_enable_logging), false); Log.i(TAG, "isFileLoggingEnabled preference: " + mIsFileLoggingEnabled); mIsFileLoggingEnabled = mIsFileLoggingEnabled && ensureLogsFolder() != null; @@ -83,7 +79,7 @@ public final class LogsManager private void assertFileLoggingInit() { - assert mApplication != null : "mApplication must be initialized first by calling initFileLogging()"; + assert mApplicationContext != null : "mApplicationContext must be initialized first by calling initFileLogging()"; } /** @@ -118,9 +114,9 @@ public final class LogsManager if (mLogsFolder != null && createWritableDir(mLogsFolder)) return mLogsFolder; - mLogsFolder = createLogsFolder(mApplication.getExternalFilesDir(null)); + mLogsFolder = createLogsFolder(mApplicationContext.getExternalFilesDir(null)); if (mLogsFolder == null) - mLogsFolder = createLogsFolder(mApplication.getFilesDir()); + mLogsFolder = createLogsFolder(mApplicationContext.getFilesDir()); if (mLogsFolder == null) Log.e(TAG, "Can't create any logs folder"); @@ -170,10 +166,7 @@ public final class LogsManager mIsFileLoggingEnabled = enabled; // Only Debug builds log DEBUG level to Android system log. nativeToggleCoreDebugLogs(enabled || BuildConfig.DEBUG); - MwmApplication.prefs(mApplication) - .edit() - .putBoolean(mApplication.getString(R.string.pref_enable_logging), enabled) - .apply(); + mPrefs.edit().putBoolean(mApplicationContext.getString(R.string.pref_enable_logging), enabled).apply(); Log.i(TAG, "Logging to " + (enabled ? "logs folder " + mLogsFolder : "system log")); } @@ -184,7 +177,7 @@ public final class LogsManager /** * Returns false if file logging can't be enabled. - * + *

* NOTE: initFileLogging() must be called before. */ public synchronized boolean setFileLoggingEnabled(boolean enabled) @@ -235,14 +228,16 @@ public final class LogsManager final DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US); final StringBuilder sb = new StringBuilder(512); - sb.append("Datetime: ").append(fmt.format(new Date())) - .append("\n\nAndroid version: ") - .append(Build.VERSION.CODENAME.equals("REL") ? Build.VERSION.RELEASE : Build.VERSION.CODENAME) - .append(" (API ").append(Build.VERSION.SDK_INT).append(')'); + sb.append("Datetime: ") + .append(fmt.format(new Date())) + .append("\n\nAndroid version: ") + .append(Build.VERSION.CODENAME.equals("REL") ? Build.VERSION.RELEASE : Build.VERSION.CODENAME) + .append(" (API ") + .append(Build.VERSION.SDK_INT) + .append(')'); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) sb.append(", security patch level: ").append(Build.VERSION.SECURITY_PATCH); - sb.append(", os.version: ").append(System.getProperty("os.version", "N/A")) - .append("\nDevice: "); + sb.append(", os.version: ").append(System.getProperty("os.version", "N/A")).append("\nDevice: "); if (!StringUtils.toLowerCase(Build.MODEL).startsWith(StringUtils.toLowerCase(Build.MANUFACTURER))) sb.append(Build.MANUFACTURER).append(' '); sb.append(Build.MODEL).append(" (").append(Build.DEVICE).append(')'); @@ -250,10 +245,15 @@ public final class LogsManager sb.append("\nSupported ABIs:"); for (String abi : Build.SUPPORTED_ABIS) sb.append(' ').append(abi); - sb.append("\nApp version: ").append(BuildConfig.APPLICATION_ID).append(' ').append(BuildConfig.VERSION_NAME) - .append("\nLocale: ").append(Locale.getDefault()) - .append("\nNetworks: "); - final ConnectivityManager manager = (ConnectivityManager) mApplication.getSystemService(Context.CONNECTIVITY_SERVICE); + sb.append("\nApp version: ") + .append(BuildConfig.APPLICATION_ID) + .append(' ') + .append(BuildConfig.VERSION_NAME) + .append("\nLocale: ") + .append(Locale.getDefault()) + .append("\nNetworks: "); + final ConnectivityManager manager = + (ConnectivityManager) mApplicationContext.getSystemService(Context.CONNECTIVITY_SERVICE); if (manager != null) { for (Network network : manager.getAllNetworks()) @@ -263,15 +263,18 @@ public final class LogsManager } } sb.append("\nLocation providers:"); - final LocationManager locMngr = (android.location.LocationManager) mApplication.getSystemService(Context.LOCATION_SERVICE); + final LocationManager locMngr = + (android.location.LocationManager) mApplicationContext.getSystemService(Context.LOCATION_SERVICE); if (locMngr != null) for (String provider : locMngr.getProviders(true)) sb.append(' ').append(provider); sb.append("\nLocation permissions:"); - if (ContextCompat.checkSelfPermission(mApplication, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) + if (ContextCompat.checkSelfPermission(mApplicationContext, Manifest.permission.ACCESS_COARSE_LOCATION) + == PackageManager.PERMISSION_GRANTED) sb.append(' ').append("coarse"); - if (ContextCompat.checkSelfPermission(mApplication, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) + if (ContextCompat.checkSelfPermission(mApplicationContext, Manifest.permission.ACCESS_FINE_LOCATION) + == PackageManager.PERMISSION_GRANTED) sb.append(' ').append("fine"); sb.append("\n\n"); @@ -293,25 +296,25 @@ public final class LogsManager final StringBuilder log = new StringBuilder(256); log.append("Memory info: ") - .append(" Debug.getNativeHeapSize() = ") - .append(Debug.getNativeHeapSize() / 1024) - .append("KB; Debug.getNativeHeapAllocatedSize() = ") - .append(Debug.getNativeHeapAllocatedSize() / 1024) - .append("KB; Debug.getNativeHeapFreeSize() = ") - .append(Debug.getNativeHeapFreeSize() / 1024) - .append("KB; debugMI.getTotalPrivateDirty() = ") - .append(debugMI.getTotalPrivateDirty()) - .append("KB; debugMI.getTotalPss() = ") - .append(debugMI.getTotalPss()) - .append("KB; mi.availMem = ") - .append(mi.availMem / 1024) - .append("KB; mi.threshold = ") - .append(mi.threshold / 1024) - .append("KB; mi.lowMemory = ") - .append(mi.lowMemory) - .append("; mi.totalMem = ") - .append(mi.totalMem / 1024) - .append("KB;"); + .append(" Debug.getNativeHeapSize() = ") + .append(Debug.getNativeHeapSize() / 1024) + .append("KB; Debug.getNativeHeapAllocatedSize() = ") + .append(Debug.getNativeHeapAllocatedSize() / 1024) + .append("KB; Debug.getNativeHeapFreeSize() = ") + .append(Debug.getNativeHeapFreeSize() / 1024) + .append("KB; debugMI.getTotalPrivateDirty() = ") + .append(debugMI.getTotalPrivateDirty()) + .append("KB; debugMI.getTotalPss() = ") + .append(debugMI.getTotalPss()) + .append("KB; mi.availMem = ") + .append(mi.availMem / 1024) + .append("KB; mi.threshold = ") + .append(mi.threshold / 1024) + .append("KB; mi.lowMemory = ") + .append(mi.lowMemory) + .append("; mi.totalMem = ") + .append(mi.totalMem / 1024) + .append("KB;"); return log.toString(); } diff --git a/android/app/src/main/java/app/organicmaps/util/log/ZipLogsTask.java b/android/app/src/main/java/app/organicmaps/sdk/util/log/ZipLogsTask.java similarity index 82% rename from android/app/src/main/java/app/organicmaps/util/log/ZipLogsTask.java rename to android/app/src/main/java/app/organicmaps/sdk/util/log/ZipLogsTask.java index 6a51dd40d..489dcdb2b 100644 --- a/android/app/src/main/java/app/organicmaps/util/log/ZipLogsTask.java +++ b/android/app/src/main/java/app/organicmaps/sdk/util/log/ZipLogsTask.java @@ -1,8 +1,7 @@ -package app.organicmaps.util.log; +package app.organicmaps.sdk.util.log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; @@ -47,9 +46,8 @@ class ZipLogsTask implements Runnable File sourceFile = new File(sourcePath); if (!sourceFile.isDirectory()) return false; - try ( - FileOutputStream dest = new FileOutputStream(toLocation, false); - ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest))) + try (FileOutputStream dest = new FileOutputStream(toLocation, false); + ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest))) { zipSubFolder(out, sourceFile, sourceFile.getPath().length()); } @@ -61,8 +59,7 @@ class ZipLogsTask implements Runnable return true; } - private void zipSubFolder(ZipOutputStream out, File folder, - int basePathLength) throws IOException + private void zipSubFolder(ZipOutputStream out, File folder, int basePathLength) throws IOException { File[] fileList = folder.listFiles(); if (fileList == null) @@ -80,9 +77,8 @@ class ZipLogsTask implements Runnable byte[] data = new byte[bufSize]; String unmodifiedFilePath = file.getPath(); String relativePath = unmodifiedFilePath.substring(basePathLength); - try ( - FileInputStream fi = new FileInputStream(unmodifiedFilePath); - BufferedInputStream origin = new BufferedInputStream(fi, bufSize)) + try (FileInputStream fi = new FileInputStream(unmodifiedFilePath); + BufferedInputStream origin = new BufferedInputStream(fi, bufSize)) { ZipEntry entry = new ZipEntry(relativePath); out.putNextEntry(entry); @@ -112,9 +108,8 @@ class ZipLogsTask implements Runnable path += File.separator + "logcat.log"; final File file = new File(path); - try ( - InputStreamReader reader = new InputStreamReader(process.getInputStream()); - FileWriter writer = new FileWriter(file)) + try (InputStreamReader reader = new InputStreamReader(process.getInputStream()); + FileWriter writer = new FileWriter(file)) { writer.write(LogsManager.INSTANCE.getSystemInformation()); char[] buffer = new char[10000]; @@ -124,7 +119,8 @@ class ZipLogsTask implements Runnable if (n == -1) break; writer.write(buffer, 0, n); - } while (true); + } + while (true); } catch (Throwable e) { diff --git a/android/app/src/main/java/app/organicmaps/sdk/widget/placepage/PlacePageButtonFactory.java b/android/app/src/main/java/app/organicmaps/sdk/widget/placepage/PlacePageButtonFactory.java new file mode 100644 index 000000000..59069ebc1 --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/sdk/widget/placepage/PlacePageButtonFactory.java @@ -0,0 +1,6 @@ +package app.organicmaps.sdk.widget.placepage; + +public class PlacePageButtonFactory +{ + public native static boolean nativeHasRecentlyDeletedBookmark(); +} diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageData.java b/android/app/src/main/java/app/organicmaps/sdk/widget/placepage/PlacePageData.java similarity index 53% rename from android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageData.java rename to android/app/src/main/java/app/organicmaps/sdk/widget/placepage/PlacePageData.java index 002c0126f..3dab4583e 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageData.java +++ b/android/app/src/main/java/app/organicmaps/sdk/widget/placepage/PlacePageData.java @@ -1,12 +1,9 @@ -package app.organicmaps.widget.placepage; +package app.organicmaps.sdk.widget.placepage; import android.os.Parcelable; - import androidx.annotation.Keep; // Used by JNI. @Keep @SuppressWarnings("unused") -public interface PlacePageData extends Parcelable -{ -} +public interface PlacePageData extends Parcelable {} diff --git a/android/app/src/main/java/app/organicmaps/search/CategoriesAdapter.java b/android/app/src/main/java/app/organicmaps/search/CategoriesAdapter.java index 2fecc13de..fe509cacb 100644 --- a/android/app/src/main/java/app/organicmaps/search/CategoriesAdapter.java +++ b/android/app/src/main/java/app/organicmaps/search/CategoriesAdapter.java @@ -3,32 +3,32 @@ package app.organicmaps.search; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; +import android.content.res.Configuration; import android.content.res.Resources; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; - import androidx.annotation.DrawableRes; import androidx.annotation.IntDef; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; - import app.organicmaps.R; import app.organicmaps.sdk.search.DisplayedCategories; +import app.organicmaps.sdk.util.Language; import app.organicmaps.util.ThemeUtils; - import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Locale; class CategoriesAdapter extends RecyclerView.Adapter { @Retention(RetentionPolicy.SOURCE) - @IntDef({ ViewType.CATEGORY }) - @interface ViewType { + @IntDef({ViewType.CATEGORY}) + @interface ViewType + { int CATEGORY = 0; } @@ -42,15 +42,14 @@ class CategoriesAdapter extends RecyclerView.Adapter= Build.VERSION_CODES.N ? c.getLocales().get(0).toString() : c.locale.toString(); + // } + + private @NonNull String getEnglishString(@StringRes int categoryId) + { + // Not thread safe, but we don't care, as it should always run on the same thread. + if (mEnglishResources == null) + { + final Configuration newConfig = new Configuration(mResources.getConfiguration()); + newConfig.setLocale(new Locale("en")); + final Context localizedContext = mInflater.getContext().createConfigurationContext(newConfig); + mEnglishResources = localizedContext.getResources(); + } + return mEnglishResources.getString(categoryId); + } + ViewHolder(@NonNull View v, @NonNull TextView tv) { super(v); mView = v; mTitle = tv; + + // TODO(AB): Change Language.getDefaultLocale() to getResourcesLanguage() and pass proper language to the search. + mIsLangSupported = DisplayedCategories.nativeIsLangSupported(Language.getDefaultLocale()); } void setupClickListeners() @@ -181,17 +185,16 @@ class CategoriesAdapter extends RecyclerView.Adapter { @@ -47,7 +46,7 @@ class SearchAdapter extends RecyclerView.Adapter processClick(mResult, mOrder)); } @@ -63,7 +62,8 @@ class SearchAdapter extends RecyclerView.Adapter { - if (result.description.minutesUntilClosed < 60) // less than 1 hour + if (result.description.minutesUntilClosed < 60) // less than 1 hour { - final String time = result.description.minutesUntilClosed + " " + - resources.getString(R.string.minute); + final String time = result.description.minutesUntilClosed + " " + resources.getString(R.string.minute); final String string = resources.getString(R.string.closes_in, time); UiUtils.setTextAndShow(mOpen, string); @@ -170,8 +169,7 @@ class SearchAdapter extends RecyclerView.Adapter - new SuggestViewHolder(inflater.inflate(R.layout.item_search_suggest, parent, false)); + new SuggestViewHolder(inflater.inflate(R.layout.item_search_suggest, parent, false)); case SearchResult.TYPE_RESULT -> - new ResultViewHolder(inflater.inflate(R.layout.item_search_result, parent, false)); + new ResultViewHolder(inflater.inflate(R.layout.item_search_result, parent, false)); default -> throw new IllegalArgumentException("Unhandled view type given"); }; } diff --git a/android/app/src/main/java/app/organicmaps/search/SearchCategoriesFragment.java b/android/app/src/main/java/app/organicmaps/search/SearchCategoriesFragment.java index bab53eee1..905b7074d 100644 --- a/android/app/src/main/java/app/organicmaps/search/SearchCategoriesFragment.java +++ b/android/app/src/main/java/app/organicmaps/search/SearchCategoriesFragment.java @@ -2,14 +2,12 @@ package app.organicmaps.search; import android.os.Bundle; import android.view.View; - import androidx.annotation.NonNull; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmRecyclerFragment; -public class SearchCategoriesFragment extends BaseMwmRecyclerFragment - implements CategoriesAdapter.CategoriesUiListener +public class SearchCategoriesFragment + extends BaseMwmRecyclerFragment implements CategoriesAdapter.CategoriesUiListener { @Override public void onViewCreated(View view, Bundle savedInstanceState) @@ -33,7 +31,6 @@ public class SearchCategoriesFragment extends BaseMwmRecyclerFragment mAttachedRecyclers = new ArrayList<>(); - private final RecyclerView.OnScrollListener mRecyclerListener = new RecyclerView.OnScrollListener() - { + private final RecyclerView.OnScrollListener mRecyclerListener = new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { @@ -175,13 +170,13 @@ public class SearchFragment extends BaseMwmFragment private String mInitialLocale; private boolean mInitialSearchOnMap = false; - private final ActivityResultLauncher startVoiceRecognitionForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> - mToolbarController.onVoiceRecognitionResult(activityResult)); + private final ActivityResultLauncher startVoiceRecognitionForResult = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), + activityResult -> mToolbarController.onVoiceRecognitionResult(activityResult)); - private final LocationListener mLocationListener = new LocationListener() - { + private final LocationListener mLocationListener = new LocationListener() { @Override - public void onLocationUpdated(Location location) + public void onLocationUpdated(@NonNull Location location) { mLastPosition.set(location.getLatitude(), location.getLongitude()); @@ -204,9 +199,7 @@ public class SearchFragment extends BaseMwmFragment if (fragment == null || fragment.isDetached() || fragment.isRemoving()) { fragment = fm.getFragmentFactory().instantiate(requireActivity().getClassLoader(), fragmentName); - fm.beginTransaction() - .add(R.id.download_suggest_frame, fragment, fragmentName) - .commit(); + fm.beginTransaction().add(R.id.download_suggest_frame, fragment, fragmentName).commit(); } } @@ -218,9 +211,7 @@ public class SearchFragment extends BaseMwmFragment final FragmentManager manager = getChildFragmentManager(); final Fragment fragment = manager.findFragmentByTag(CountrySuggestFragment.class.getName()); if (fragment != null && !fragment.isDetached() && !fragment.isRemoving()) - manager.beginTransaction() - .remove(fragment) - .commitAllowingStateLoss(); + manager.beginTransaction().remove(fragment).commitAllowingStateLoss(); } private void updateFrames() @@ -229,7 +220,8 @@ public class SearchFragment extends BaseMwmFragment MaterialToolbar toolbar = mToolbarController.getToolbar(); AppBarLayout.LayoutParams lp = (AppBarLayout.LayoutParams) toolbar.getLayoutParams(); lp.setScrollFlags(hasQuery ? AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS - | AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL : 0); + | AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL + : 0); toolbar.setLayoutParams(lp); UiUtils.showIf(hasQuery, mResultsFrame); @@ -244,9 +236,7 @@ public class SearchFragment extends BaseMwmFragment private void updateResultsPlaceholder() { - final boolean show = !mSearchRunning - && mSearchAdapter.getItemCount() == 0 - && mToolbarController.hasQuery(); + final boolean show = !mSearchRunning && mSearchAdapter.getItemCount() == 0 && mToolbarController.hasQuery(); UiUtils.showIf(show, mResultsPlaceholder); } @@ -286,13 +276,13 @@ public class SearchFragment extends BaseMwmFragment mResultsPlaceholder.setContent(R.string.search_not_found, R.string.search_not_found_query); mSearchAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() - { - @Override - public void onChanged() - { - updateResultsPlaceholder(); - } - }); + { + @Override + public void onChanged() + { + updateResultsPlaceholder(); + } + }); mShowOnMapFab = root.findViewById(R.id.show_on_map_fab); mShowOnMapFab.setOnClickListener(v -> showAllResultsOnMap()); @@ -302,8 +292,7 @@ public class SearchFragment extends BaseMwmFragment updateFrames(); updateResultsPlaceholder(); ViewCompat.setOnApplyWindowInsetsListener( - mResults, - new WindowInsetUtils.ScrollableContentInsetsListener(mResults, mShowOnMapFab)); + mResults, new WindowInsetUtils.ScrollableContentInsetsListener(mResults, mShowOnMapFab)); mToolbarController.activate(); @@ -330,8 +319,9 @@ public class SearchFragment extends BaseMwmFragment public void onResume() { super.onResume(); - LocationHelper.from(requireContext()).addListener(mLocationListener); - if (mInitialQuery != null) { + MwmApplication.from(requireContext()).getLocationHelper().addListener(mLocationListener); + if (mInitialQuery != null) + { setQuery(mInitialQuery, false); mInitialQuery = null; } @@ -340,7 +330,7 @@ public class SearchFragment extends BaseMwmFragment @Override public void onPause() { - LocationHelper.from(requireContext()).removeListener(mLocationListener); + MwmApplication.from(requireContext()).getLocationHelper().removeListener(mLocationListener); super.onPause(); } @@ -362,9 +352,18 @@ public class SearchFragment extends BaseMwmFragment super.onDestroy(); } - private String getQuery() { return mToolbarController.getQuery(); } - private boolean isCategory() { return mToolbarController.isCategory(); } - void setQuery(String text, boolean isCategory) { mToolbarController.setQuery(text, isCategory); } + private String getQuery() + { + return mToolbarController.getQuery(); + } + private boolean isCategory() + { + return mToolbarController.isCategory(); + } + void setQuery(String text, boolean isCategory) + { + mToolbarController.setQuery(text, isCategory); + } private void readArguments() { @@ -379,7 +378,7 @@ public class SearchFragment extends BaseMwmFragment private boolean tryRecognizeHiddenCommand(@NonNull String query) { - for(HiddenCommand command: getHiddenCommands()) + for (HiddenCommand command : getHiddenCommands()) { if (command.execute(query)) return true; @@ -393,11 +392,9 @@ public class SearchFragment extends BaseMwmFragment { if (mHiddenCommands.isEmpty()) { - mHiddenCommands.addAll( - Arrays.asList(new BadStorageCommand("?emulateBadStorage", requireContext()), - new JavaCrashCommand("?emulateJavaCrash"), - new NativeCrashCommand("?emulateNativeCrash"), - new PushTokenCommand("?pushToken"))); + mHiddenCommands.addAll(Arrays.asList( + new BadStorageCommand("?emulateBadStorage", requireContext()), new JavaCrashCommand("?emulateJavaCrash"), + new NativeCrashCommand("?emulateNativeCrash"), new PushTokenCommand("?pushToken"))); } return mHiddenCommands; @@ -416,8 +413,8 @@ public class SearchFragment extends BaseMwmFragment final String subtitle = (result.description != null) ? result.description.localizedFeatureType : ""; final String title = TextUtils.isEmpty(result.name) ? subtitle : result.name; - final MapObject point = MapObject.createMapObject(FeatureId.EMPTY, MapObject.SEARCH, - title, subtitle, result.lat, result.lon); + final MapObject point = + MapObject.createMapObject(FeatureId.EMPTY, MapObject.SEARCH, title, subtitle, result.lat, result.lon); RoutingController.get().onPoiSelected(point); } else @@ -433,6 +430,8 @@ public class SearchFragment extends BaseMwmFragment void showAllResultsOnMap() { + SearchEngine.INSTANCE.updateViewportWithLastResults(); + // The previous search should be cancelled before the new one is started, since previous search // results are no longer needed. SearchEngine.INSTANCE.cancel(); @@ -443,8 +442,8 @@ public class SearchFragment extends BaseMwmFragment mLastQueryTimestamp = System.nanoTime(); SearchEngine.INSTANCE.searchInteractive( - query, isCategory(), !TextUtils.isEmpty(mInitialLocale) - ? mInitialLocale : app.organicmaps.util.Language.getKeyboardLocale(requireContext()), + query, isCategory(), + !TextUtils.isEmpty(mInitialLocale) ? mInitialLocale : Language.getKeyboardLocale(requireContext()), mLastQueryTimestamp, false /* isMapAndTable */); SearchEngine.INSTANCE.setQuery(query); @@ -486,13 +485,13 @@ public class SearchFragment extends BaseMwmFragment mLastQueryTimestamp = System.nanoTime(); if (isTabletSearch()) { - SearchEngine.INSTANCE.searchInteractive(requireContext(), getQuery(), isCategory(), - mLastQueryTimestamp, true /* isMapAndTable */); + SearchEngine.INSTANCE.searchInteractive(requireContext(), getQuery(), isCategory(), mLastQueryTimestamp, + true /* isMapAndTable */); } else { - if (!SearchEngine.INSTANCE.search(requireContext(), getQuery(), isCategory(), - mLastQueryTimestamp, mLastPosition.valid, mLastPosition.lat, mLastPosition.lon)) + if (!SearchEngine.INSTANCE.search(requireContext(), getQuery(), isCategory(), mLastQueryTimestamp, + mLastPosition.valid, mLastPosition.lat, mLastPosition.lon)) { return; } @@ -504,8 +503,6 @@ public class SearchFragment extends BaseMwmFragment updateFrames(); } - // Called from JNI. - @SuppressWarnings("unused") @Override public void onResultsUpdate(@NonNull SearchResult[] results, long timestamp) { @@ -515,8 +512,6 @@ public class SearchFragment extends BaseMwmFragment refreshSearchResults(results); } - // Called from JNI. - @SuppressWarnings("unused") @Override public void onResultsEnd(long timestamp) { @@ -563,7 +558,7 @@ public class SearchFragment extends BaseMwmFragment private void closeSearch() { - final Activity activity = requireActivity(); + final Activity activity = requireActivity(); activity.finish(); } @@ -593,7 +588,7 @@ public class SearchFragment extends BaseMwmFragment @Override void executeInternal() { - SharedPropertiesUtils.setShouldShowEmulateBadStorageSetting(mContext, true); + SharedPropertiesUtils.setShouldShowEmulateBadStorageSetting(true); } } @@ -634,7 +629,6 @@ public class SearchFragment extends BaseMwmFragment @Override void executeInternal() - { - } + {} } } diff --git a/android/app/src/main/java/app/organicmaps/search/SearchHistoryAdapter.java b/android/app/src/main/java/app/organicmaps/search/SearchHistoryAdapter.java index b405b66ae..df906f695 100644 --- a/android/app/src/main/java/app/organicmaps/search/SearchHistoryAdapter.java +++ b/android/app/src/main/java/app/organicmaps/search/SearchHistoryAdapter.java @@ -4,16 +4,14 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.location.LocationHelper; import app.organicmaps.routing.RoutingController; import app.organicmaps.sdk.search.SearchRecents; -import app.organicmaps.widget.SearchToolbarController; import app.organicmaps.util.Graphics; +import app.organicmaps.widget.SearchToolbarController; class SearchHistoryAdapter extends RecyclerView.Adapter { @@ -52,12 +50,14 @@ class SearchHistoryAdapter extends RecyclerView.Adapter mSearchToolbarController.setQuery(res.mText.getText())); break; case TYPE_CLEAR: - res = new ViewHolder(LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_search_clear_history, viewGroup, false)); + res = new ViewHolder( + LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_search_clear_history, viewGroup, false)); res.mText.setOnClickListener(v -> { SearchRecents.clear(); notifyDataSetChanged(); @@ -65,15 +65,16 @@ class SearchHistoryAdapter extends RecyclerView.Adapter { - RoutingController.get().onPoiSelected(LocationHelper.from(viewGroup.getContext()).getMyPosition()); + RoutingController.get().onPoiSelected( + MwmApplication.from(viewGroup.getContext()).getLocationHelper().getMyPosition()); mSearchToolbarController.onUpClick(); }); break; - default: - throw new IllegalArgumentException("Unsupported ViewHolder type given"); + default: throw new IllegalArgumentException("Unsupported ViewHolder type given"); } Graphics.tint(res.mText); diff --git a/android/app/src/main/java/app/organicmaps/search/SearchHistoryFragment.java b/android/app/src/main/java/app/organicmaps/search/SearchHistoryFragment.java index b1ea928de..82d3c29b1 100644 --- a/android/app/src/main/java/app/organicmaps/search/SearchHistoryFragment.java +++ b/android/app/src/main/java/app/organicmaps/search/SearchHistoryFragment.java @@ -2,20 +2,18 @@ package app.organicmaps.search; import android.os.Bundle; import android.view.View; - import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - +import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.base.BaseMwmRecyclerFragment; -import app.organicmaps.location.LocationHelper; import app.organicmaps.routing.RoutingController; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.widget.PlaceholderView; import app.organicmaps.widget.SearchToolbarController; -import app.organicmaps.util.UiUtils; public class SearchHistoryFragment extends BaseMwmRecyclerFragment { @@ -31,8 +29,9 @@ public class SearchHistoryFragment extends BaseMwmRecyclerFragment folderPickerLauncher; @@ -74,64 +67,61 @@ public class BackupSettingsFragment { super.onCreate(savedInstanceState); - folderPickerLauncher = registerForActivityResult( - new ActivityResultContracts.StartActivityForResult(), - result -> { - boolean isSuccess = false; + folderPickerLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { + boolean isSuccess = false; - String lastFolderPath = prefs.getString(BACKUP_FOLDER_PATH_KEY, null); + String lastFolderPath = prefs.getString(BACKUP_FOLDER_PATH_KEY, null); - if (result.getResultCode() == Activity.RESULT_OK) - { - Intent data = result.getData(); - Logger.i(TAG, "Folder selection result: " + data); - if (data == null) - return; + if (result.getResultCode() == Activity.RESULT_OK) + { + Intent data = result.getData(); + Logger.i(TAG, "Folder selection result: " + data); + if (data == null) + return; - Uri uri = data.getData(); - if (uri != null) - { - takePersistableUriPermission(uri); - Logger.i(TAG, "Backup location changed to " + uri); - prefs.edit().putString(BACKUP_FOLDER_PATH_KEY, uri.toString()).apply(); - setFormattedBackupPath(uri); + Uri uri = data.getData(); + if (uri != null) + { + takePersistableUriPermission(uri); + Logger.i(TAG, "Backup location changed to " + uri); + prefs.edit().putString(BACKUP_FOLDER_PATH_KEY, uri.toString()).apply(); + setFormattedBackupPath(uri); - runBackup(); + runBackup(); - isSuccess = true; - } - else - { - Logger.w(TAG, "Folder selection result is null"); - } - } - else if (result.getResultCode() == Activity.RESULT_CANCELED) - { - Logger.w(TAG, "User canceled folder selection"); - if (TextUtils.isEmpty(lastFolderPath)) - { - prefs.edit().putString(BACKUP_FOLDER_PATH_KEY, null).apply(); - Logger.i(TAG, "Backup settings reset"); - initBackupLocationOption(); - } - else if (isFolderWritable(requireActivity(), lastFolderPath)) - { - Logger.i(TAG, "Backup location not changed, using previous value " + lastFolderPath); - isSuccess = true; - } - else - { - Logger.e(TAG, "Backup location not changed, but last folder is not writable: " + lastFolderPath); - } - } - - resetLastBackupTime(); - updateStatusSummaryOption(); - - Logger.i(TAG, "Folder selection result: " + isSuccess); - applyAdvancedSettings(isSuccess); + isSuccess = true; } - ); + else + { + Logger.w(TAG, "Folder selection result is null"); + } + } + else if (result.getResultCode() == Activity.RESULT_CANCELED) + { + Logger.w(TAG, "User canceled folder selection"); + if (TextUtils.isEmpty(lastFolderPath)) + { + prefs.edit().putString(BACKUP_FOLDER_PATH_KEY, null).apply(); + Logger.i(TAG, "Backup settings reset"); + initBackupLocationOption(); + } + else if (isFolderWritable(requireActivity(), lastFolderPath)) + { + Logger.i(TAG, "Backup location not changed, using previous value " + lastFolderPath); + isSuccess = true; + } + else + { + Logger.e(TAG, "Backup location not changed, but last folder is not writable: " + lastFolderPath); + } + } + + resetLastBackupTime(); + updateStatusSummaryOption(); + + Logger.i(TAG, "Folder selection result: " + isSuccess); + applyAdvancedSettings(isSuccess); + }); } @Override @@ -151,7 +141,6 @@ public class BackupSettingsFragment initBackupNowOption(); } - private void initBackupLocationOption() { String storedFolderPath = prefs.getString(BACKUP_FOLDER_PATH_KEY, null); @@ -167,7 +156,8 @@ public class BackupSettingsFragment { Logger.e(TAG, "Backup location is not available, path: " + storedFolderPath); showBackupErrorAlertDialog(requireContext().getString(R.string.dialog_report_error_missing_folder)); - backupLocationOption.setSummary(requireContext().getString(R.string.pref_backup_now_summary_folder_unavailable)); + backupLocationOption.setSummary( + requireContext().getString(R.string.pref_backup_now_summary_folder_unavailable)); } } else @@ -258,7 +248,6 @@ public class BackupSettingsFragment backupNowOption.setVisible(isBackupEnabled); } - private void runBackup() { String currentFolderPath = prefs.getString(BACKUP_FOLDER_PATH_KEY, null); @@ -267,8 +256,7 @@ public class BackupSettingsFragment if (isFolderWritable(requireContext(), currentFolderPath)) { mBackupManager = new LocalBackupManager(requireActivity(), currentFolderPath, getMaxBackups(prefs)); - mBackupManager.setListener(new LocalBackupManager.Listener() - { + mBackupManager.setListener(new LocalBackupManager.Listener() { @Override public void onBackupStarted() { @@ -355,21 +343,19 @@ public class BackupSettingsFragment private void showBackupErrorAlertDialog(String message) { - requireActivity().runOnUiThread(() -> { - new MaterialAlertDialogBuilder(requireActivity()) - .setTitle(R.string.pref_backup_now_summary_failed) - .setMessage(message) - .setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss()) - .show(); - }); + requireActivity().runOnUiThread( + () + -> new MaterialAlertDialogBuilder(requireActivity()) + .setTitle(R.string.pref_backup_now_summary_failed) + .setMessage(message) + .setPositiveButton(android.R.string.ok, (dialog, which) -> dialog.dismiss()) + .show()); } private void takePersistableUriPermission(Uri uri) { requireContext().getContentResolver().takePersistableUriPermission( - uri, - Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION - ); + uri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); } @Nullable diff --git a/android/app/src/main/java/app/organicmaps/settings/BaseSettingsFragment.java b/android/app/src/main/java/app/organicmaps/settings/BaseSettingsFragment.java index 2dbfadc61..7c1f4033d 100644 --- a/android/app/src/main/java/app/organicmaps/settings/BaseSettingsFragment.java +++ b/android/app/src/main/java/app/organicmaps/settings/BaseSettingsFragment.java @@ -5,10 +5,8 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.LayoutRes; import androidx.annotation.Nullable; - import app.organicmaps.base.BaseMwmFragment; abstract class BaseSettingsFragment extends BaseMwmFragment @@ -21,16 +19,17 @@ abstract class BaseSettingsFragment extends BaseMwmFragment private void savePaddings() { - View parent = (View)mFrame.getParent(); + View parent = (View) mFrame.getParent(); if (parent != null) { - mSavedPaddings.set(parent.getPaddingStart(), parent.getPaddingTop(), parent.getPaddingEnd(), parent.getPaddingBottom()); + mSavedPaddings.set(parent.getPaddingStart(), parent.getPaddingTop(), parent.getPaddingEnd(), + parent.getPaddingBottom()); } } protected void restorePaddings() { - View parent = (View)mFrame.getParent(); + View parent = (View) mFrame.getParent(); if (parent != null) { parent.setPaddingRelative(mSavedPaddings.left, mSavedPaddings.top, mSavedPaddings.right, mSavedPaddings.bottom); @@ -59,5 +58,4 @@ abstract class BaseSettingsFragment extends BaseMwmFragment restorePaddings(); } - } diff --git a/android/app/src/main/java/app/organicmaps/settings/BaseXmlSettingsFragment.java b/android/app/src/main/java/app/organicmaps/settings/BaseXmlSettingsFragment.java index 588418503..0b8eec6bf 100644 --- a/android/app/src/main/java/app/organicmaps/settings/BaseXmlSettingsFragment.java +++ b/android/app/src/main/java/app/organicmaps/settings/BaseXmlSettingsFragment.java @@ -3,7 +3,6 @@ package app.organicmaps.settings; import android.content.Context; import android.os.Bundle; import android.view.View; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.XmlRes; @@ -12,7 +11,6 @@ import androidx.core.view.ViewCompat; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; import androidx.recyclerview.widget.RecyclerView; - import app.organicmaps.R; import app.organicmaps.util.ThemeUtils; import app.organicmaps.util.Utils; @@ -27,7 +25,7 @@ abstract class BaseXmlSettingsFragment extends PreferenceFragmentCompat { final T pref = findPreference(key); if (pref == null) - throw new RuntimeException("Can't get preference by key: "+key); + throw new RuntimeException("Can't get preference by key: " + key); return pref; } @Override diff --git a/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsActivity.java b/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsActivity.java index b98fe46f3..885bb4811 100644 --- a/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsActivity.java +++ b/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsActivity.java @@ -2,7 +2,6 @@ package app.organicmaps.settings; import android.app.Activity; import android.content.Intent; - import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; diff --git a/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsFragment.java b/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsFragment.java index 5c5f2f480..69d3a53e0 100644 --- a/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsFragment.java +++ b/android/app/src/main/java/app/organicmaps/settings/DrivingOptionsFragment.java @@ -6,16 +6,14 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.SwitchCompat; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmToolbarFragment; import app.organicmaps.routing.RoutingController; import app.organicmaps.sdk.routing.RoutingOptions; - +import app.organicmaps.sdk.settings.RoadType; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -37,8 +35,8 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment View root = inflater.inflate(R.layout.fragment_driving_options, container, false); initViews(root); mRoadTypes = savedInstanceState != null && savedInstanceState.containsKey(BUNDLE_ROAD_TYPES) - ? makeRouteTypes(savedInstanceState) - : RoutingOptions.getActiveRoadTypes(); + ? makeRouteTypes(savedInstanceState) + : RoutingOptions.getActiveRoadTypes(); return root; } @@ -92,26 +90,22 @@ public class DrivingOptionsFragment extends BaseMwmToolbarFragment { SwitchCompat tollsBtn = root.findViewById(R.id.avoid_tolls_btn); tollsBtn.setChecked(RoutingOptions.hasOption(RoadType.Toll)); - CompoundButton.OnCheckedChangeListener tollBtnListener = - new ToggleRoutingOptionListener(RoadType.Toll); + CompoundButton.OnCheckedChangeListener tollBtnListener = new ToggleRoutingOptionListener(RoadType.Toll); tollsBtn.setOnCheckedChangeListener(tollBtnListener); SwitchCompat motorwaysBtn = root.findViewById(R.id.avoid_motorways_btn); motorwaysBtn.setChecked(RoutingOptions.hasOption(RoadType.Motorway)); - CompoundButton.OnCheckedChangeListener motorwayBtnListener = - new ToggleRoutingOptionListener(RoadType.Motorway); + CompoundButton.OnCheckedChangeListener motorwayBtnListener = new ToggleRoutingOptionListener(RoadType.Motorway); motorwaysBtn.setOnCheckedChangeListener(motorwayBtnListener); SwitchCompat ferriesBtn = root.findViewById(R.id.avoid_ferries_btn); ferriesBtn.setChecked(RoutingOptions.hasOption(RoadType.Ferry)); - CompoundButton.OnCheckedChangeListener ferryBtnListener = - new ToggleRoutingOptionListener(RoadType.Ferry); + CompoundButton.OnCheckedChangeListener ferryBtnListener = new ToggleRoutingOptionListener(RoadType.Ferry); ferriesBtn.setOnCheckedChangeListener(ferryBtnListener); SwitchCompat dirtyRoadsBtn = root.findViewById(R.id.avoid_dirty_roads_btn); dirtyRoadsBtn.setChecked(RoutingOptions.hasOption(RoadType.Dirty)); - CompoundButton.OnCheckedChangeListener dirtyBtnListener = - new ToggleRoutingOptionListener(RoadType.Dirty); + CompoundButton.OnCheckedChangeListener dirtyBtnListener = new ToggleRoutingOptionListener(RoadType.Dirty); dirtyRoadsBtn.setOnCheckedChangeListener(dirtyBtnListener); } diff --git a/android/app/src/main/java/app/organicmaps/settings/SettingsActivity.java b/android/app/src/main/java/app/organicmaps/settings/SettingsActivity.java index c96eab3b9..461b282e2 100644 --- a/android/app/src/main/java/app/organicmaps/settings/SettingsActivity.java +++ b/android/app/src/main/java/app/organicmaps/settings/SettingsActivity.java @@ -2,18 +2,16 @@ package app.organicmaps.settings; import android.os.Bundle; import android.text.TextUtils; - import androidx.fragment.app.Fragment; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceScreen; - import app.organicmaps.R; import app.organicmaps.base.BaseToolbarActivity; -public class SettingsActivity extends BaseToolbarActivity - implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback, - PreferenceFragmentCompat.OnPreferenceStartScreenCallback +public class SettingsActivity + extends BaseToolbarActivity implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback, + PreferenceFragmentCompat.OnPreferenceStartScreenCallback { @Override protected int getContentLayoutResId() @@ -36,7 +34,8 @@ public class SettingsActivity extends BaseToolbarActivity { Class fragment = (Class) Class.forName(pref.getFragment()); stackFragment(fragment, title, pref.getExtras()); - } catch (ClassNotFoundException e) + } + catch (ClassNotFoundException e) { e.printStackTrace(); } @@ -44,7 +43,8 @@ public class SettingsActivity extends BaseToolbarActivity } @Override - public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat, PreferenceScreen preferenceScreen) + public boolean onPreferenceStartScreen(PreferenceFragmentCompat preferenceFragmentCompat, + PreferenceScreen preferenceScreen) { Bundle args = new Bundle(); args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.getKey()); diff --git a/android/app/src/main/java/app/organicmaps/settings/SettingsPrefsFragment.java b/android/app/src/main/java/app/organicmaps/settings/SettingsPrefsFragment.java index 3e50ea039..0e75ecb04 100644 --- a/android/app/src/main/java/app/organicmaps/settings/SettingsPrefsFragment.java +++ b/android/app/src/main/java/app/organicmaps/settings/SettingsPrefsFragment.java @@ -10,7 +10,6 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.view.View; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; @@ -20,36 +19,35 @@ import androidx.preference.MultiSelectListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; import androidx.preference.TwoStatePreference; -import app.organicmaps.Framework; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.downloader.MapManager; import app.organicmaps.downloader.OnmapDownloader; -import app.organicmaps.editor.OsmOAuth; import app.organicmaps.editor.LanguagesFragment; import app.organicmaps.editor.ProfileActivity; -import app.organicmaps.editor.data.Language; -import app.organicmaps.help.HelpActivity; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.LocationProviderFactory; -import app.organicmaps.sdk.routing.RoutingOptions; import app.organicmaps.leftbutton.LeftButton; import app.organicmaps.leftbutton.LeftButtonsHolder; -import app.organicmaps.util.Config; -import app.organicmaps.util.NetworkPolicy; -import app.organicmaps.util.PowerManagment; -import app.organicmaps.util.SharedPropertiesUtils; -import app.organicmaps.util.ThemeSwitcher; -import app.organicmaps.util.Utils; -import app.organicmaps.util.log.LogsManager; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.editor.OsmOAuth; +import app.organicmaps.sdk.editor.data.Language; +import app.organicmaps.sdk.location.LocationHelper; +import app.organicmaps.sdk.location.LocationProviderFactory; +import app.organicmaps.sdk.routing.RoutingOptions; import app.organicmaps.sdk.search.SearchRecents; -import app.organicmaps.traffxml.AndroidTransport; +import app.organicmaps.sdk.settings.MapLanguageCode; +import app.organicmaps.sdk.settings.UnitLocale; +import app.organicmaps.sdk.traffxml.AndroidTransport; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.NetworkPolicy; +import app.organicmaps.sdk.util.PowerManagment; +import app.organicmaps.sdk.util.SharedPropertiesUtils; +import app.organicmaps.sdk.util.ThemeSwitcher; +import app.organicmaps.sdk.util.log.LogsManager; +import app.organicmaps.util.Utils; import com.google.android.material.dialog.MaterialAlertDialogBuilder; - import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; import java.util.List; import java.util.Locale; import java.util.Set; @@ -202,9 +200,9 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La private void updateProfileSettingsPrefsSummary() { final Preference pref = getPreference(getString(R.string.pref_osm_profile)); - if (OsmOAuth.isAuthorized(requireContext())) + if (OsmOAuth.isAuthorized()) { - final String username = OsmOAuth.getUsername(requireContext()); + final String username = OsmOAuth.getUsername(); pref.setSummary(username); } else @@ -236,11 +234,13 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La } else if (key.equals(getString(R.string.pref_tts_screen))) { - getSettingsActivity().stackFragment(VoiceInstructionsSettingsFragment.class, getString(R.string.pref_tts_enable_title), null); + getSettingsActivity().stackFragment(VoiceInstructionsSettingsFragment.class, + getString(R.string.pref_tts_enable_title), null); } else if (key.equals(getString(R.string.pref_map_locale))) { - LanguagesFragment langFragment = (LanguagesFragment)getSettingsActivity().stackFragment(LanguagesFragment.class, getString(R.string.change_map_locale), null); + LanguagesFragment langFragment = (LanguagesFragment) getSettingsActivity().stackFragment( + LanguagesFragment.class, getString(R.string.change_map_locale), null); langFragment.setListener(this); } else if (key.equals(getString(R.string.pref_backup))) @@ -255,7 +255,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La { final Preference pref = getPreference(getString(R.string.pref_large_fonts_size)); - ((TwoStatePreference)pref).setChecked(Config.isLargeFontsSize()); + ((TwoStatePreference) pref).setChecked(Config.isLargeFontsSize()); pref.setOnPreferenceChangeListener((preference, newValue) -> { final boolean oldVal = Config.isLargeFontsSize(); final boolean newVal = (Boolean) newValue; @@ -270,7 +270,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La { final Preference pref = getPreference(getString(R.string.pref_transliteration)); - ((TwoStatePreference)pref).setChecked(Config.isTransliteration()); + ((TwoStatePreference) pref).setChecked(Config.isTransliteration()); pref.setOnPreferenceChangeListener((preference, newValue) -> { final boolean oldVal = Config.isTransliteration(); final boolean newVal = (Boolean) newValue; @@ -372,7 +372,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La NetworkPolicy.Type curValue = Config.getUseMobileDataSettings(); if (curValue == NetworkPolicy.Type.NOT_TODAY || curValue == NetworkPolicy.Type.TODAY) - curValue = NetworkPolicy.Type.ASK; + curValue = NetworkPolicy.Type.ASK; mobilePref.setValue(curValue.name()); mobilePref.setOnPreferenceChangeListener((preference, newValue) -> { final String valueStr = (String) newValue; @@ -390,8 +390,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La int curValue = PowerManagment.getScheme(); powerManagementPref.setValue(String.valueOf(curValue)); - powerManagementPref.setOnPreferenceChangeListener((preference, newValue) -> - { + powerManagementPref.setOnPreferenceChangeListener((preference, newValue) -> { @PowerManagment.SchemeType int scheme = Integer.parseInt((String) newValue); @@ -425,7 +424,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La if (pref == null) return; - if (!SharedPropertiesUtils.shouldShowEmulateBadStorageSetting(requireContext())) + if (!SharedPropertiesUtils.shouldShowEmulateBadStorageSetting()) removePreference(getString(R.string.pref_settings_general), pref); else pref.setVisible(true); @@ -454,13 +453,12 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La else { ((TwoStatePreference) pref).setChecked(Config.useGoogleServices()); - pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() - { + pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @SuppressLint("MissingPermission") @Override public boolean onPreferenceChange(@NonNull Preference preference, Object newValue) { - final LocationHelper locationHelper = LocationHelper.from(requireContext()); + final LocationHelper locationHelper = MwmApplication.from(requireContext()).getLocationHelper(); boolean oldVal = Config.useGoogleServices(); boolean newVal = (Boolean) newValue; if (oldVal != newVal) @@ -510,13 +508,14 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La // Read power managements preference. final ListPreference powerManagementPref = getPreference(getString(R.string.pref_power_management)); final String powerManagementValueStr = powerManagementPref.getValue(); - final Integer powerManagementValue = (powerManagementValueStr!=null) ? Integer.parseInt(powerManagementValueStr) : null; + final Integer powerManagementValue = + (powerManagementValueStr != null) ? Integer.parseInt(powerManagementValueStr) : null; disableOrEnable3DBuildingsForPowerMode(powerManagementValue); pref.setOnPreferenceChangeListener((preference, newValue) -> { Framework.Params3dMode current = new Framework.Params3dMode(); Framework.nativeGet3dMode(current); - Framework.nativeSet3dMode(current.enabled, (Boolean)newValue); + Framework.nativeSet3dMode(current.enabled, (Boolean) newValue); return true; }); } @@ -603,7 +602,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La { final Preference pref = getPreference(getString(R.string.pref_show_zoom_buttons)); - ((TwoStatePreference)pref).setChecked(Config.showZoomButtons()); + ((TwoStatePreference) pref).setChecked(Config.showZoomButtons()); pref.setOnPreferenceChangeListener((preference, newValue) -> { Config.setShowZoomButtons((boolean) newValue); return true; @@ -614,7 +613,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La { final Preference pref = getPreference(getString(R.string.pref_munits)); - ((ListPreference)pref).setValue(String.valueOf(UnitLocale.getUnits())); + ((ListPreference) pref).setValue(String.valueOf(UnitLocale.getUnits())); pref.setOnPreferenceChangeListener((preference, newValue) -> { UnitLocale.setUnits(Integer.parseInt((String) newValue)); return true; @@ -648,8 +647,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La final boolean isKeepScreenOnEnabled = Config.isKeepScreenOnEnabled(); ((TwoStatePreference) pref).setChecked(isKeepScreenOnEnabled); - pref.setOnPreferenceChangeListener((preference, newValue) -> - { + pref.setOnPreferenceChangeListener((preference, newValue) -> { boolean newVal = (Boolean) newValue; if (isKeepScreenOnEnabled != newVal) { @@ -666,8 +664,7 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La final boolean isShowOnLockScreenEnabled = Config.isShowOnLockScreenEnabled(); ((TwoStatePreference) pref).setChecked(isShowOnLockScreenEnabled); - pref.setOnPreferenceChangeListener((preference, newValue) -> - { + pref.setOnPreferenceChangeListener((preference, newValue) -> { boolean newVal = (Boolean) newValue; if (isShowOnLockScreenEnabled != newVal) { @@ -717,11 +714,4 @@ public class SettingsPrefsFragment extends BaseXmlSettingsFragment implements La return AUTO; } } - - public enum SpeedCameraMode - { - AUTO, - ALWAYS, - NEVER - } } diff --git a/android/app/src/main/java/app/organicmaps/settings/StoragePathAdapter.java b/android/app/src/main/java/app/organicmaps/settings/StoragePathAdapter.java index ba4e30346..13dca24dc 100644 --- a/android/app/src/main/java/app/organicmaps/settings/StoragePathAdapter.java +++ b/android/app/src/main/java/app/organicmaps/settings/StoragePathAdapter.java @@ -10,10 +10,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckedTextView; - import app.organicmaps.R; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.UiUtils; class StoragePathAdapter extends BaseAdapter { @@ -57,22 +56,22 @@ class StoragePathAdapter extends BaseAdapter checkedView.setChecked(isCurrent); checkedView.setEnabled(!item.mIsReadonly && (isStorageBigEnough(position) || isCurrent)); - final String size = mActivity.getString(R.string.maps_storage_free_size, - Formatter.formatShortFileSize(mActivity, item.mFreeSize), - Formatter.formatShortFileSize(mActivity, item.mTotalSize)); + final String size = + mActivity.getString(R.string.maps_storage_free_size, Formatter.formatShortFileSize(mActivity, item.mFreeSize), + Formatter.formatShortFileSize(mActivity, item.mTotalSize)); SpannableStringBuilder sb = new SpannableStringBuilder(item.mLabel + "\n" + size); sb.setSpan(new ForegroundColorSpan(ThemeUtils.getColor(mActivity, android.R.attr.textColorSecondary)), sb.length() - size.length(), sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - sb.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(mActivity, R.dimen.text_size_body_3)), - sb.length() - size.length(), sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + sb.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(mActivity, R.dimen.text_size_body_3)), sb.length() - size.length(), + sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); final String path = item.mPath + (item.mIsReadonly ? " (read-only)" : ""); sb.append("\n").append(path); sb.setSpan(new ForegroundColorSpan(ThemeUtils.getColor(mActivity, android.R.attr.textColorSecondary)), sb.length() - path.length(), sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - sb.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(mActivity, R.dimen.text_size_body_4)), - sb.length() - path.length(), sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + sb.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(mActivity, R.dimen.text_size_body_4)), sb.length() - path.length(), + sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); checkedView.setText(sb); diff --git a/android/app/src/main/java/app/organicmaps/settings/StoragePathFragment.java b/android/app/src/main/java/app/organicmaps/settings/StoragePathFragment.java index 555996614..88001de91 100644 --- a/android/app/src/main/java/app/organicmaps/settings/StoragePathFragment.java +++ b/android/app/src/main/java/app/organicmaps/settings/StoragePathFragment.java @@ -8,27 +8,24 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ListView; -import android.widget.TextView; - import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.NonNull; - -import app.organicmaps.Framework; import app.organicmaps.R; -import app.organicmaps.util.Config; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.StorageUtils; +import app.organicmaps.sdk.util.concurrency.ThreadPool; +import app.organicmaps.sdk.util.concurrency.UiThread; import app.organicmaps.util.SharingUtils; -import app.organicmaps.util.StorageUtils; import app.organicmaps.util.Utils; -import app.organicmaps.util.concurrency.ThreadPool; -import app.organicmaps.util.concurrency.UiThread; import com.google.android.material.dialog.MaterialAlertDialogBuilder; - +import com.google.android.material.textview.MaterialTextView; import java.io.File; import java.util.List; public class StoragePathFragment extends BaseSettingsFragment { - private TextView mHeader; + private MaterialTextView mHeader; private StoragePathAdapter mAdapter; private StoragePathManager mPathManager; @@ -77,7 +74,8 @@ public class StoragePathFragment extends BaseSettingsFragment { final long dirSize = StorageUtils.getDirSizeRecursively(new File(Framework.nativeGetWritableDir()), StoragePathManager.MOVABLE_FILES_FILTER); - mHeader.setText(getString(R.string.maps_storage_downloaded) + ": " + Formatter.formatShortFileSize(requireActivity(), dirSize)); + mHeader.setText(getString(R.string.maps_storage_downloaded) + ": " + + Formatter.formatShortFileSize(requireActivity(), dirSize)); mAdapter.update(dirSize); } @@ -135,7 +133,8 @@ public class StoragePathFragment extends BaseSettingsFragment { new MaterialAlertDialogBuilder(requireActivity(), R.style.MwmTheme_AlertDialog) .setTitle(R.string.move_maps_error) - .setPositiveButton(R.string.report_a_bug, + .setPositiveButton( + R.string.report_a_bug, (dlg, which) -> Utils.sendBugReport(shareLauncher, requireActivity(), "Error moving map files", "")) .show(); } diff --git a/android/app/src/main/java/app/organicmaps/settings/StoragePathManager.java b/android/app/src/main/java/app/organicmaps/settings/StoragePathManager.java index 3cc28453f..d22f93193 100644 --- a/android/app/src/main/java/app/organicmaps/settings/StoragePathManager.java +++ b/android/app/src/main/java/app/organicmaps/settings/StoragePathManager.java @@ -9,16 +9,14 @@ import android.os.Environment; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import android.text.TextUtils; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import app.organicmaps.Framework; import app.organicmaps.R; -import app.organicmaps.downloader.MapManager; -import app.organicmaps.util.Config; -import app.organicmaps.util.StorageUtils; -import app.organicmaps.util.log.Logger; - +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.StorageUtils; +import app.organicmaps.sdk.util.log.Logger; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; @@ -30,7 +28,8 @@ public class StoragePathManager private static final String TAG = StoragePathManager.class.getSimpleName(); private static final String DATA_FILE_EXT = Framework.nativeGetDataFileExt(); private static final String[] MOVABLE_EXTS = Framework.nativeGetMovableFilesExts(); - static final FilenameFilter MOVABLE_FILES_FILTER = (dir, filename) -> { + static final FilenameFilter MOVABLE_FILES_FILTER = (dir, filename) -> + { for (String ext : MOVABLE_EXTS) if (filename.endsWith(ext)) return true; @@ -71,8 +70,7 @@ public class StoragePathManager public void startExternalStorageWatching(final @Nullable OnStorageListChangedListener storagesChangedListener) { mStoragesChangedListener = storagesChangedListener; - mInternalReceiver = new BroadcastReceiver() - { + mInternalReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -146,11 +144,10 @@ public class StoragePathManager final long totalSize = dir.getTotalSpace(); final long freeSize = dir.getUsableSpace(); - String commentedPath = path + (StorageUtils.addTrailingSeparator(dir.getPath()).equals(path) - ? "" : " (" + dir.getPath() + ")") + " - " + - (isCurrent ? "currently configured, " : "") + - (isInternal ? "internal" : "external") + ", " + - freeSize + " available of " + totalSize + " bytes"; + String commentedPath = + path + (StorageUtils.addTrailingSeparator(dir.getPath()).equals(path) ? "" : " (" + dir.getPath() + ")") + " - " + + (isCurrent ? "currently configured, " : "") + (isInternal ? "internal" : "external") + ", " + freeSize + + " available of " + totalSize + " bytes"; boolean isEmulated = false; boolean isRemovable = false; @@ -164,9 +161,8 @@ public class StoragePathManager isEmulated = Environment.isExternalStorageEmulated(dir); isRemovable = Environment.isExternalStorageRemovable(dir); state = Environment.getExternalStorageState(dir); - commentedPath += (isEmulated ? ", emulated" : "") + - (isRemovable ? ", removable" : "") + - (state != null ? ", state=" + state : ""); + commentedPath += (isEmulated ? ", emulated" : "") + (isRemovable ? ", removable" : "") + + (state != null ? ", state=" + state : ""); } catch (IllegalArgumentException e) { @@ -185,9 +181,9 @@ public class StoragePathManager if (sv != null) { label = sv.getDescription(mContext); - commentedPath += (sv.isPrimary() ? ", primary" : "") + - (!TextUtils.isEmpty(sv.getUuid()) ? ", uuid=" + sv.getUuid() : "") + - (!TextUtils.isEmpty(label) ? ", label='" + label + "'" : ""); + commentedPath += (sv.isPrimary() ? ", primary" : "") + + (!TextUtils.isEmpty(sv.getUuid()) ? ", uuid=" + sv.getUuid() : "") + + (!TextUtils.isEmpty(label) ? ", label='" + label + "'" : ""); } else Logger.w(TAG, "Can't get StorageVolume for " + commentedPath); @@ -197,8 +193,7 @@ public class StoragePathManager } } - if (state != null && !Environment.MEDIA_MOUNTED.equals(state) - && !Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) + if (state != null && !Environment.MEDIA_MOUNTED.equals(state) && !Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { Logger.w(TAG, "Not mounted: " + commentedPath); return; @@ -280,7 +275,9 @@ public class StoragePathManager */ private static boolean containsMapData(String storagePath) { - return StorageUtils.getDirSizeRecursively(new File(storagePath), (dir, filename) -> filename.endsWith(DATA_FILE_EXT)) > 0; + return StorageUtils.getDirSizeRecursively(new File(storagePath), + (dir, filename) -> filename.endsWith(DATA_FILE_EXT)) + > 0; } /** @@ -292,8 +289,8 @@ public class StoragePathManager StorageItem res = null; for (StorageItem storage : mStorages) { - if ((res == null || res.mFreeSize < storage.mFreeSize) - && !storage.mIsReadonly && !storage.equals(mInternalStorage)) + if ((res == null || res.mFreeSize < storage.mFreeSize) && !storage.mIsReadonly + && !storage.equals(mInternalStorage)) res = storage; } diff --git a/android/app/src/main/java/app/organicmaps/settings/VoiceInstructionsSettingsFragment.java b/android/app/src/main/java/app/organicmaps/settings/VoiceInstructionsSettingsFragment.java index 1bb101a39..1c198c69c 100644 --- a/android/app/src/main/java/app/organicmaps/settings/VoiceInstructionsSettingsFragment.java +++ b/android/app/src/main/java/app/organicmaps/settings/VoiceInstructionsSettingsFragment.java @@ -11,7 +11,6 @@ import android.text.SpannableString; import android.text.style.ForegroundColorSpan; import android.view.View; import android.widget.Toast; - import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; @@ -21,15 +20,14 @@ import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.SeekBarPreference; import androidx.preference.TwoStatePreference; - -import app.organicmaps.Framework; import app.organicmaps.R; -import app.organicmaps.sound.LanguageData; -import app.organicmaps.sound.TtsPlayer; -import app.organicmaps.util.Config; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.settings.SpeedCameraMode; +import app.organicmaps.sdk.sound.LanguageData; +import app.organicmaps.sdk.sound.TtsPlayer; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Utils; - import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -38,7 +36,6 @@ import java.util.Map; public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment { - @NonNull @SuppressWarnings("NotNullFieldNotInitialized") private TwoStatePreference mTtsPrefEnabled; @@ -69,15 +66,16 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment private LanguageData mCurrentLanguage; private String mSelectedLanguage; - private final ActivityResultLauncher startInstallDataIntentForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { + private final ActivityResultLauncher startInstallDataIntentForResult = + registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), activityResult -> { + if (activityResult.getResultCode() == Activity.RESULT_OK) + { + onInstallDataResult(); + } + }); - if(activityResult.getResultCode() == Activity.RESULT_OK) - { - onInstallDataResult(); - } - }); - - private final Preference.OnPreferenceChangeListener mEnabledListener = (preference, newValue) -> { + private final Preference.OnPreferenceChangeListener mEnabledListener = (preference, newValue) -> + { final boolean set = (Boolean) newValue; if (!set) { @@ -105,7 +103,8 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment return false; }; - private final Preference.OnPreferenceChangeListener mLangListener = (preference, newValue) -> { + private final Preference.OnPreferenceChangeListener mLangListener = (preference, newValue) -> + { if (newValue == null) return false; @@ -117,12 +116,14 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment if (lang.downloaded) setLanguage(lang); else - UiUtils.startActivityForResult(startInstallDataIntentForResult, new Intent(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA)); + UiUtils.startActivityForResult(startInstallDataIntentForResult, + new Intent(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA)); return false; }; - private final Preference.OnPreferenceChangeListener mStreetNameListener = (preference, newValue) -> { + private final Preference.OnPreferenceChangeListener mStreetNameListener = (preference, newValue) -> + { boolean set = (Boolean) newValue; Config.TTS.setAnnounceStreets(set); @@ -149,13 +150,12 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment mTtsOpenSystemSettings.setOnPreferenceClickListener(pref -> { try { - final Intent intent = new Intent() - .setAction("com.android.settings.TTS_SETTINGS") - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + final Intent intent = + new Intent().setAction("com.android.settings.TTS_SETTINGS").setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); return true; } - catch(ActivityNotFoundException e) + catch (ActivityNotFoundException e) { CharSequence noTtsSettingString = getString(R.string.pref_tts_no_system_tts); Toast.makeText(super.getSettingsActivity(), noTtsSettingString, Toast.LENGTH_LONG).show(); @@ -176,7 +176,8 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment return true; }); - TtsPlayer.sOnReloadCallback = () -> { + TtsPlayer.sOnReloadCallback = () -> + { Toast.makeText(requireContext(), "TTS engine reloaded", Toast.LENGTH_SHORT).show(); updateTts(); }; @@ -253,8 +254,7 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment } final boolean enabled = TtsPlayer.isEnabled(); - mTtsLangInfo.setSummary(enabled ? R.string.prefs_languages_information - : R.string.prefs_languages_information_off); + mTtsLangInfo.setSummary(enabled ? R.string.prefs_languages_information : R.string.prefs_languages_information_off); final CharSequence[] entries = new CharSequence[languages.size()]; final CharSequence[] values = new CharSequence[languages.size()]; @@ -285,7 +285,8 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment // Update array of TTS test strings. Strings are taken from resources using selected TTS language. final Configuration config = new Configuration(getResources().getConfiguration()); config.setLocale(mCurrentLanguage.locale); - mTtsTestStringArray = Arrays.asList(requireContext().createConfigurationContext(config).getResources().getStringArray(R.array.app_tips)); + mTtsTestStringArray = Arrays.asList( + requireContext().createConfigurationContext(config).getResources().getStringArray(R.array.app_tips)); Collections.shuffle(mTtsTestStringArray); mTestStringIndex = 0; } @@ -325,8 +326,9 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment final String ttsLinkText = getString(R.string.prefs_languages_information_off_link); final Spannable link = new SpannableString(ttsLinkText + "↗"); // Set link color. - link.setSpan(new ForegroundColorSpan(ContextCompat.getColor(requireContext(), - UiUtils.getStyledResourceId(requireContext(), androidx.appcompat.R.attr.colorAccent))), + link.setSpan( + new ForegroundColorSpan(ContextCompat.getColor( + requireContext(), UiUtils.getStyledResourceId(requireContext(), androidx.appcompat.R.attr.colorAccent))), 0, ttsLinkText.length(), 0); ttsLangInfoLink.setSummary(link); @@ -343,7 +345,7 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment pref.setSummary(pref.getEntry()); pref.setOnPreferenceChangeListener((preference, newValue) -> { final String speedCamModeValue = (String) newValue; - final SettingsPrefsFragment.SpeedCameraMode newCamMode = SettingsPrefsFragment.SpeedCameraMode.valueOf(speedCamModeValue); + final SpeedCameraMode newCamMode = SpeedCameraMode.valueOf(speedCamModeValue); final CharSequence summary = pref.getEntries()[newCamMode.ordinal()]; pref.setSummary(summary); if (pref.getValue().equals(newValue)) @@ -354,7 +356,7 @@ public class VoiceInstructionsSettingsFragment extends BaseXmlSettingsFragment }); } - private void onSpeedCamerasPrefChanged(@NonNull SettingsPrefsFragment.SpeedCameraMode newCamMode) + private void onSpeedCamerasPrefChanged(@NonNull SpeedCameraMode newCamMode) { Framework.setSpeedCamerasMode(newCamMode); } diff --git a/android/app/src/main/java/app/organicmaps/util/Graphics.java b/android/app/src/main/java/app/organicmaps/util/Graphics.java index 811ca8e04..98a44700b 100644 --- a/android/app/src/main/java/app/organicmaps/util/Graphics.java +++ b/android/app/src/main/java/app/organicmaps/util/Graphics.java @@ -12,7 +12,6 @@ import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.widget.TextView; - import androidx.annotation.AttrRes; import androidx.annotation.ColorInt; import androidx.annotation.DimenRes; @@ -20,9 +19,7 @@ import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.graphics.drawable.DrawableCompat; - import app.organicmaps.R; - import java.util.Objects; public final class Graphics @@ -45,9 +42,8 @@ public final class Graphics } @NonNull - public static Drawable drawCircleAndImage(int color, @DimenRes int sizeResId, - @DrawableRes int imageResId, @DimenRes int sizeImgResId, - @NonNull Context context) + public static Drawable drawCircleAndImage(int color, @DimenRes int sizeResId, @DrawableRes int imageResId, + @DimenRes int sizeImgResId, @NonNull Context context) { final Resources res = context.getResources(); final int size = res.getDimensionPixelSize(sizeResId); @@ -92,7 +88,7 @@ public final class Graphics public static Drawable tint(Context context, @DrawableRes int resId, @AttrRes int tintAttr) { - //noinspection deprecation + // noinspection deprecation return tint(context, AppCompatResources.getDrawable(context, resId), tintAttr); } diff --git a/android/app/src/main/java/app/organicmaps/util/InputUtils.java b/android/app/src/main/java/app/organicmaps/util/InputUtils.java index 6ca34a74c..6bdc550af 100644 --- a/android/app/src/main/java/app/organicmaps/util/InputUtils.java +++ b/android/app/src/main/java/app/organicmaps/util/InputUtils.java @@ -6,18 +6,18 @@ import android.speech.RecognizerIntent; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; - import androidx.annotation.NonNull; - -import app.organicmaps.util.concurrency.UiThread; - +import app.organicmaps.sdk.util.Utils; +import app.organicmaps.sdk.util.concurrency.UiThread; import java.util.ArrayList; public class InputUtils { private static Boolean mVoiceInputSupported = null; - private InputUtils() { /* static class */ } + private InputUtils() + { /* static class */ + } public static boolean isVoiceInputSupported(@NonNull Context context) { @@ -31,7 +31,7 @@ public class InputUtils { final Intent vrIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); vrIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH) - .putExtra(RecognizerIntent.EXTRA_PROMPT, promptText); + .putExtra(RecognizerIntent.EXTRA_PROMPT, promptText); return vrIntent; } @@ -41,8 +41,7 @@ public class InputUtils */ public static String getBestRecognitionResult(Intent vrIntentResult) { - final ArrayList recognizedStrings - = vrIntentResult.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); + final ArrayList recognizedStrings = vrIntentResult.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); if (recognizedStrings == null) return null; @@ -53,7 +52,7 @@ public class InputUtils private static void showKeyboardSync(final View input) { if (input != null) - ((InputMethodManager)input.getContext().getSystemService(Context.INPUT_METHOD_SERVICE)) + ((InputMethodManager) input.getContext().getSystemService(Context.INPUT_METHOD_SERVICE)) .showSoftInput(input, InputMethodManager.SHOW_IMPLICIT); } @@ -72,7 +71,7 @@ public class InputUtils public static void hideKeyboard(View view) { - InputMethodManager imm = (InputMethodManager)view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } diff --git a/android/app/src/main/java/app/organicmaps/util/RtlUtils.java b/android/app/src/main/java/app/organicmaps/util/RtlUtils.java index afd5b8930..b138cad17 100644 --- a/android/app/src/main/java/app/organicmaps/util/RtlUtils.java +++ b/android/app/src/main/java/app/organicmaps/util/RtlUtils.java @@ -2,25 +2,24 @@ package app.organicmaps.util; import android.app.Activity; import android.view.View; - import androidx.annotation.NonNull; import androidx.core.text.TextUtilsCompat; - import java.util.Arrays; import java.util.List; import java.util.Locale; public class RtlUtils { - private final static List rtlLocalesWithTranslation = Arrays.asList("ar", "fa"); + private final static List rtlLocalesWithTranslation = Arrays.asList("ar", "fa"); - public static void manageRtl(@NonNull final Activity activity) - { - final String currentLanguage = Locale.getDefault().getLanguage(); - final boolean isRTL = TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL; - if (isRTL && rtlLocalesWithTranslation.contains(currentLanguage)) - activity.getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL); - else - activity.getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_LTR); - } + public static void manageRtl(@NonNull final Activity activity) + { + final String currentLanguage = Locale.getDefault().getLanguage(); + final boolean isRTL = + TextUtilsCompat.getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL; + if (isRTL && rtlLocalesWithTranslation.contains(currentLanguage)) + activity.getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_RTL); + else + activity.getWindow().getDecorView().setLayoutDirection(View.LAYOUT_DIRECTION_LTR); + } } diff --git a/android/app/src/main/java/app/organicmaps/util/SharedPropertiesUtils.java b/android/app/src/main/java/app/organicmaps/util/SharedPropertiesUtils.java deleted file mode 100644 index 12ad4059a..000000000 --- a/android/app/src/main/java/app/organicmaps/util/SharedPropertiesUtils.java +++ /dev/null @@ -1,92 +0,0 @@ -package app.organicmaps.util; - -import static app.organicmaps.util.Config.KEY_PREF_STATISTICS; - -import android.content.Context; -import android.content.SharedPreferences; - -import androidx.annotation.NonNull; -import androidx.preference.PreferenceManager; - -import app.organicmaps.MwmApplication; -import app.organicmaps.R; -import app.organicmaps.maplayer.Mode; - -import java.io.IOException; -import java.util.Locale; - -public final class SharedPropertiesUtils -{ - private static final String PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING = "ShowEmulateBadStorageSetting"; - private static final String PREFS_SHOULD_SHOW_LAYER_MARKER_FOR = "ShouldShowGuidesLayerMarkerFor"; - - //Utils class - private SharedPropertiesUtils() - { - throw new IllegalStateException("Try instantiate utility class SharedPropertiesUtils"); - } - - public static boolean isStatisticsEnabled(@NonNull Context context) - { - return MwmApplication.prefs(context).getBoolean(KEY_PREF_STATISTICS, true); - } - - public static void setShouldShowEmulateBadStorageSetting(@NonNull Context context, boolean show) - { - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(MwmApplication.from(context)); - prefs.edit().putBoolean(PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING, show).apply(); - } - - public static boolean shouldShowEmulateBadStorageSetting(@NonNull Context context) - { - SharedPreferences prefs = PreferenceManager - .getDefaultSharedPreferences(MwmApplication.from(context)); - return prefs.getBoolean(PREFS_SHOW_EMULATE_BAD_STORAGE_SETTING, false); - } - - /** - * @param context context - * @throws IOException if "Emulate bad storage" is enabled in preferences - */ - public static void emulateBadExternalStorage(@NonNull Context context) throws IOException - { - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(MwmApplication.from(context)); - String key = MwmApplication.from(context).getString(R.string.pref_emulate_bad_external_storage); - if (prefs.getBoolean(key, false)) - { - // Emulate one time only -> reset setting to run normally next time. - prefs.edit().putBoolean(key, false).apply(); - throw new IOException("Bad external storage error injection"); - } - } - - public static boolean shouldShowNewMarkerForLayerMode(@NonNull Context context, - @NonNull Mode mode) - { - return switch (mode) - { - case SUBWAY, TRAFFIC, ISOLINES -> false; - default -> getBoolean(context, PREFS_SHOULD_SHOW_LAYER_MARKER_FOR + mode.name().toLowerCase(Locale.ENGLISH), true); - }; - } - - public static void setLayerMarkerShownForLayerMode(@NonNull Context context, @NonNull Mode mode) - { - putBoolean(context, PREFS_SHOULD_SHOW_LAYER_MARKER_FOR + mode.name() - .toLowerCase(Locale.ENGLISH), false); - } - - private static boolean getBoolean(@NonNull Context context, @NonNull String key, boolean defValue) - { - return MwmApplication.prefs(context).getBoolean(key, defValue); - } - - private static void putBoolean(@NonNull Context context, @NonNull String key, boolean value) - { - MwmApplication.prefs(context) - .edit() - .putBoolean(key, value) - .apply(); - } -} diff --git a/android/app/src/main/java/app/organicmaps/util/SharingUtils.java b/android/app/src/main/java/app/organicmaps/util/SharingUtils.java index 076890872..ec0056330 100644 --- a/android/app/src/main/java/app/organicmaps/util/SharingUtils.java +++ b/android/app/src/main/java/app/organicmaps/util/SharingUtils.java @@ -2,33 +2,32 @@ package app.organicmaps.util; import android.app.Activity; import android.content.ClipData; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; -import android.content.ComponentName; import android.location.Location; import android.net.Uri; import android.os.Build; import android.text.TextUtils; import android.util.Pair; - import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContract; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; - +import app.organicmaps.R; +import app.organicmaps.SplashActivity; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.bookmarks.data.BookmarkInfo; +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.util.StorageUtils; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.log.Logger; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import app.organicmaps.Framework; -import app.organicmaps.R; -import app.organicmaps.SplashActivity; -import app.organicmaps.bookmarks.data.BookmarkInfo; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.util.log.Logger; - public class SharingUtils { private static final String TAG = SharingUtils.class.getSimpleName(); @@ -44,9 +43,7 @@ public class SharingUtils public String mMail = ""; public String mFileName = ""; - ShareInfo() - { - } + ShareInfo() {} ShareInfo(@NonNull String mimeType, String subject, String text, String mail, String fileName) { @@ -79,11 +76,17 @@ public class SharingUtils mSource = source; } - Intent GetIntent() {return mIntent;} - Uri GetSourceFile() {return mSource;} + Intent GetIntent() + { + return mIntent; + } + Uri GetSourceFile() + { + return mSource; + } } - public static class SharingContract extends ActivityResultContract> + public static class SharingContract extends ActivityResultContract> { static private Uri sourceUri; @@ -96,7 +99,7 @@ public class SharingUtils } @Override - public Pair parseResult(int resultCode, Intent intent) + public Pair parseResult(int resultCode, Intent intent) { if (resultCode == Activity.RESULT_OK && intent != null) { @@ -108,9 +111,7 @@ public class SharingUtils } // This utility class has only static methods - private SharingUtils() - { - } + private SharingUtils() {} public static void shareLocation(@NonNull Context context, @NonNull Location loc) { @@ -120,10 +121,10 @@ public class SharingUtils final String subject = context.getString(R.string.share); intent.putExtra(Intent.EXTRA_SUBJECT, subject); - final String geoUrl = Framework.nativeGetGeoUri(loc.getLatitude(), loc.getLongitude(), Framework - .nativeGetDrawScale(), ""); - final String httpUrl = Framework.getHttpGe0Url(loc.getLatitude(), loc.getLongitude(), Framework - .nativeGetDrawScale(), ""); + final String geoUrl = + Framework.nativeGetGeoUri(loc.getLatitude(), loc.getLongitude(), Framework.nativeGetDrawScale(), ""); + final String httpUrl = + Framework.getHttpGe0Url(loc.getLatitude(), loc.getLongitude(), Framework.nativeGetDrawScale(), ""); final String text = geoUrl + "\n" + httpUrl; intent.putExtra(Intent.EXTRA_TEXT, text); @@ -135,15 +136,14 @@ public class SharingUtils Intent intent = new Intent(Intent.ACTION_SEND); intent.setType(TEXT_MIME_TYPE); - final String subject = object.isMyPosition() ? - context.getString(R.string.my_position_share_email_subject) : - context.getString(R.string.bookmark_share_email_subject); + final String subject = object.isMyPosition() ? context.getString(R.string.my_position_share_email_subject) + : context.getString(R.string.bookmark_share_email_subject); intent.putExtra(Intent.EXTRA_SUBJECT, subject); - final String geoUrl = Framework.nativeGetGeoUri(object.getLat(), object.getLon(), - object.getScale(), object.getName()); - final String httpUrl = Framework.getHttpGe0Url(object.getLat(), object.getLon(), - object.getScale(), object.getName()); + final String geoUrl = + Framework.nativeGetGeoUri(object.getLat(), object.getLon(), object.getScale(), object.getName()); + final String httpUrl = + Framework.getHttpGe0Url(object.getLat(), object.getLon(), object.getScale(), object.getName()); final String text = geoUrl + "\n" + httpUrl; intent.putExtra(Intent.EXTRA_TEXT, text); @@ -158,10 +158,10 @@ public class SharingUtils final String subject = context.getString(R.string.bookmark_share_email_subject); intent.putExtra(Intent.EXTRA_SUBJECT, subject); - final String geoUrl = Framework.nativeGetGe0Url(bookmark.getLat(), bookmark.getLon(), - bookmark.getScale(), bookmark.getName()); - final String httpUrl = Framework.getHttpGe0Url(bookmark.getLat(), bookmark.getLon(), - bookmark.getScale(), bookmark.getName()); + final String geoUrl = + Framework.nativeGetGe0Url(bookmark.getLat(), bookmark.getLon(), bookmark.getScale(), bookmark.getName()); + final String httpUrl = + Framework.getHttpGe0Url(bookmark.getLat(), bookmark.getLon(), bookmark.getScale(), bookmark.getName()); StringBuilder text = new StringBuilder(); text.append(bookmark.getName()); if (!TextUtils.isEmpty(bookmark.getAddress())) @@ -180,7 +180,7 @@ public class SharingUtils private static void ProcessShareResult(@NonNull ContentResolver resolver, Pair result) { - if (resolver!=null && result != null) + if (resolver != null && result != null) { Uri sourceUri = result.first; Uri destinationUri = result.second; @@ -199,16 +199,12 @@ public class SharingUtils public static ActivityResultLauncher RegisterLauncher(@NonNull Fragment fragment) { return fragment.registerForActivityResult( - new SharingContract(), - result -> ProcessShareResult(fragment.requireContext().getContentResolver(), result) - ); + new SharingContract(), result -> ProcessShareResult(fragment.requireContext().getContentResolver(), result)); } public static ActivityResultLauncher RegisterLauncher(@NonNull AppCompatActivity activity) { - return activity.registerForActivityResult( - new SharingContract(), - result -> ProcessShareResult(activity.getContentResolver(), result) - ); + return activity.registerForActivityResult(new SharingContract(), + result -> ProcessShareResult(activity.getContentResolver(), result)); } public static void shareFile(Context context, ActivityResultLauncher launcher, ShareInfo info) @@ -218,7 +214,7 @@ public class SharingUtils if (!info.mSubject.isEmpty()) intent.putExtra(Intent.EXTRA_SUBJECT, info.mSubject); if (!info.mMail.isEmpty()) - intent.putExtra(Intent.EXTRA_EMAIL, new String[]{info.mMail}); + intent.putExtra(Intent.EXTRA_EMAIL, new String[] {info.mMail}); if (!info.mText.isEmpty()) intent.putExtra(Intent.EXTRA_TEXT, info.mText); @@ -236,15 +232,17 @@ public class SharingUtils // https://developer.android.com/reference/androidx/core/content/FileProvider#include-the-permission-in-an-intent intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK); - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) { + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) + { intent.setClipData(ClipData.newRawUri("", fileUri)); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION + | Intent.FLAG_ACTIVITY_NEW_TASK); } Intent saveIntent = new Intent(Intent.ACTION_CREATE_DOCUMENT); saveIntent.setType(info.mMimeType); - final String fileName = fileUri.getPathSegments().get(fileUri.getPathSegments().size()-1); + final String fileName = fileUri.getPathSegments().get(fileUri.getPathSegments().size() - 1); saveIntent.putExtra(Intent.EXTRA_TITLE, fileName); Intent[] extraIntents = {saveIntent}; @@ -252,7 +250,7 @@ public class SharingUtils // Prevent sharing to ourselves (supported from API Level 24). if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - ComponentName[] excludeSelf = { new ComponentName(context, SplashActivity.class) }; + ComponentName[] excludeSelf = {new ComponentName(context, SplashActivity.class)}; chooser.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, excludeSelf); } @@ -264,7 +262,8 @@ public class SharingUtils launcher.launch(sharingIntent); } - public static void shareBookmarkFile(Context context, ActivityResultLauncher launcher, String fileName, String mimeType) + public static void shareBookmarkFile(Context context, ActivityResultLauncher launcher, String fileName, + String mimeType) { final String subject = context.getString(R.string.share_bookmarks_email_subject); final String text = context.getString(R.string.share_bookmarks_email_body); diff --git a/android/app/src/main/java/app/organicmaps/util/ThemeUtils.java b/android/app/src/main/java/app/organicmaps/util/ThemeUtils.java index c121c8d31..bd866ca0c 100644 --- a/android/app/src/main/java/app/organicmaps/util/ThemeUtils.java +++ b/android/app/src/main/java/app/organicmaps/util/ThemeUtils.java @@ -3,13 +3,12 @@ package app.organicmaps.util; import android.content.Context; import android.content.res.TypedArray; import android.util.TypedValue; - import androidx.annotation.AttrRes; import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.StyleRes; - import app.organicmaps.R; +import app.organicmaps.sdk.util.Config; public final class ThemeUtils { @@ -37,7 +36,7 @@ public final class ThemeUtils { int styleRef = getResource(context, style); - int[] attrs = new int[] { attr }; + int[] attrs = new int[] {attr}; TypedArray ta = context.getTheme().obtainStyledAttributes(styleRef, attrs); ta.getValue(0, VALUE_BUFFER); ta.recycle(); @@ -87,7 +86,7 @@ public final class ThemeUtils { String navAutoTheme = context.getString(R.string.theme_nav_auto); return navAutoTheme.equals(theme); -} + } public static boolean isValidTheme(@NonNull Context context, String theme) { diff --git a/android/app/src/main/java/app/organicmaps/util/Utils.java b/android/app/src/main/java/app/organicmaps/util/Utils.java index aadb5c76e..5c6614da1 100644 --- a/android/app/src/main/java/app/organicmaps/util/Utils.java +++ b/android/app/src/main/java/app/organicmaps/util/Utils.java @@ -1,6 +1,7 @@ package app.organicmaps.util; -import android.annotation.SuppressLint; +import static app.organicmaps.sdk.util.Utils.isIntentSupported; + import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.ClipData; @@ -9,8 +10,6 @@ import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -19,7 +18,6 @@ import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.Spanned; import android.text.TextUtils; -import android.text.format.DateUtils; import android.text.style.AbsoluteSizeSpan; import android.util.AndroidRuntimeException; import android.view.View; @@ -27,7 +25,6 @@ import android.view.Window; import android.view.WindowManager; import android.widget.TextView; import android.widget.Toast; - import androidx.activity.result.ActivityResultLauncher; import androidx.annotation.DimenRes; import androidx.annotation.Keep; @@ -42,18 +39,14 @@ import app.organicmaps.BuildConfig; import app.organicmaps.MwmActivity; import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.util.concurrency.UiThread; -import app.organicmaps.util.log.Logger; -import app.organicmaps.util.log.LogsManager; +import app.organicmaps.sdk.util.Constants; +import app.organicmaps.sdk.util.Distance; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.concurrency.UiThread; +import app.organicmaps.sdk.util.log.Logger; +import app.organicmaps.sdk.util.log.LogsManager; import com.google.android.material.snackbar.Snackbar; - -import java.io.Closeable; -import java.io.IOException; import java.lang.ref.WeakReference; -import java.text.DecimalFormatSymbols; -import java.util.Currency; -import java.util.Locale; -import java.util.Map; @Keep public class Utils @@ -67,10 +60,7 @@ public class Utils public static final String ZIP_MIME_TYPE = "application/x-zip"; public static final String EMAIL_MIME_TYPE = "message/rfc822"; - - private Utils() - { - } + private Utils() {} /** * Enable to keep screen on. @@ -128,8 +118,8 @@ public class Utils showSnackbar(context, view, null, messageResId); } - public static void showSnackbar(@NonNull Context context, @NonNull View view, - @Nullable View viewAbove, int messageResId) + public static void showSnackbar(@NonNull Context context, @NonNull View view, @Nullable View viewAbove, + int messageResId) { final String message = context.getString(messageResId); if (viewAbove == null) @@ -138,20 +128,6 @@ public class Utils showSnackbarAbove(view, viewAbove, message); } - @SuppressWarnings("deprecated") - private static @Nullable ResolveInfo resolveActivity(@NonNull PackageManager pm, @NonNull Intent intent, int flags) - { - return pm.resolveActivity(intent, flags); - } - - public static boolean isIntentSupported(@NonNull Context context, @NonNull Intent intent) - { - final PackageManager pm = context.getPackageManager(); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) - return resolveActivity(pm, intent, 0) != null; - return pm.resolveActivity(intent, PackageManager.ResolveInfoFlags.of(0)) != null; - } - public static @Nullable Intent makeSystemLocationSettingIntent(@NonNull Context context) { Intent intent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS); @@ -170,7 +146,8 @@ public class Utils public static void checkNotNull(Object object) { - if (null == object) throw new NullPointerException("Argument here must not be NULL"); + if (null == object) + throw new NullPointerException("Argument here must not be NULL"); } public static void copyTextToClipboard(Context context, String text) @@ -180,33 +157,10 @@ public class Utils final ClipData clip = ClipData.newPlainText(context.getString(R.string.project_name) + ": " + text, text); clipboard.setPrimaryClip(clip); } - - public static String mapPrettyPrint(Map map) - { - if (map == null) - return "[null]"; - if (map.isEmpty()) - return "[]"; - - - String joined = ""; - for (final K key : map.keySet()) - { - final String keyVal = key + "=" + map.get(key); - if (!joined.isEmpty()) - joined = TextUtils.join(",", new Object[]{joined, keyVal}); - else - joined = keyVal; - } - - return "[" + joined + "]"; - } - public static Uri buildMailUri(String to, String subject, String body) { - String uriString = Constants.Url.MAILTO_SCHEME + Uri.encode(to) + - Constants.Url.MAIL_SUBJECT + Uri.encode(subject) + - Constants.Url.MAIL_BODY + Uri.encode(body); + String uriString = Constants.Url.MAILTO_SCHEME + Uri.encode(to) + Constants.Url.MAIL_SUBJECT + Uri.encode(subject) + + Constants.Url.MAIL_BODY + Uri.encode(body); return Uri.parse(uriString); } @@ -220,7 +174,8 @@ public class Utils try { activity.startActivity(marketIntent); - } catch (ActivityNotFoundException e) + } + catch (ActivityNotFoundException e) { Logger.e(TAG, "Failed to start activity", e); } @@ -233,7 +188,8 @@ public class Utils // Exception is thrown if we don't have installed Facebook application. getPackageInfo(activity.getPackageManager(), Constants.Package.FB_PACKAGE, 0); activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Constants.Url.FB_OM_COMMUNITY_NATIVE))); - } catch (final Exception e) + } + catch (final Exception e) { activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(Constants.Url.FB_OM_COMMUNITY_HTTP))); } @@ -245,9 +201,8 @@ public class Utils return; final Intent intent = new Intent(Intent.ACTION_VIEW); - Uri uri = isHttpOrHttpsScheme(url) - ? Uri.parse(url) - : new Uri.Builder().scheme("http").appendEncodedPath(url).build(); + Uri uri = + isHttpOrHttpsScheme(url) ? Uri.parse(url) : new Uri.Builder().scheme("http").appendEncodedPath(url).build(); intent.setData(uri); try { @@ -293,40 +248,27 @@ public class Utils return url.startsWith("http://") || url.startsWith("https://"); } - public static void closeSafely(@NonNull Closeable... closeable) - { - for (Closeable each : closeable) - { - if (each != null) - { - try - { - each.close(); - } - catch (IOException e) - { - Logger.e(TAG, "Failed to close '" + each + "'", e); - } - } - } - } - // subject is optional (could be an empty string). /** * @param subject could be an empty string */ - public static void sendBugReport(@NonNull ActivityResultLauncher launcher, @NonNull Activity activity, @NonNull String subject, @NonNull String body) + public static void sendBugReport(@NonNull ActivityResultLauncher launcher, + @NonNull Activity activity, @NonNull String subject, @NonNull String body) { - subject = activity.getString(R.string.project_name) + " Bug Report" + (TextUtils.isEmpty(subject) ? "" : ": " + subject); - LogsManager.INSTANCE.zipLogs(new SupportInfoWithLogsCallback(launcher, activity, subject, body, Constants.Email.SUPPORT)); + subject = + activity.getString(R.string.project_name) + " Bug Report" + (TextUtils.isEmpty(subject) ? "" : ": " + subject); + LogsManager.INSTANCE.zipLogs( + new SupportInfoWithLogsCallback(launcher, activity, subject, body, Constants.Email.SUPPORT)); } - // TODO: Don't send logs with general feedback, send system information only (version, device name, connectivity, etc.) - public static void sendFeedback(@NonNull ActivityResultLauncher launcher, @NonNull Activity activity) + // TODO: Don't send logs with general feedback, send system information only (version, device name, connectivity, + // etc.) + public static void sendFeedback(@NonNull ActivityResultLauncher launcher, + @NonNull Activity activity) { - LogsManager.INSTANCE.zipLogs(new SupportInfoWithLogsCallback(launcher, activity, activity.getString(R.string.project_name) + " Feedback", "", - Constants.Email.SUPPORT)); + LogsManager.INSTANCE.zipLogs(new SupportInfoWithLogsCallback( + launcher, activity, activity.getString(R.string.project_name) + " Feedback", "", Constants.Email.SUPPORT)); } public static void navigateToParent(@NonNull Activity activity) @@ -337,11 +279,14 @@ public class Utils NavUtils.navigateUpFromSameTask(activity); } - public static SpannableStringBuilder formatTime(Context context, @DimenRes int size, @DimenRes int units, String dimension, String unitText) + public static SpannableStringBuilder formatTime(Context context, @DimenRes int size, @DimenRes int units, + String dimension, String unitText) { final SpannableStringBuilder res = new SpannableStringBuilder(dimension).append("\u00A0").append(unitText); - res.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(context, size), false), 0, dimension.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - res.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(context, units), false), dimension.length(), res.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + res.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(context, size), false), 0, dimension.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + res.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(context, units), false), dimension.length(), res.length(), + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return res; } @@ -349,12 +294,10 @@ public class Utils public static Spannable formatDistance(Context context, @NonNull Distance distance) { final SpannableStringBuilder res = new SpannableStringBuilder(distance.toString(context)); - res.setSpan( - new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_nav_number), false), - 0, distance.mDistanceStr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - res.setSpan( - new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_nav_dimension), false), - distance.mDistanceStr.length(), res.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + res.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_nav_number), false), 0, + distance.mDistanceStr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + res.setSpan(new AbsoluteSizeSpan(UiUtils.dimen(context, R.dimen.text_size_nav_dimension), false), + distance.mDistanceStr.length(), res.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); return res; } @@ -368,7 +311,8 @@ public class Utils sendTo(context, email, subject, ""); } - public static void sendTo(@NonNull Context context, @NonNull String email, @NonNull String subject, @NonNull String body) + public static void sendTo(@NonNull Context context, @NonNull String email, @NonNull String subject, + @NonNull String body) { Intent intent = new Intent(Intent.ACTION_SENDTO); intent.setData(Utils.buildMailUri(email, subject, body)); @@ -389,199 +333,7 @@ public class Utils } } - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @Nullable - public static String getCurrencyCode() - { - Locale[] locales = { Locale.getDefault(), Locale.US }; - for (Locale locale : locales) - { - Currency currency = getCurrencyForLocale(locale); - if (currency != null) - return currency.getCurrencyCode(); - } - return null; - } - - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @NonNull - public static String getCountryCode() - { - return Locale.getDefault().getCountry(); - } - - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @NonNull - public static String getLanguageCode() - { - return Locale.getDefault().getLanguage(); - } - - - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @NonNull - public static String getDecimalSeparator() - { - return String.valueOf(DecimalFormatSymbols.getInstance().getDecimalSeparator()); - } - - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @NonNull - public static String getGroupingSeparator() - { - return String.valueOf(DecimalFormatSymbols.getInstance().getGroupingSeparator()); - } - - @Nullable - public static Currency getCurrencyForLocale(@NonNull Locale locale) - { - try - { - return Currency.getInstance(locale); - } - catch (Throwable e) - { - Logger.e(TAG, "Failed to obtain a currency for locale: " + locale, e); - return null; - } - } - - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @NonNull - public static String getCurrencySymbol(@NonNull String currencyCode) - { - try - { - return Currency.getInstance(currencyCode).getSymbol(Locale.getDefault()); - } - catch (Throwable e) - { - Logger.e(TAG, "Failed to obtain currency symbol by currency code = " + currencyCode, e); - } - - return currencyCode; - } - - static String makeUrlSafe(@NonNull final String url) - { - return url.replaceAll("(token|password|key)=([^&]+)", "***"); - } - - @StringRes - @SuppressLint("DiscouragedApi") - public static int getStringIdByKey(@NonNull Context context, @NonNull String key) - { - try - { - Resources res = context.getResources(); - @StringRes - int nameId = res.getIdentifier(key, "string", context.getPackageName()); - if (nameId == INVALID_ID || nameId == View.NO_ID) - throw new Resources.NotFoundException("String id '" + key + "' is not found"); - return nameId; - } - catch (RuntimeException e) - { - Logger.e(TAG, "Failed to get string with id '" + key + "'", e); - if (BuildConfig.BUILD_TYPE.equals("debug") || BuildConfig.BUILD_TYPE.equals("beta")) - { - Toast.makeText(context, "Add string id for '" + key + "'!", Toast.LENGTH_LONG).show(); - } - } - return INVALID_ID; - } - - /** - * Returns a string value for the specified key. If the value is not found then its key will be - * returned. - * - * @return string value or its key if there is no string for the specified key. - */ - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @NonNull - public static String getStringValueByKey(@NonNull Context context, @NonNull String key) - { - try - { - return context.getString(getStringIdByKey(context, key)); - } - catch (Resources.NotFoundException e) - { - Logger.e(TAG, "Failed to get value for string '" + key + "'", e); - } - return key; - } - - /** - * Returns a name for a new bookmark created off the current GPS location. - * The name includes current time and date in locale-specific format. - * - * @return bookmark name with time and date. - */ - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @NonNull - public static String getMyPositionBookmarkName(@NonNull Context context) - { - return DateUtils.formatDateTime(context, System.currentTimeMillis(), - DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR); - } - - // Called from JNI. - @NonNull - @Keep - @SuppressWarnings("unused") - public static String getDeviceName() - { - return Build.MANUFACTURER; - } - - // Called from JNI. - @NonNull - @Keep - @SuppressWarnings("unused") - public static String getDeviceModel() - { - return Build.MODEL; - } - - // Called from JNI. - @NonNull - @Keep - @SuppressWarnings("unused") - public static String getVersion() - { - return BuildConfig.VERSION_NAME; - } - - // Called from JNI. - @Keep - @SuppressWarnings("unused") - public static int getIntVersion() - { - // Please sync with getVersion() in build.gradle - // - % 100000000 removes prefix for special markets, e.g Huawei. - // - / 100 removes the number of commits in the current day. - return (BuildConfig.VERSION_CODE % 1_00_00_00_00) / 100; - } - - public static void detachFragmentIfCoreNotInitialized(@NonNull Context context, - @NonNull Fragment fragment) + public static void detachFragmentIfCoreNotInitialized(@NonNull Context context, @NonNull Fragment fragment) { if (MwmApplication.from(context).getOrganicMaps().arePlatformAndCoreInitialized()) return; @@ -614,66 +366,6 @@ public class Utils return Character.toLowerCase(src.charAt(0)) + src.substring(1); } - - public interface Proc - { - void invoke(@NonNull T param); - } - - @NonNull - private static String getLocalizedFeatureByKey(@NonNull Context context, @NonNull String key) - { - return getStringValueByKey(context, key); - } - - @Keep - @SuppressWarnings("unused") - @NonNull - public static String getTagValueLocalized(@NonNull Context context, @Nullable String tagKey, @Nullable String value) - { - if (TextUtils.isEmpty(tagKey) || TextUtils.isEmpty(value)) - return ""; - - return getLocalizedFeatureType(context, tagKey + "-" + value); - } - - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @NonNull - public static String getLocalizedFeatureType(@NonNull Context context, @Nullable String type) - { - if (TextUtils.isEmpty(type)) - return ""; - - String key = "type." + type.replace('-', '.') - .replace(':', '_'); - return getLocalizedFeatureByKey(context, key); - } - - // Called from JNI. - @Keep - @SuppressWarnings("unused") - @NonNull - public static String getLocalizedBrand(@NonNull Context context, @Nullable String brand) - { - if (TextUtils.isEmpty(brand)) - return ""; - - try - { - @StringRes - int nameId = context.getResources().getIdentifier("brand." + brand, "string", context.getPackageName()); - if (nameId == INVALID_ID || nameId == View.NO_ID) - return brand; - return context.getString(nameId); - } - catch (Resources.NotFoundException e) - { - } - return brand; - } - public static String getLocalizedLevel(@NonNull Context context, @Nullable String level) { if (TextUtils.isEmpty(level)) @@ -694,8 +386,9 @@ public class Utils @NonNull private final String mEmail; - private SupportInfoWithLogsCallback(@NonNull ActivityResultLauncher launcher, @NonNull Activity activity, @NonNull String subject, - @NonNull String body, @NonNull String email) + private SupportInfoWithLogsCallback(@NonNull ActivityResultLauncher launcher, + @NonNull Activity activity, @NonNull String subject, @NonNull String body, + @NonNull String email) { mActivityRef = new WeakReference<>(activity); mSubject = subject; @@ -730,13 +423,11 @@ public class Utils } SharingUtils.shareFile(activity.getApplicationContext(), mLauncher, info); - }); } } - public static T getParcelable(@NonNull Bundle in, @Nullable String key, - @NonNull Class clazz) + public static T getParcelable(@NonNull Bundle in, @Nullable String key, @NonNull Class clazz) { in.setClassLoader(clazz.getClassLoader()); return BundleCompat.getParcelable(in, key, clazz); @@ -755,22 +446,6 @@ public class Utils return Html.fromHtml(htmlDescription, Html.FROM_HTML_MODE_LEGACY); } - @SuppressWarnings("deprecation") - private static ApplicationInfo getApplicationInfoOld(@NonNull PackageManager manager, @NonNull String packageName, int flags) - throws PackageManager.NameNotFoundException - { - return manager.getApplicationInfo(packageName, flags); - } - - public static ApplicationInfo getApplicationInfo(@NonNull PackageManager manager, @NonNull String packageName, - int flags) - throws PackageManager.NameNotFoundException - { - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) - return getApplicationInfoOld(manager, packageName, flags); - return manager.getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags)); - } - @SuppressWarnings("deprecation") private static PackageInfo getPackageInfoOld(@NonNull PackageManager manager, @NonNull String packageName, int flags) throws PackageManager.NameNotFoundException diff --git a/android/app/src/main/java/app/organicmaps/util/WindowInsetUtils.java b/android/app/src/main/java/app/organicmaps/util/WindowInsetUtils.java index f36656222..8655ead24 100644 --- a/android/app/src/main/java/app/organicmaps/util/WindowInsetUtils.java +++ b/android/app/src/main/java/app/organicmaps/util/WindowInsetUtils.java @@ -2,29 +2,25 @@ package app.organicmaps.util; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.Insets; import androidx.core.view.OnApplyWindowInsetsListener; import androidx.core.view.WindowInsetsCompat; import app.organicmaps.R; +import app.organicmaps.sdk.util.UiUtils; public final class WindowInsetUtils { - - private WindowInsetUtils() - { - } + private WindowInsetUtils() {} /** * The insets that include areas where content may be covered by other drawn content. * This includes all systemBars, displayCutout and ime. */ @WindowInsetsCompat.Type.InsetsType - public static final int TYPE_SAFE_DRAWING = WindowInsetsCompat.Type.systemBars() - | WindowInsetsCompat.Type.displayCutout() - | WindowInsetsCompat.Type.ime(); + public static final int TYPE_SAFE_DRAWING = + WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() | WindowInsetsCompat.Type.ime(); /** * A utility class that implements {@link android.view.View.OnApplyWindowInsetsListener} @@ -40,7 +36,6 @@ public final class WindowInsetUtils */ public static final class ScrollableContentInsetsListener implements OnApplyWindowInsetsListener { - @Nullable private final View mFloatingActionButton; @NonNull @@ -58,10 +53,10 @@ public final class WindowInsetUtils if (floatingActionButton != null) { - floatingActionButton.addOnLayoutChangeListener(new View.OnLayoutChangeListener() - { + floatingActionButton.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, + int oldRight, int oldBottom) { int height = v.getMeasuredHeight(); if (height > 0) @@ -87,23 +82,19 @@ public final class WindowInsetUtils int spacing = UiUtils.dimen(v.getContext(), R.dimen.margin_base); int buttonMarginBottom = insets.bottom + spacing; - ViewGroup.MarginLayoutParams buttonLayoutParams = (ViewGroup.MarginLayoutParams) mFloatingActionButton.getLayoutParams(); + ViewGroup.MarginLayoutParams buttonLayoutParams = + (ViewGroup.MarginLayoutParams) mFloatingActionButton.getLayoutParams(); buttonLayoutParams.bottomMargin = buttonMarginBottom; - scrollableViewPaddingBottom = buttonMarginBottom - + mFloatingActionButton.getMeasuredHeight() - + spacing; + scrollableViewPaddingBottom = buttonMarginBottom + mFloatingActionButton.getMeasuredHeight() + spacing; } else { scrollableViewPaddingBottom = insets.bottom; } - mScrollableView.setPadding( - v.getPaddingLeft(), - v.getPaddingTop(), - v.getPaddingRight(), - scrollableViewPaddingBottom); + mScrollableView.setPadding(v.getPaddingLeft(), v.getPaddingTop(), v.getPaddingRight(), + scrollableViewPaddingBottom); // update margins instead of paddings, because item decorators do not respect paddings updateScrollableViewMargins(insets); @@ -113,7 +104,8 @@ public final class WindowInsetUtils private void updateScrollableViewMargins(@NonNull Insets insets) { - final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) mScrollableView.getLayoutParams(); + final ViewGroup.MarginLayoutParams layoutParams = + (ViewGroup.MarginLayoutParams) mScrollableView.getLayoutParams(); if (layoutParams != null) { boolean dirty = false; @@ -137,7 +129,6 @@ public final class WindowInsetUtils public static final class PaddingInsetsListener implements OnApplyWindowInsetsListener { - private final int insetsTypeMask; private final boolean top; private final boolean bottom; @@ -181,16 +172,13 @@ public final class WindowInsetUtils public WindowInsetsCompat onApplyWindowInsets(@NonNull View v, @NonNull WindowInsetsCompat windowInsets) { final Insets insets = windowInsets.getInsets(insetsTypeMask); - v.setPadding( - left ? insets.left : v.getPaddingLeft(), - top ? insets.top : v.getPaddingTop(), - right ? insets.right : v.getPaddingRight(), - bottom ? insets.bottom : v.getPaddingBottom()); + v.setPadding(left ? insets.left : v.getPaddingLeft(), top ? insets.top : v.getPaddingTop(), + right ? insets.right : v.getPaddingRight(), bottom ? insets.bottom : v.getPaddingBottom()); return windowInsets; } - public static class Builder { - + public static class Builder + { private int mInsetsTypeMask = TYPE_SAFE_DRAWING; private boolean mTop; private boolean mBottom; @@ -203,7 +191,8 @@ public final class WindowInsetUtils return this; } - public Builder setAllSides() { + public Builder setAllSides() + { mTop = true; mBottom = true; mLeft = true; @@ -211,7 +200,8 @@ public final class WindowInsetUtils return this; } - public Builder setExcludeTop() { + public Builder setExcludeTop() + { mTop = false; mBottom = true; mLeft = true; @@ -219,7 +209,8 @@ public final class WindowInsetUtils return this; } - public Builder setExcludeBottom() { + public Builder setExcludeBottom() + { mTop = true; mBottom = false; mLeft = true; diff --git a/android/app/src/main/java/app/organicmaps/util/bottomsheet/MenuAdapter.java b/android/app/src/main/java/app/organicmaps/util/bottomsheet/MenuAdapter.java index f95144ced..8a3823789 100644 --- a/android/app/src/main/java/app/organicmaps/util/bottomsheet/MenuAdapter.java +++ b/android/app/src/main/java/app/organicmaps/util/bottomsheet/MenuAdapter.java @@ -4,18 +4,13 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.recyclerview.widget.RecyclerView; - +import app.organicmaps.R; +import app.organicmaps.sdk.location.TrackRecorder; import com.google.android.material.imageview.ShapeableImageView; import com.google.android.material.textview.MaterialTextView; - -import app.organicmaps.R; -import app.organicmaps.location.TrackRecorder; -import app.organicmaps.util.Config; - import java.util.ArrayList; public class MenuAdapter extends RecyclerView.Adapter @@ -24,7 +19,8 @@ public class MenuAdapter extends RecyclerView.Adapter @Nullable private final MenuBottomSheetItem.OnClickListener onClickListener; - public MenuAdapter(ArrayList dataSet, @Nullable MenuBottomSheetItem.OnClickListener onClickListener) + public MenuAdapter(ArrayList dataSet, + @Nullable MenuBottomSheetItem.OnClickListener onClickListener) { this.dataSet = dataSet; this.onClickListener = onClickListener; @@ -41,8 +37,7 @@ public class MenuAdapter extends RecyclerView.Adapter @Override public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) { - View view = LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.bottom_sheet_menu_item, viewGroup, false); + View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.bottom_sheet_menu_item, viewGroup, false); return new ViewHolder(view); } @@ -51,13 +46,7 @@ public class MenuAdapter extends RecyclerView.Adapter { final MenuBottomSheetItem item = dataSet.get(position); final ShapeableImageView iv = viewHolder.getIconImageView(); - if (item.iconRes == R.drawable.ic_donate && Config.isNY()) - { - iv.setImageResource(R.drawable.ic_christmas_tree); - iv.setImageTintMode(null); - } - else - iv.setImageResource(item.iconRes); + iv.setImageResource(item.iconRes); viewHolder.getContainer().setOnClickListener((v) -> onMenuItemClick(item)); viewHolder.getTitleTextView().setText(item.titleRes); MaterialTextView badge = viewHolder.getBadgeTextView(); @@ -65,7 +54,9 @@ public class MenuAdapter extends RecyclerView.Adapter { badge.setText(String.valueOf(item.badgeCount)); badge.setVisibility(View.VISIBLE); - } else { + } + else + { badge.setVisibility(View.GONE); } @@ -121,5 +112,4 @@ public class MenuAdapter extends RecyclerView.Adapter return container; } } - } diff --git a/android/app/src/main/java/app/organicmaps/util/bottomsheet/MenuBottomSheetFragment.java b/android/app/src/main/java/app/organicmaps/util/bottomsheet/MenuBottomSheetFragment.java index 56c5626e7..7b38d5be0 100644 --- a/android/app/src/main/java/app/organicmaps/util/bottomsheet/MenuBottomSheetFragment.java +++ b/android/app/src/main/java/app/organicmaps/util/bottomsheet/MenuBottomSheetFragment.java @@ -7,7 +7,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.Window; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.WindowCompat; @@ -15,21 +14,17 @@ import androidx.core.view.WindowInsetsControllerCompat; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; - +import app.organicmaps.R; +import app.organicmaps.sdk.util.UiUtils; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.bottomsheet.BottomSheetDialog; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.textview.MaterialTextView; - import java.util.ArrayList; import java.util.Objects; -import app.organicmaps.R; -import app.organicmaps.util.UiUtils; - public class MenuBottomSheetFragment extends BottomSheetDialogFragment { - @Nullable private ArrayList mMenuBottomSheetItems; @Nullable @@ -60,11 +55,11 @@ public class MenuBottomSheetFragment extends BottomSheetDialogFragment { return new BottomSheetDialog(requireContext(), getTheme()) { @Override - public void onAttachedToWindow() { + public void onAttachedToWindow() + { super.onAttachedToWindow(); Window window = Objects.requireNonNull(getWindow()); - WindowInsetsControllerCompat insetsController = - WindowCompat.getInsetsController(window, window.getDecorView()); + WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(window, window.getDecorView()); insetsController.setAppearanceLightNavigationBars(false); } }; @@ -72,7 +67,8 @@ public class MenuBottomSheetFragment extends BottomSheetDialogFragment @Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.bottom_sheet, container); } @@ -139,9 +135,9 @@ public class MenuBottomSheetFragment extends BottomSheetDialogFragment { Activity parentActivity = requireActivity(); if (parentActivity instanceof MenuBottomSheetInterfaceWithHeader) - bottomSheetInterfaceWithHeader = (MenuBottomSheetInterfaceWithHeader) parentActivity; + bottomSheetInterfaceWithHeader = (MenuBottomSheetInterfaceWithHeader) parentActivity; else if (parentActivity instanceof MenuBottomSheetInterface) - bottomSheetInterface = (MenuBottomSheetInterface) parentActivity; + bottomSheetInterface = (MenuBottomSheetInterface) parentActivity; } if (bottomSheetInterface != null) @@ -180,5 +176,4 @@ public class MenuBottomSheetFragment extends BottomSheetDialogFragment @Nullable ArrayList getMenuBottomSheetItems(String id); } - } diff --git a/android/app/src/main/java/app/organicmaps/widget/ArrowView.java b/android/app/src/main/java/app/organicmaps/widget/ArrowView.java index 0c8f27005..3ba0981d9 100644 --- a/android/app/src/main/java/app/organicmaps/widget/ArrowView.java +++ b/android/app/src/main/java/app/organicmaps/widget/ArrowView.java @@ -3,7 +3,6 @@ package app.organicmaps.widget; import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; - import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatImageView; @@ -43,4 +42,3 @@ public class ArrowView extends AppCompatImageView canvas.restore(); } } - diff --git a/android/app/src/main/java/app/organicmaps/widget/LanesDrawable.java b/android/app/src/main/java/app/organicmaps/widget/LanesDrawable.java index c54ba8bb6..0d3df577b 100644 --- a/android/app/src/main/java/app/organicmaps/widget/LanesDrawable.java +++ b/android/app/src/main/java/app/organicmaps/widget/LanesDrawable.java @@ -6,17 +6,14 @@ import android.graphics.ColorFilter; import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; - import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.content.res.AppCompatResources; import androidx.core.content.ContextCompat; - import app.organicmaps.R; import app.organicmaps.sdk.routing.SingleLaneInfo; - import java.util.Objects; public class LanesDrawable extends Drawable @@ -44,7 +41,8 @@ public class LanesDrawable extends Drawable { private final Drawable mDrawable; - private LaneDrawable(@NonNull final Context context, @NonNull SingleLaneInfo laneInfo, int horizontalOffset, TintColorInfo colorInfo) + private LaneDrawable(@NonNull final Context context, @NonNull SingleLaneInfo laneInfo, int horizontalOffset, + TintColorInfo colorInfo) { mDrawable = Objects.requireNonNull(AppCompatResources.getDrawable(context, laneInfo.mLane[0].mTurnRes)); @@ -69,13 +67,13 @@ public class LanesDrawable extends Drawable public LanesDrawable(@NonNull final Context context, @NonNull SingleLaneInfo[] lanes) { - final TintColorInfo tintColorInfo = new TintColorInfo( - ContextCompat.getColor(context, ACTIVE_LANE_TINT_RES), - ContextCompat.getColor(context, INACTIVE_LANE_TINT_RES)); + final TintColorInfo tintColorInfo = new TintColorInfo(ContextCompat.getColor(context, ACTIVE_LANE_TINT_RES), + ContextCompat.getColor(context, INACTIVE_LANE_TINT_RES)); mLanes = createLaneDrawables(context, lanes, tintColorInfo); } - public LanesDrawable(@NonNull final Context context, @NonNull SingleLaneInfo[] lanes, @ColorInt int activeLaneTint, @ColorInt int inactiveLaneTint) + public LanesDrawable(@NonNull final Context context, @NonNull SingleLaneInfo[] lanes, @ColorInt int activeLaneTint, + @ColorInt int inactiveLaneTint) { final TintColorInfo tintColorInfo = new TintColorInfo(activeLaneTint, inactiveLaneTint); mLanes = createLaneDrawables(context, lanes, tintColorInfo); @@ -119,11 +117,8 @@ public class LanesDrawable extends Drawable offsetX += widthForOneLane; } - super.setBounds( - mLanes[0].mDrawable.getBounds().left, - mLanes[0].mDrawable.getBounds().top, - mLanes[mLanes.length - 1].mDrawable.getBounds().right, - mLanes[0].mDrawable.getBounds().bottom); + super.setBounds(mLanes[0].mDrawable.getBounds().left, mLanes[0].mDrawable.getBounds().top, + mLanes[mLanes.length - 1].mDrawable.getBounds().right, mLanes[0].mDrawable.getBounds().bottom); } @Override @@ -134,10 +129,12 @@ public class LanesDrawable extends Drawable } @Override - public void setAlpha(int alpha) {} + public void setAlpha(int alpha) + {} @Override - public void setColorFilter(@Nullable ColorFilter colorFilter) {} + public void setColorFilter(@Nullable ColorFilter colorFilter) + {} @Override public int getOpacity() @@ -146,7 +143,8 @@ public class LanesDrawable extends Drawable } @NonNull - private LaneDrawable[] createLaneDrawables(@NonNull Context context, @NonNull SingleLaneInfo[] lanes, @NonNull TintColorInfo tintColorInfo) + private LaneDrawable[] createLaneDrawables(@NonNull Context context, @NonNull SingleLaneInfo[] lanes, + @NonNull TintColorInfo tintColorInfo) { assert lanes.length > 0; diff --git a/android/app/src/main/java/app/organicmaps/widget/LanesView.java b/android/app/src/main/java/app/organicmaps/widget/LanesView.java index 0aa0aab4c..6198fd268 100644 --- a/android/app/src/main/java/app/organicmaps/widget/LanesView.java +++ b/android/app/src/main/java/app/organicmaps/widget/LanesView.java @@ -11,12 +11,10 @@ import android.util.AttributeSet; import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; - import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StyleableRes; - import app.organicmaps.R; import app.organicmaps.sdk.routing.SingleLaneInfo; @@ -60,13 +58,17 @@ public class LanesView extends View try (TypedArray data = context.getTheme().obtainStyledAttributes(attrs, R.styleable.LanesView, 0, 0)) { backgroundColor = getAttrColor(data, R.styleable.LanesView_lanesBackgroundColor, DefaultValues.BACKGROUND_COLOR); - mActiveLaneTintColor = getAttrColor(data, R.styleable.LanesView_lanesActiveLaneTintColor, DefaultValues.ACTIVE_LANE_TINT_COLOR); - mInactiveLaneTintColor = getAttrColor(data, R.styleable.LanesView_lanesInactiveLaneTintColor, DefaultValues.INACTIVE_LANE_TINT_COLOR); - mCornerRadius = (int) Math.max(data.getDimension(R.styleable.LanesView_lanesCornerRadius, DefaultValues.CORNER_RADIUS), 0.0f); + mActiveLaneTintColor = + getAttrColor(data, R.styleable.LanesView_lanesActiveLaneTintColor, DefaultValues.ACTIVE_LANE_TINT_COLOR); + mInactiveLaneTintColor = + getAttrColor(data, R.styleable.LanesView_lanesInactiveLaneTintColor, DefaultValues.INACTIVE_LANE_TINT_COLOR); + mCornerRadius = + (int) Math.max(data.getDimension(R.styleable.LanesView_lanesCornerRadius, DefaultValues.CORNER_RADIUS), 0.0f); if (isInEditMode()) { - final int lanesCount = Math.max(1, data.getInt(R.styleable.LanesView_lanesEditModeLanesCount, DefaultValues.LANES_COUNT)); + final int lanesCount = + Math.max(1, data.getInt(R.styleable.LanesView_lanesEditModeLanesCount, DefaultValues.LANES_COUNT)); createLanesForEditMode(lanesCount); } } @@ -156,15 +158,15 @@ public class LanesView extends View private void createLanesForEditMode(int lanesCount) { final SingleLaneInfo[] lanes = new SingleLaneInfo[lanesCount]; - lanes[0] = new SingleLaneInfo(new byte[]{1}, false); + lanes[0] = new SingleLaneInfo(new byte[] {1}, false); if (lanes.length > 1) - lanes[1] = new SingleLaneInfo(new byte[]{3}, false); + lanes[1] = new SingleLaneInfo(new byte[] {3}, false); for (int i = 2; i <= lanes.length - 1; i++) - lanes[i] = new SingleLaneInfo(new byte[]{0}, true); + lanes[i] = new SingleLaneInfo(new byte[] {0}, true); if (lanes.length > 2) - lanes[lanes.length - 2] = new SingleLaneInfo(new byte[]{8}, false); + lanes[lanes.length - 2] = new SingleLaneInfo(new byte[] {8}, false); if (lanes.length > 3) - lanes[lanes.length - 1] = new SingleLaneInfo(new byte[]{9}, false); + lanes[lanes.length - 1] = new SingleLaneInfo(new byte[] {9}, false); setLanes(lanes); } diff --git a/android/app/src/main/java/app/organicmaps/widget/PlaceholderView.java b/android/app/src/main/java/app/organicmaps/widget/PlaceholderView.java index 0c3c9fe97..9dd3a09ba 100644 --- a/android/app/src/main/java/app/organicmaps/widget/PlaceholderView.java +++ b/android/app/src/main/java/app/organicmaps/widget/PlaceholderView.java @@ -9,14 +9,12 @@ import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; - import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; - import app.organicmaps.R; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.util.UiUtils; public class PlaceholderView extends LinearLayout { @@ -59,8 +57,7 @@ public class PlaceholderView extends LinearLayout init(context, attrs); } - public PlaceholderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, - int defStyleRes) + public PlaceholderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(context, attrs); @@ -85,17 +82,10 @@ public class PlaceholderView extends LinearLayout TypedArray attrsArray = null; try { - attrsArray = - context.getTheme().obtainStyledAttributes(attrs, R.styleable.PlaceholderView, 0, 0); - mImgSrcDefault = attrsArray.getResourceId( - R.styleable.PlaceholderView_imgSrcDefault, - UiUtils.NO_ID); - mTitleResIdDefault = attrsArray.getResourceId( - R.styleable.PlaceholderView_titleDefault, - UiUtils.NO_ID); - mSubtitleResIdDefault = attrsArray.getResourceId( - R.styleable.PlaceholderView_subTitleDefault, - UiUtils.NO_ID); + attrsArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.PlaceholderView, 0, 0); + mImgSrcDefault = attrsArray.getResourceId(R.styleable.PlaceholderView_imgSrcDefault, UiUtils.NO_ID); + mTitleResIdDefault = attrsArray.getResourceId(R.styleable.PlaceholderView_titleDefault, UiUtils.NO_ID); + mSubtitleResIdDefault = attrsArray.getResourceId(R.styleable.PlaceholderView_subTitleDefault, UiUtils.NO_ID); } finally { @@ -144,10 +134,8 @@ public class PlaceholderView extends LinearLayout final int defHeight = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec); MarginLayoutParams imgParams = (MarginLayoutParams) mImage.getLayoutParams(); - int potentialHeight = - defHeight - getPaddingBottom() - getPaddingTop() - childrenTextTotalHeight - - imgParams.bottomMargin - imgParams.topMargin; - + int potentialHeight = defHeight - getPaddingBottom() - getPaddingTop() - childrenTextTotalHeight + - imgParams.bottomMargin - imgParams.topMargin; int imgSpaceRaw = Math.min(potentialHeight, mImgMaxHeight); imgParams.height = imgSpaceRaw; @@ -160,7 +148,7 @@ public class PlaceholderView extends LinearLayout childrenTotalHeight += calcHeightWithMargins(mImage); UiUtils.showIf(isImageSpaceAllowed, mImage); - final int height = childrenTotalHeight + getPaddingTop() + getPaddingBottom(); + final int height = childrenTotalHeight + getPaddingTop() + getPaddingBottom(); final int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec); setMeasuredDimension(width, height); } @@ -173,20 +161,20 @@ public class PlaceholderView extends LinearLayout View child = getChildAt(index); if (child.getVisibility() == VISIBLE && child != mImage) { - measureChildWithMargins(child, widthMeasureSpec , 0, heightMeasureSpec, 0); + measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0); totalHeight += calcHeightWithMargins(child); } } return totalHeight; } - private static int calcHeightWithMargins(@NonNull View view) { + private static int calcHeightWithMargins(@NonNull View view) + { MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams(); return view.getMeasuredHeight() + params.bottomMargin + params.topMargin; } - public void setContent(@StringRes int titleRes, - @StringRes int subtitleRes) + public void setContent(@StringRes int titleRes, @StringRes int subtitleRes) { mTitle.setText(titleRes); mSubtitle.setText(subtitleRes); diff --git a/android/app/src/main/java/app/organicmaps/widget/RoutingToolbarButton.java b/android/app/src/main/java/app/organicmaps/widget/RoutingToolbarButton.java index cfad34db1..c98423a74 100644 --- a/android/app/src/main/java/app/organicmaps/widget/RoutingToolbarButton.java +++ b/android/app/src/main/java/app/organicmaps/widget/RoutingToolbarButton.java @@ -2,12 +2,10 @@ package app.organicmaps.widget; import android.content.Context; import android.util.AttributeSet; - import androidx.annotation.ColorRes; import androidx.annotation.DrawableRes; import androidx.appcompat.content.res.AppCompatResources; import androidx.appcompat.widget.AppCompatRadioButton; - import app.organicmaps.R; import app.organicmaps.util.ThemeUtils; diff --git a/android/app/src/main/java/app/organicmaps/widget/SearchToolbarController.java b/android/app/src/main/java/app/organicmaps/widget/SearchToolbarController.java index 434d71438..12e17bc92 100644 --- a/android/app/src/main/java/app/organicmaps/widget/SearchToolbarController.java +++ b/android/app/src/main/java/app/organicmaps/widget/SearchToolbarController.java @@ -9,16 +9,15 @@ import android.text.TextWatcher; import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.EditorInfo; - +import androidx.activity.OnBackPressedCallback; import androidx.activity.result.ActivityResult; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; - import app.organicmaps.R; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.InputUtils; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; import com.google.android.material.textfield.TextInputEditText; public class SearchToolbarController extends ToolbarController implements View.OnClickListener @@ -40,18 +39,27 @@ public class SearchToolbarController extends ToolbarController implements View.O private final View mVoiceInput; private final boolean mVoiceInputSupported = InputUtils.isVoiceInputSupported(requireActivity()); @NonNull - private final TextWatcher mTextWatcher = new StringUtils.SimpleTextWatcher() - { + private final TextWatcher mTextWatcher = new StringUtils.SimpleTextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { - updateViewsVisibility(TextUtils.isEmpty(s)); + final boolean isEmpty = TextUtils.isEmpty(s); + mBackPressedCallback.setEnabled(!isEmpty); + updateViewsVisibility(isEmpty); SearchToolbarController.this.onTextChanged(s.toString()); } }; - public SearchToolbarController(@NonNull View root, - @NonNull Activity activity) + private final OnBackPressedCallback mBackPressedCallback = new OnBackPressedCallback(false) { + @Override + public void handleOnBackPressed() + { + clear(); + setEnabled(false); + } + }; + + public SearchToolbarController(@NonNull View root, @NonNull Activity activity) { super(root, activity); mToolbarContainer = getToolbar().findViewById(R.id.toolbar_container); @@ -60,17 +68,14 @@ public class SearchToolbarController extends ToolbarController implements View.O mQuery = mSearchContainer.findViewById(R.id.query); mQuery.setOnClickListener(this); mQuery.addTextChangedListener(mTextWatcher); - mQuery.setOnEditorActionListener( - (v, actionId, event) -> - { - boolean isSearchDown = (event != null && - event.getAction() == KeyEvent.ACTION_DOWN && - event.getKeyCode() == KeyEvent.KEYCODE_SEARCH); + mQuery.setOnEditorActionListener((v, actionId, event) -> { + boolean isSearchDown = + (event != null && event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_SEARCH); - boolean isSearchAction = (actionId == EditorInfo.IME_ACTION_SEARCH); + boolean isSearchAction = (actionId == EditorInfo.IME_ACTION_SEARCH); - return (isSearchDown || isSearchAction) && onStartSearchClick(); - }); + return (isSearchDown || isSearchAction) && onStartSearchClick(); + }); mProgress = mSearchContainer.findViewById(R.id.progress); mVoiceInput = mSearchContainer.findViewById(R.id.voice_input); mVoiceInput.setOnClickListener(this); @@ -129,12 +134,11 @@ public class SearchToolbarController extends ToolbarController implements View.O { try { - startVoiceRecognition(InputUtils.createIntentForVoiceRecognition( - requireActivity().getString(getVoiceInputPrompt()))); + startVoiceRecognition( + InputUtils.createIntentForVoiceRecognition(requireActivity().getString(getVoiceInputPrompt()))); } catch (ActivityNotFoundException e) - { - } + {} } protected @StringRes int getVoiceInputPrompt() @@ -153,7 +157,10 @@ public class SearchToolbarController extends ToolbarController implements View.O { return (UiUtils.isVisible(mSearchContainer) ? mQuery.getText().toString() : ""); } - public boolean isCategory() { return mFromCategory; } + public boolean isCategory() + { + return mFromCategory; + } public void setQuery(CharSequence query, boolean fromCategory) { @@ -162,7 +169,10 @@ public class SearchToolbarController extends ToolbarController implements View.O if (!TextUtils.isEmpty(query)) mQuery.setSelection(query.length()); } - public void setQuery(CharSequence query) { setQuery(query, false); } + public void setQuery(CharSequence query) + { + setQuery(query, false); + } public void clear() { @@ -212,20 +222,25 @@ public class SearchToolbarController extends ToolbarController implements View.O public void onVoiceRecognitionResult(ActivityResult activityResult) { - if(activityResult.getResultCode() == Activity.RESULT_OK) + if (activityResult.getResultCode() == Activity.RESULT_OK) + { + if (activityResult.getData() == null) { - if (activityResult.getData() == null) - { - return; - } - String recognitionResult = InputUtils.getBestRecognitionResult(activityResult.getData()); - if (!TextUtils.isEmpty(recognitionResult)) - setQuery(recognitionResult); + return; } + String recognitionResult = InputUtils.getBestRecognitionResult(activityResult.getData()); + if (!TextUtils.isEmpty(recognitionResult)) + setQuery(recognitionResult); + } } public void setHint(@StringRes int hint) { mQuery.setHint(hint); } + + @NonNull + public OnBackPressedCallback getBackPressedCallback() { + return mBackPressedCallback; + } } diff --git a/android/app/src/main/java/app/organicmaps/widget/SpeedLimitView.java b/android/app/src/main/java/app/organicmaps/widget/SpeedLimitView.java index 4e71f55c5..12c4f4819 100644 --- a/android/app/src/main/java/app/organicmaps/widget/SpeedLimitView.java +++ b/android/app/src/main/java/app/organicmaps/widget/SpeedLimitView.java @@ -10,11 +10,9 @@ import android.graphics.Typeface; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; - import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; - import app.organicmaps.R; public class SpeedLimitView extends View @@ -72,14 +70,15 @@ public class SpeedLimitView extends View { super(context, attrs); - try (TypedArray data = context.getTheme() - .obtainStyledAttributes(attrs, R.styleable.SpeedLimitView, 0, 0)) + try (TypedArray data = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SpeedLimitView, 0, 0)) { - mBackgroundColor = data.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR); + mBackgroundColor = + data.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR); mBorderColor = data.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_COLOR); mAlertColor = data.getColor(R.styleable.SpeedLimitView_speedLimitAlertColor, DefaultValues.ALERT_COLOR); mTextColor = data.getColor(R.styleable.SpeedLimitView_speedLimitTextColor, DefaultValues.TEXT_COLOR); - mTextAlertColor = data.getColor(R.styleable.SpeedLimitView_speedLimitTextAlertColor, DefaultValues.TEXT_ALERT_COLOR); + mTextAlertColor = + data.getColor(R.styleable.SpeedLimitView_speedLimitTextAlertColor, DefaultValues.TEXT_ALERT_COLOR); if (isInEditMode()) { mSpeedLimit = data.getInt(R.styleable.SpeedLimitView_speedLimitEditModeSpeedLimit, 60); diff --git a/android/app/src/main/java/app/organicmaps/widget/StackedButtonDialogFragment.java b/android/app/src/main/java/app/organicmaps/widget/StackedButtonDialogFragment.java index 33c7178ba..544d154c4 100644 --- a/android/app/src/main/java/app/organicmaps/widget/StackedButtonDialogFragment.java +++ b/android/app/src/main/java/app/organicmaps/widget/StackedButtonDialogFragment.java @@ -2,20 +2,17 @@ package app.organicmaps.widget; import android.app.Dialog; import android.os.Bundle; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; - import app.organicmaps.R; -import app.organicmaps.util.Config; -import app.organicmaps.util.NetworkPolicy; +import app.organicmaps.sdk.util.Config; +import app.organicmaps.sdk.util.NetworkPolicy; public class StackedButtonDialogFragment extends DialogFragment { - @Nullable private NetworkPolicy.NetworkPolicyListener mListener; @@ -47,7 +44,6 @@ public class StackedButtonDialogFragment extends DialogFragment Config.setUseMobileDataSettings(type); if (mListener != null) mListener.onResult(NetworkPolicy.newInstance(canUse)); - } @Override diff --git a/android/app/src/main/java/app/organicmaps/widget/StackedButtonsDialog.java b/android/app/src/main/java/app/organicmaps/widget/StackedButtonsDialog.java index 0aed8e974..f8fc1db04 100644 --- a/android/app/src/main/java/app/organicmaps/widget/StackedButtonsDialog.java +++ b/android/app/src/main/java/app/organicmaps/widget/StackedButtonsDialog.java @@ -5,14 +5,12 @@ import android.content.DialogInterface; import android.os.Bundle; import android.view.View; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StringRes; import androidx.appcompat.app.AppCompatDialog; - import app.organicmaps.R; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.util.UiUtils; public class StackedButtonsDialog extends AppCompatDialog implements View.OnClickListener { @@ -151,8 +149,7 @@ public class StackedButtonsDialog extends AppCompatDialog implements View.OnClic } @NonNull - public Builder setPositiveButton(@StringRes int resId, - @Nullable DialogInterface.OnClickListener listener) + public Builder setPositiveButton(@StringRes int resId, @Nullable DialogInterface.OnClickListener listener) { mPositive = mContext.getString(resId); mPositiveListener = listener; @@ -160,8 +157,7 @@ public class StackedButtonsDialog extends AppCompatDialog implements View.OnClic } @NonNull - public Builder setNeutralButton(@StringRes int resId, - @Nullable DialogInterface.OnClickListener listener) + public Builder setNeutralButton(@StringRes int resId, @Nullable DialogInterface.OnClickListener listener) { mNeutral = mContext.getString(resId); mNeutralListener = listener; @@ -169,8 +165,7 @@ public class StackedButtonsDialog extends AppCompatDialog implements View.OnClic } @NonNull - public Builder setNegativeButton(@StringRes int resId, - @Nullable DialogInterface.OnClickListener listener) + public Builder setNegativeButton(@StringRes int resId, @Nullable DialogInterface.OnClickListener listener) { mNegative = mContext.getString(resId); mNegativeListener = listener; @@ -187,9 +182,8 @@ public class StackedButtonsDialog extends AppCompatDialog implements View.OnClic @NonNull public StackedButtonsDialog build() { - return new StackedButtonsDialog(mContext, mTitle, mMessage, mPositive, mPositiveListener, - mNeutral, mNeutralListener, mNegative, mNegativeListener, - mCancelable, mCancelListener); + return new StackedButtonsDialog(mContext, mTitle, mMessage, mPositive, mPositiveListener, mNeutral, + mNeutralListener, mNegative, mNegativeListener, mCancelable, mCancelListener); } } } diff --git a/android/app/src/main/java/app/organicmaps/widget/ToolbarController.java b/android/app/src/main/java/app/organicmaps/widget/ToolbarController.java index c93362b4e..4dd6de14a 100644 --- a/android/app/src/main/java/app/organicmaps/widget/ToolbarController.java +++ b/android/app/src/main/java/app/organicmaps/widget/ToolbarController.java @@ -2,7 +2,6 @@ package app.organicmaps.widget; import android.app.Activity; import android.view.View; - import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -10,18 +9,16 @@ import androidx.annotation.StringRes; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.ViewCompat; - -import com.google.android.material.appbar.MaterialToolbar; - import app.organicmaps.R; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Utils; import app.organicmaps.util.WindowInsetUtils; +import com.google.android.material.appbar.MaterialToolbar; public class ToolbarController { @Nullable - private Activity mActivity; + private Activity mActivity; @NonNull private final MaterialToolbar mToolbar; @NonNull @@ -32,10 +29,7 @@ public class ToolbarController mActivity = activity; mToolbar = root.findViewById(getToolbarId()); - - ViewCompat.setOnApplyWindowInsetsListener( - getToolbar(), - WindowInsetUtils.PaddingInsetsListener.excludeBottom()); + ViewCompat.setOnApplyWindowInsetsListener(getToolbar(), WindowInsetUtils.PaddingInsetsListener.excludeBottom()); UiUtils.setupNavigationIcon(mToolbar, mNavigationClickListener); setSupportActionBar(activity, mToolbar); diff --git a/android/app/src/main/java/app/organicmaps/widget/WheelProgressView.java b/android/app/src/main/java/app/organicmaps/widget/WheelProgressView.java index addf80b5b..27dca9982 100644 --- a/android/app/src/main/java/app/organicmaps/widget/WheelProgressView.java +++ b/android/app/src/main/java/app/organicmaps/widget/WheelProgressView.java @@ -12,12 +12,10 @@ import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; - import androidx.annotation.NonNull; import androidx.appcompat.widget.AppCompatImageView; import androidx.core.content.res.ResourcesCompat; import androidx.core.graphics.drawable.DrawableCompat; - import app.organicmaps.R; import app.organicmaps.util.Graphics; import app.organicmaps.util.ThemeUtils; @@ -72,7 +70,8 @@ public class WheelProgressView extends AppCompatImageView typedArray.recycle(); - mPendingDrawable = (AnimationDrawable) ResourcesCompat.getDrawable(getResources(), ThemeUtils.getResource(context, R.attr.wheelPendingAnimation), context.getTheme()); + mPendingDrawable = (AnimationDrawable) ResourcesCompat.getDrawable( + getResources(), ThemeUtils.getResource(context, R.attr.wheelPendingAnimation), context.getTheme()); Graphics.tint(mPendingDrawable, progressColor); mBgPaint = new Paint(); @@ -91,7 +90,8 @@ public class WheelProgressView extends AppCompatImageView @NonNull private static Drawable makeCenterDrawable(@NonNull Context context) { - Drawable normalDrawable = ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_close_spinner, context.getTheme()); + Drawable normalDrawable = + ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_close_spinner, context.getTheme()); Drawable wrapped = DrawableCompat.wrap(normalDrawable); DrawableCompat.setTint(wrapped.mutate(), ThemeUtils.getColor(context, R.attr.iconTint)); return normalDrawable; @@ -119,7 +119,7 @@ public class WheelProgressView extends AppCompatImageView if (mCenterDrawable instanceof BitmapDrawable) { - Bitmap bmp = ((BitmapDrawable)mCenterDrawable).getBitmap(); + Bitmap bmp = ((BitmapDrawable) mCenterDrawable).getBitmap(); int halfw = bmp.getWidth() / 2; int halfh = bmp.getHeight() / 2; mCenterDrawable.setBounds(mCenter.x - halfw, mCenter.y - halfh, mCenter.x + halfw, mCenter.y + halfh); @@ -163,5 +163,4 @@ public class WheelProgressView extends AppCompatImageView invalidate(); } - } diff --git a/android/app/src/main/java/app/organicmaps/widget/menu/MainMenu.java b/android/app/src/main/java/app/organicmaps/widget/menu/MainMenu.java index 5213c5c1b..e5c978820 100644 --- a/android/app/src/main/java/app/organicmaps/widget/menu/MainMenu.java +++ b/android/app/src/main/java/app/organicmaps/widget/menu/MainMenu.java @@ -1,8 +1,7 @@ package app.organicmaps.widget.menu; import android.view.View; - -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.util.UiUtils; public class MainMenu { @@ -52,8 +51,8 @@ public class MainMenu private class FrameLayoutChangeListener implements View.OnLayoutChangeListener { @Override - public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, - int oldTop, int oldRight, int oldBottom) + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, + int oldBottom) { mMenuHeight = bottom - top; mOnMenuSizeChangedListener.OnMenuSizeChange(UiUtils.isVisible(mFrame)); diff --git a/android/app/src/main/java/app/organicmaps/widget/menu/MyPositionButton.java b/android/app/src/main/java/app/organicmaps/widget/menu/MyPositionButton.java index 42ede08cd..875ed86a1 100644 --- a/android/app/src/main/java/app/organicmaps/widget/menu/MyPositionButton.java +++ b/android/app/src/main/java/app/organicmaps/widget/menu/MyPositionButton.java @@ -9,20 +9,18 @@ import android.view.View; import android.view.animation.Animation; import android.view.animation.LinearInterpolator; import android.view.animation.RotateAnimation; - import androidx.annotation.AttrRes; import androidx.annotation.DimenRes; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.core.content.res.ResourcesCompat; import androidx.core.widget.ImageViewCompat; -import com.google.android.material.floatingactionbutton.FloatingActionButton; - -import app.organicmaps.Map; import app.organicmaps.R; -import app.organicmaps.location.LocationState; +import app.organicmaps.sdk.Map; +import app.organicmaps.sdk.location.LocationState; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.UiUtils; +import com.google.android.material.floatingactionbutton.FloatingActionButton; public class MyPositionButton { @@ -47,9 +45,12 @@ public class MyPositionButton public void update(int mode) { Drawable image = mIcons.get(mode); - @AttrRes int colorAttr = R.attr.iconTint; - @DimenRes int sizeDimen = R.dimen.map_button_icon_size; - if (mode == LocationState.FOLLOW || mode == LocationState.FOLLOW_AND_ROTATE || mode == LocationState.PENDING_POSITION) + @AttrRes + int colorAttr = R.attr.iconTint; + @DimenRes + int sizeDimen = R.dimen.map_button_icon_size; + if (mode == LocationState.FOLLOW || mode == LocationState.FOLLOW_AND_ROTATE + || mode == LocationState.PENDING_POSITION) { colorAttr = androidx.appcompat.R.attr.colorAccent; if (mode == LocationState.PENDING_POSITION) @@ -61,7 +62,8 @@ public class MyPositionButton Context context = mButton.getContext(); if (image == null) { - @DrawableRes int drawableRes = switch (mode) + @DrawableRes + int drawableRes = switch (mode) { case LocationState.PENDING_POSITION -> R.drawable.ic_menu_location_pending; case LocationState.NOT_FOLLOW_NO_POSITION -> R.drawable.ic_location_off; @@ -70,7 +72,7 @@ public class MyPositionButton case LocationState.FOLLOW_AND_ROTATE -> R.drawable.ic_follow_and_rotate; default -> throw new IllegalArgumentException("Invalid button mode: " + mode); }; - image = ResourcesCompat.getDrawable(resources, drawableRes, context.getTheme()); + image = ResourcesCompat.getDrawable(resources, drawableRes, context.getTheme()); mIcons.put(mode, image); } @@ -81,8 +83,8 @@ public class MyPositionButton if (mode == LocationState.PENDING_POSITION) { - final RotateAnimation rotate = new RotateAnimation(0, 360, - Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); + final RotateAnimation rotate = + new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); rotate.setDuration(1000); rotate.setRepeatCount(Animation.INFINITE); diff --git a/android/app/src/main/java/app/organicmaps/widget/menu/NavMenu.java b/android/app/src/main/java/app/organicmaps/widget/menu/NavMenu.java index 855f364cd..e25f922db 100644 --- a/android/app/src/main/java/app/organicmaps/widget/menu/NavMenu.java +++ b/android/app/src/main/java/app/organicmaps/widget/menu/NavMenu.java @@ -5,23 +5,20 @@ import android.util.Pair; import android.view.View; import android.widget.Button; import android.widget.ImageView; -import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; - -import com.google.android.material.bottomsheet.BottomSheetBehavior; +import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.location.LocationHelper; import app.organicmaps.sdk.routing.RoutingInfo; -import app.organicmaps.sound.TtsPlayer; +import app.organicmaps.sdk.sound.TtsPlayer; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Graphics; -import app.organicmaps.util.StringUtils; import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.UiUtils; +import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.progressindicator.LinearProgressIndicator; - +import com.google.android.material.textview.MaterialTextView; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.concurrent.TimeUnit; @@ -34,15 +31,15 @@ public class NavMenu private final ImageView mTts; private final View mSpeedViewContainer; - private final TextView mSpeedValue; - private final TextView mSpeedUnits; - private final TextView mTimeHourValue; - private final TextView mTimeHourUnits; - private final TextView mTimeMinuteValue; - private final TextView mTimeMinuteUnits; - private final TextView mTimeEstimate; - private final TextView mDistanceValue; - private final TextView mDistanceUnits; + private final MaterialTextView mSpeedValue; + private final MaterialTextView mSpeedUnits; + private final MaterialTextView mTimeHourValue; + private final MaterialTextView mTimeHourUnits; + private final MaterialTextView mTimeMinuteValue; + private final MaterialTextView mTimeMinuteUnits; + private final MaterialTextView mTimeEstimate; + private final MaterialTextView mDistanceValue; + private final MaterialTextView mDistanceUnits; private final LinearProgressIndicator mRouteProgress; private final AppCompatActivity mActivity; @@ -50,7 +47,6 @@ public class NavMenu private int currentPeekHeight = 0; - public interface OnMenuSizeChangedListener { void OnMenuSizeChange(); @@ -58,7 +54,8 @@ public class NavMenu private final OnMenuSizeChangedListener mOnMenuSizeChangedListener; - public NavMenu(AppCompatActivity activity, NavMenuListener navMenuListener, OnMenuSizeChangedListener onMenuSizeChangedListener) + public NavMenu(AppCompatActivity activity, NavMenuListener navMenuListener, + OnMenuSizeChangedListener onMenuSizeChangedListener) { mActivity = activity; mNavMenuListener = navMenuListener; @@ -72,8 +69,7 @@ public class NavMenu mBottomSheetBackground.setOnClickListener(v -> collapseNavBottomSheet()); mBottomSheetBackground.setVisibility(View.GONE); mBottomSheetBackground.setAlpha(0); - mNavBottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() - { + mNavBottomSheetBehavior.addBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { @Override public void onStateChanged(@NonNull View bottomSheet, int newState) { @@ -81,7 +77,8 @@ public class NavMenu { mBottomSheetBackground.setVisibility(View.GONE); mBottomSheetBackground.setAlpha(0); - } else + } + else { mBottomSheetBackground.setVisibility(View.VISIBLE); } @@ -169,12 +166,11 @@ public class NavMenu public void refreshTts() { - mTts.setImageDrawable(TtsPlayer.isEnabled() ? Graphics.tint(mActivity, R.drawable.ic_voice_on, - androidx.appcompat.R.attr.colorAccent) - : Graphics.tint(mActivity, R.drawable.ic_voice_off)); + mTts.setImageDrawable(TtsPlayer.isEnabled() + ? Graphics.tint(mActivity, R.drawable.ic_voice_on, androidx.appcompat.R.attr.colorAccent) + : Graphics.tint(mActivity, R.drawable.ic_voice_off)); } - private void updateTime(int seconds) { updateTimeLeft(seconds); @@ -200,15 +196,15 @@ public class NavMenu private void updateTimeEstimate(int seconds) { - final String format = android.text.format.DateFormat.is24HourFormat(mTimeMinuteValue.getContext()) - ? "HH:mm" : "h:mm a"; + final String format = + android.text.format.DateFormat.is24HourFormat(mTimeMinuteValue.getContext()) ? "HH:mm" : "h:mm a"; final LocalTime localTime = LocalTime.now().plusSeconds(seconds); mTimeEstimate.setText(localTime.format(DateTimeFormatter.ofPattern(format))); } private void updateSpeedView(@NonNull RoutingInfo info) { - final Location last = LocationHelper.from(mActivity).getSavedLocation(); + final Location last = MwmApplication.from(mActivity).getLocationHelper().getSavedLocation(); if (last == null) return; diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/AxisValueFormatter.java b/android/app/src/main/java/app/organicmaps/widget/placepage/AxisValueFormatter.java index a96706f51..d3542f370 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/AxisValueFormatter.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/AxisValueFormatter.java @@ -1,10 +1,9 @@ package app.organicmaps.widget.placepage; import androidx.annotation.NonNull; - +import app.organicmaps.sdk.Framework; import com.github.mikephil.charting.charts.BarLineChartBase; import com.github.mikephil.charting.formatter.DefaultValueFormatter; -import app.organicmaps.Framework; public class AxisValueFormatter extends DefaultValueFormatter { diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/BookmarkColorDialogFragment.java b/android/app/src/main/java/app/organicmaps/widget/placepage/BookmarkColorDialogFragment.java index f9e1c0028..a1a966b63 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/BookmarkColorDialogFragment.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/BookmarkColorDialogFragment.java @@ -6,16 +6,13 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.widget.GridView; - import androidx.annotation.NonNull; - import app.organicmaps.R; import app.organicmaps.base.BaseMwmDialogFragment; import app.organicmaps.bookmarks.IconsAdapter; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.Icon; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.Icon; import com.google.android.material.dialog.MaterialAlertDialogBuilder; - import java.util.List; public class BookmarkColorDialogFragment extends BaseMwmDialogFragment @@ -59,7 +56,8 @@ public class BookmarkColorDialogFragment extends BaseMwmDialogFragment adapter.chooseItem(mIconColor); @SuppressLint("InflateParams") - final GridView gView = (GridView) LayoutInflater.from(requireActivity()).inflate(R.layout.fragment_color_grid, null); + final GridView gView = + (GridView) LayoutInflater.from(requireActivity()).inflate(R.layout.fragment_color_grid, null); gView.setAdapter(adapter); gView.setOnItemClickListener((arg0, who, pos, id) -> { if (mColorSetListener != null) @@ -69,5 +67,4 @@ public class BookmarkColorDialogFragment extends BaseMwmDialogFragment return gView; } - } diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/CoordinatesFormat.java b/android/app/src/main/java/app/organicmaps/widget/placepage/CoordinatesFormat.java index 98c8a454e..ad621f990 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/CoordinatesFormat.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/CoordinatesFormat.java @@ -2,12 +2,12 @@ package app.organicmaps.widget.placepage; public enum CoordinatesFormat { - LatLonDMS(0, "DMS", false), // Latitude, Longitude in degrees minutes seconds format, comma separated + LatLonDMS(0, "DMS", false), // Latitude, Longitude in degrees minutes seconds format, comma separated LatLonDecimal(1, "Decimal", false), // Latitude, Longitude in decimal format, comma separated - OLCFull(2, "OLC", false), // Open location code, full format - OSMLink(3, "osm.org", false), // Link to the OSM. E.g. https://osm.org/go/xcXjyqQlq-?m= - UTM(4, "UTM", true), // Universal Transverse Mercator - MGRS(5, "MGRS", true); // Military Grid Reference System + OLCFull(2, "OLC", false), // Open location code, full format + OSMLink(3, "osm.org", false), // Link to the OSM. E.g. https://osm.org/go/xcXjyqQlq-?m= + UTM(4, "UTM", true), // Universal Transverse Mercator + MGRS(5, "MGRS", true); // Military Grid Reference System private final int id; private final String label; @@ -37,7 +37,7 @@ public enum CoordinatesFormat public static CoordinatesFormat fromId(int id) { - for (CoordinatesFormat cursor: CoordinatesFormat.values()) + for (CoordinatesFormat cursor : CoordinatesFormat.values()) { if (cursor.id == id) return cursor; diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/CurrentLocationMarkerView.java b/android/app/src/main/java/app/organicmaps/widget/placepage/CurrentLocationMarkerView.java index ce2112d45..110498df5 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/CurrentLocationMarkerView.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/CurrentLocationMarkerView.java @@ -2,16 +2,13 @@ package app.organicmaps.widget.placepage; import android.annotation.SuppressLint; import android.content.Context; - import androidx.annotation.NonNull; - +import app.organicmaps.R; import com.github.mikephil.charting.components.MarkerView; import com.github.mikephil.charting.utils.MPPointF; -import app.organicmaps.R; @SuppressLint("ViewConstructor") -public -class CurrentLocationMarkerView extends MarkerView +public class CurrentLocationMarkerView extends MarkerView { /** * Constructor. Sets up the MarkerView with a custom layout resource. @@ -24,7 +21,8 @@ class CurrentLocationMarkerView extends MarkerView } @Override - public MPPointF getOffset() { + public MPPointF getOffset() + { return new MPPointF(-(getWidth() / 2f), -getHeight()); } diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/DirectionFragment.java b/android/app/src/main/java/app/organicmaps/widget/placepage/DirectionFragment.java index 28af2112b..2062281ee 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/DirectionFragment.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/DirectionFragment.java @@ -5,36 +5,32 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - -import app.organicmaps.Framework; import app.organicmaps.MwmActivity; +import app.organicmaps.MwmApplication; import app.organicmaps.R; import app.organicmaps.base.BaseMwmDialogFragment; -import app.organicmaps.bookmarks.data.DistanceAndAzimut; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.LocationListener; -import app.organicmaps.location.SensorHelper; -import app.organicmaps.location.SensorListener; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.bookmarks.data.DistanceAndAzimut; +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.location.LocationListener; +import app.organicmaps.sdk.location.SensorListener; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Utils; import app.organicmaps.widget.ArrowView; +import com.google.android.material.textview.MaterialTextView; -public class DirectionFragment extends BaseMwmDialogFragment - implements LocationListener, SensorListener +public class DirectionFragment extends BaseMwmDialogFragment implements LocationListener, SensorListener { private static final String EXTRA_MAP_OBJECT = "MapObject"; private ArrowView mAvDirection; - private TextView mTvTitle; - private TextView mTvSubtitle; - private TextView mTvDistance; - private TextView mTvAzimuth; + private MaterialTextView mTvTitle; + private MaterialTextView mTvSubtitle; + private MaterialTextView mTvDistance; + private MaterialTextView mTvAzimuth; private MapObject mMapObject; @@ -97,13 +93,12 @@ public class DirectionFragment extends BaseMwmDialogFragment } } - @Override public void onResume() { super.onResume(); - LocationHelper.from(requireContext()).addListener(this); - SensorHelper.from(requireContext()).addListener(this); + MwmApplication.from(requireContext()).getLocationHelper().addListener(this); + MwmApplication.from(requireContext()).getSensorHelper().addListener(this); ((MwmActivity) requireActivity()).hideOrShowUIWithoutClosingPlacePage(true); refreshViews(); } @@ -112,8 +107,8 @@ public class DirectionFragment extends BaseMwmDialogFragment public void onPause() { super.onPause(); - LocationHelper.from(requireContext()).removeListener(this); - SensorHelper.from(requireContext()).removeListener(this); + MwmApplication.from(requireContext()).getLocationHelper().removeListener(this); + MwmApplication.from(requireContext()).getSensorHelper().removeListener(this); } @Override @@ -128,9 +123,8 @@ public class DirectionFragment extends BaseMwmDialogFragment { if (mMapObject != null) { - final DistanceAndAzimut distanceAndAzimuth = - Framework.nativeGetDistanceAndAzimuthFromLatLon(mMapObject.getLat(), mMapObject.getLon(), - location.getLatitude(), location.getLongitude(), 0.0); + final DistanceAndAzimut distanceAndAzimuth = Framework.nativeGetDistanceAndAzimuthFromLatLon( + mMapObject.getLat(), mMapObject.getLon(), location.getLatitude(), location.getLongitude(), 0.0); mTvDistance.setText(distanceAndAzimuth.getDistance().toString(requireContext())); } } @@ -138,20 +132,18 @@ public class DirectionFragment extends BaseMwmDialogFragment @Override public void onCompassUpdated(double north) { - final Location last = LocationHelper.from(requireContext()).getSavedLocation(); + final Location last = MwmApplication.from(requireContext()).getLocationHelper().getSavedLocation(); if (last == null || mMapObject == null) return; final DistanceAndAzimut da = Framework.nativeGetDistanceAndAzimuthFromLatLon( - mMapObject.getLat(), mMapObject.getLon(), - last.getLatitude(), last.getLongitude(), north); + mMapObject.getLat(), mMapObject.getLon(), last.getLatitude(), last.getLongitude(), north); if (da.getAzimuth() >= 0) { mAvDirection.setAzimuth(da.getAzimuth()); final DistanceAndAzimut daAbs = Framework.nativeGetDistanceAndAzimuthFromLatLon( - mMapObject.getLat(), mMapObject.getLon(), - last.getLatitude(), last.getLongitude(), 0.0); + mMapObject.getLat(), mMapObject.getLon(), last.getLatitude(), last.getLongitude(), 0.0); mTvAzimuth.setText(StringUtils.formatUsingUsLocale("%.0f°", Math.toDegrees(daAbs.getAzimuth()))); } } diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/EditBookmarkFragment.java b/android/app/src/main/java/app/organicmaps/widget/placepage/EditBookmarkFragment.java index 35a925ca2..2bcfee1ee 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/EditBookmarkFragment.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/EditBookmarkFragment.java @@ -9,7 +9,6 @@ import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; @@ -21,22 +20,20 @@ import app.organicmaps.R; import app.organicmaps.base.BaseMwmDialogFragment; import app.organicmaps.bookmarks.ChooseBookmarkCategoryFragment; import app.organicmaps.bookmarks.ChooseBookmarkCategoryFragment.Listener; -import app.organicmaps.bookmarks.data.BookmarkCategory; -import app.organicmaps.bookmarks.data.BookmarkInfo; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.Icon; -import app.organicmaps.bookmarks.data.Track; +import app.organicmaps.sdk.bookmarks.data.BookmarkCategory; +import app.organicmaps.sdk.bookmarks.data.BookmarkInfo; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.Icon; +import app.organicmaps.sdk.bookmarks.data.Track; +import app.organicmaps.sdk.util.UiUtils; import app.organicmaps.util.Graphics; import app.organicmaps.util.InputUtils; -import app.organicmaps.util.UiUtils; import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener; - import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.imageview.ShapeableImageView; import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textview.MaterialTextView; - import java.util.List; public class EditBookmarkFragment extends BaseMwmDialogFragment implements View.OnClickListener, Listener @@ -73,8 +70,7 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. } public static void editBookmark(long categoryId, long bookmarkId, @NonNull Context context, - @NonNull FragmentManager manager, - @Nullable EditBookmarkListener listener) + @NonNull FragmentManager manager, @Nullable EditBookmarkListener listener) { final Bundle args = new Bundle(); args.putInt(EXTRA_BOOKMARK_TYPE, TYPE_BOOKMARK); @@ -88,7 +84,8 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. fragment.show(manager, name); } - public static void editTrack(long categoryId, long trackId, Context context, FragmentManager manager, @Nullable EditBookmarkListener listener) + public static void editTrack(long categoryId, long trackId, Context context, FragmentManager manager, + @Nullable EditBookmarkListener listener) { final Bundle args = new Bundle(); args.putInt(EXTRA_BOOKMARK_TYPE, TYPE_TRACK); @@ -125,10 +122,10 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. mEtName = view.findViewById(R.id.et__bookmark_name); clearNameBtn = view.findViewById(R.id.edit_bookmark_name_input); clearNameBtn.setEndIconOnClickListener(v -> clearAndFocus(mEtName)); - mEtName.addTextChangedListener(new TextWatcher() - { + mEtName.addTextChangedListener(new TextWatcher() { @Override - public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {} + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) + {} @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) @@ -137,7 +134,8 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. } @Override - public void afterTextChanged(Editable editable) {} + public void afterTextChanged(Editable editable) + {} }); mEtDescription = view.findViewById(R.id.et__description); mTvBookmarkGroup = view.findViewById(R.id.tv__bookmark_set); @@ -145,7 +143,7 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. mIvColor = view.findViewById(R.id.iv__bookmark_color); mIvColor.setOnClickListener(this); - //For tracks an bookmarks same category is used so this portion is common for both + // For tracks an bookmarks same category is used so this portion is common for both if (savedInstanceState != null && savedInstanceState.getParcelable(STATE_BOOKMARK_CATEGORY) != null) mBookmarkCategory = savedInstanceState.getParcelable(STATE_BOOKMARK_CATEGORY); else @@ -236,8 +234,8 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. boolean movedFromCategory = mBookmark.getCategoryId() != mBookmarkCategory.getId(); if (movedFromCategory) BookmarkManager.INSTANCE.notifyCategoryChanging(mBookmark, mBookmarkCategory.getId()); - BookmarkManager.INSTANCE.notifyParametersUpdating(mBookmark, mEtName.getText().toString(), - mIcon, mEtDescription.getText().toString()); + BookmarkManager.INSTANCE.notifyParametersUpdating(mBookmark, mEtName.getText().toString(), mIcon, + mEtDescription.getText().toString()); if (mListener != null) mListener.onBookmarkSaved(mBookmark.getBookmarkId(), movedFromCategory); @@ -254,8 +252,8 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. boolean movedFromCategory = mTrack.getCategoryId() != mBookmarkCategory.getId(); if (movedFromCategory) BookmarkManager.INSTANCE.notifyCategoryChanging(mTrack, mBookmarkCategory.getId()); - BookmarkManager.INSTANCE.notifyParametersUpdating(mTrack, mEtName.getText().toString(), - mColor, mEtDescription.getText().toString()); + BookmarkManager.INSTANCE.notifyParametersUpdating(mTrack, mEtName.getText().toString(), mColor, + mEtDescription.getText().toString()); if (mListener != null) mListener.onBookmarkSaved(mTrack.getTrackId(), movedFromCategory); dismiss(); @@ -344,11 +342,9 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. { if (mIcon != null) { - Drawable circle = Graphics.drawCircleAndImage(mIcon.argb(), - R.dimen.track_circle_size, - R.drawable.ic_bookmark_none, - R.dimen.bookmark_icon_size, - requireContext()); + Drawable circle = + Graphics.drawCircleAndImage(mIcon.argb(), R.dimen.track_circle_size, app.organicmaps.sdk.R.drawable.ic_bookmark_none, + R.dimen.bookmark_icon_size, requireContext()); mIvColor.setImageDrawable(circle); } } @@ -357,9 +353,7 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. { if (mColor == -1) return; - Drawable circle = Graphics.drawCircle(mColor, - R.dimen.track_circle_size, - requireContext().getResources()); + Drawable circle = Graphics.drawCircle(mColor, R.dimen.track_circle_size, requireContext().getResources()); mIvColor.setImageDrawable(circle); } @@ -378,8 +372,7 @@ public class EditBookmarkFragment extends BaseMwmDialogFragment implements View. if (TextUtils.isEmpty(mEtDescription.getText())) { - mEtDescription.setText( - BookmarkManager.INSTANCE.getBookmarkDescription(mBookmark.getBookmarkId())); + mEtDescription.setText(BookmarkManager.INSTANCE.getBookmarkDescription(mBookmark.getBookmarkId())); } refreshCategory(); refreshColorMarker(); diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/ElevationProfileChart.java b/android/app/src/main/java/app/organicmaps/widget/placepage/ElevationProfileChart.java index 79b2fb2db..83ddf962a 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/ElevationProfileChart.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/ElevationProfileChart.java @@ -3,7 +3,6 @@ package app.organicmaps.widget.placepage; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; - import com.github.mikephil.charting.charts.LineChart; public class ElevationProfileChart extends LineChart @@ -32,6 +31,6 @@ public class ElevationProfileChart extends LineChart private boolean hasZoom() { - return getScaleX() < 1 || getScaleY() < 1; + return getScaleX() < 1 || getScaleY() < 1; } } diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/ElevationProfileViewRenderer.java b/android/app/src/main/java/app/organicmaps/widget/placepage/ElevationProfileViewRenderer.java index 7a7fba5fd..f0f4442cb 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/ElevationProfileViewRenderer.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/ElevationProfileViewRenderer.java @@ -5,18 +5,16 @@ import android.os.Bundle; import android.view.View; import android.widget.RelativeLayout; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.widget.NestedScrollView; - import app.organicmaps.ChartController; -import app.organicmaps.Framework; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.ElevationInfo; import app.organicmaps.routing.RoutingController; -import app.organicmaps.util.UiUtils; - +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.bookmarks.data.ElevationInfo; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.widget.placepage.PlacePageData; import java.util.Objects; @SuppressWarnings("unused") // https://github.com/organicmaps/organicmaps/issues/2829 @@ -74,8 +72,7 @@ public class ElevationProfileViewRenderer implements PlacePageStateListener mMaxAltitude.setText(formatDistance(context, mElevationInfo.getMaxAltitude())); mMinAltitude.setText(formatDistance(context, mElevationInfo.getMinAltitude())); UiUtils.hideIf(mElevationInfo.getDuration() == 0, mTimeContainer); - mTime.setText(RoutingController.formatRoutingTime(mTitle.getContext(), - (int) mElevationInfo.getDuration(), + mTime.setText(RoutingController.formatRoutingTime(mTitle.getContext(), (int) mElevationInfo.getDuration(), R.dimen.text_size_body_2)); } @@ -128,14 +125,14 @@ public class ElevationProfileViewRenderer implements PlacePageStateListener public void onSave(@NonNull Bundle outState) { -// outState.putParcelable(PlacePageUtils.EXTRA_PLACE_PAGE_DATA, mElevationInfo); + // outState.putParcelable(PlacePageUtils.EXTRA_PLACE_PAGE_DATA, mElevationInfo); } public void onRestore(@NonNull Bundle inState) { -// mElevationInfo = BundleCompat.getParcelable(inState, PlacePageUtils.EXTRA_PLACE_PAGE_DATA, ElevationInfo.class); -// if (mElevationInfo != null) -// render(mElevationInfo); + // mElevationInfo = BundleCompat.getParcelable(inState, PlacePageUtils.EXTRA_PLACE_PAGE_DATA, + // ElevationInfo.class); if (mElevationInfo != null) + // render(mElevationInfo); } public void onHide() @@ -143,5 +140,4 @@ public class ElevationProfileViewRenderer implements PlacePageStateListener mScrollView.scrollTo(0, 0); mChartController.onHide(); } - } diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/FloatingMarkerView.java b/android/app/src/main/java/app/organicmaps/widget/placepage/FloatingMarkerView.java index b965b17d4..a58ab35b1 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/FloatingMarkerView.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/FloatingMarkerView.java @@ -9,18 +9,16 @@ import android.view.LayoutInflater; import android.view.View; import android.widget.RelativeLayout; import android.widget.TextView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - +import app.organicmaps.R; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.util.StringUtils; import com.github.mikephil.charting.charts.Chart; import com.github.mikephil.charting.components.IMarker; import com.github.mikephil.charting.data.Entry; import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.utils.MPPointF; -import app.organicmaps.Framework; -import app.organicmaps.R; -import app.organicmaps.util.StringUtils; @SuppressLint("ViewConstructor") public class FloatingMarkerView extends RelativeLayout implements IMarker @@ -76,12 +74,14 @@ public class FloatingMarkerView extends RelativeLayout implements IMarker LayoutInflater.from(getContext()).inflate(R.layout.floating_marker_view, this, true); } - public void setChartView(@NonNull Chart chart) { + public void setChartView(@NonNull Chart chart) + { mChart = chart; } @Nullable - public Chart getChartView() { + public Chart getChartView() + { return mChart; } @@ -137,10 +137,11 @@ public class FloatingMarkerView extends RelativeLayout implements IMarker float halfImg = Math.abs(mImage.getWidth()) / 2f; int wholeText = Math.abs(mInfoFloatingContainer.getWidth()); float factor = calcHorizontalFactor(); - return x + (halfImg + wholeText ) * factor >= getChartView().getXChartMax(); + return x + (halfImg + wholeText) * factor >= getChartView().getXChartMax(); } - private float calcHorizontalFactor() { + private float calcHorizontalFactor() + { float delta = getChartView().getXChartMax() - getChartView().getXChartMin(); return delta / getChartView().getContentRect().width(); } @@ -149,7 +150,7 @@ public class FloatingMarkerView extends RelativeLayout implements IMarker { float height = getChartView().getContentRect().height(); float delta = getChartView().getYMax() - getChartView().getYMin(); - float factor = delta / height; + float factor = delta / height; return factor * mTextContentContainer.getHeight(); } @@ -184,7 +185,8 @@ public class FloatingMarkerView extends RelativeLayout implements IMarker private void updatePointValues(@NonNull Entry entry) { mDistanceTextView.setText(R.string.elevation_profile_distance); - mDistanceValueView.setText(StringUtils.nativeFormatDistance(entry.getX()).toString(mDistanceValueView.getContext())); + mDistanceValueView.setText( + StringUtils.nativeFormatDistance(entry.getX()).toString(mDistanceValueView.getContext())); mAltitudeView.setText(Framework.nativeFormatAltitude(entry.getY())); } @@ -224,7 +226,6 @@ public class FloatingMarkerView extends RelativeLayout implements IMarker @Override public void draw(Canvas canvas, float posX, float posY) { - MPPointF offset = getOffsetForDrawingAtPoint(posX, posY); int saveId = canvas.save(); diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlaceDescriptionActivity.java b/android/app/src/main/java/app/organicmaps/widget/placepage/PlaceDescriptionActivity.java index d042868c4..f5a425ae8 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlaceDescriptionActivity.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/PlaceDescriptionActivity.java @@ -2,10 +2,8 @@ package app.organicmaps.widget.placepage; import android.content.Context; import android.content.Intent; - import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; - import app.organicmaps.base.BaseToolbarActivity; public class PlaceDescriptionActivity extends BaseToolbarActivity @@ -21,13 +19,14 @@ public class PlaceDescriptionActivity extends BaseToolbarActivity public static void start(@NonNull Context context, @NonNull String title, @NonNull String description) { Intent intent = new Intent(context, PlaceDescriptionActivity.class) - .putExtra(PlaceDescriptionFragment.EXTRA_DESCRIPTION, description) - .putExtra(EXTRA_TITLE, title); + .putExtra(PlaceDescriptionFragment.EXTRA_DESCRIPTION, description) + .putExtra(EXTRA_TITLE, title); context.startActivity(intent); } @Override - protected void onStart() { + protected void onStart() + { super.onStart(); String toolbarTitle = getIntent().getStringExtra(EXTRA_TITLE); this.getToolbar().setTitle(toolbarTitle); diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlaceDescriptionFragment.java b/android/app/src/main/java/app/organicmaps/widget/placepage/PlaceDescriptionFragment.java index 2b2ee32b9..a7588271e 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlaceDescriptionFragment.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/PlaceDescriptionFragment.java @@ -5,7 +5,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.webkit.WebView; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.view.ViewCompat; @@ -13,7 +12,6 @@ import app.organicmaps.R; import app.organicmaps.base.BaseMwmFragment; import app.organicmaps.util.Utils; import app.organicmaps.util.WindowInsetUtils; - import java.util.Objects; public class PlaceDescriptionFragment extends BaseMwmFragment @@ -29,14 +27,12 @@ public class PlaceDescriptionFragment extends BaseMwmFragment public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - mDescription = Objects.requireNonNull(requireArguments() - .getString(EXTRA_DESCRIPTION)); + mDescription = Objects.requireNonNull(requireArguments().getString(EXTRA_DESCRIPTION)); } @Nullable @Override - public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, - @Nullable Bundle savedInstanceState) + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_place_description, container, false); WebView webView = root.findViewById(R.id.webview); diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageButtonFactory.java b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageButtonFactory.java index 5168ad5df..5f3978a0a 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageButtonFactory.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageButtonFactory.java @@ -1,7 +1,8 @@ package app.organicmaps.widget.placepage; -import android.content.Context; +import static app.organicmaps.sdk.widget.placepage.PlacePageButtonFactory.nativeHasRecentlyDeletedBookmark; +import android.content.Context; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.StringRes; @@ -13,8 +14,10 @@ public class PlacePageButtonFactory { static PlacePageButton createButton(PlacePageButtons.ButtonType buttonType, @NonNull Context context) { - @StringRes int titleId = 0; - @DrawableRes int iconId = switch (buttonType) + @StringRes + int titleId = 0; + @DrawableRes + int iconId = switch (buttonType) { case BACK -> { @@ -72,8 +75,6 @@ public class PlacePageButtonFactory yield R.drawable.ic_more; } }; - return new PlacePageButton(titleId, iconId, buttonType); + return new PlacePageButton(titleId, iconId, buttonType); } - - private native static boolean nativeHasRecentlyDeletedBookmark(); } diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageButtons.java b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageButtons.java index ddc93bbe1..cc98ca6c4 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageButtons.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageButtons.java @@ -4,7 +4,6 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.AttrRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -13,15 +12,12 @@ import androidx.core.view.WindowInsetsCompat; import androidx.fragment.app.Fragment; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; - -import com.google.android.material.imageview.ShapeableImageView; -import com.google.android.material.textview.MaterialTextView; - import app.organicmaps.R; import app.organicmaps.util.Graphics; import app.organicmaps.util.WindowInsetUtils.PaddingInsetsListener; import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment; - +import com.google.android.material.imageview.ShapeableImageView; +import com.google.android.material.textview.MaterialTextView; import java.util.ArrayList; import java.util.List; @@ -36,7 +32,8 @@ public final class PlacePageButtons extends Fragment implements Observer collectButtons(List items) + private @NonNull List collectButtons(List items) { List res = new ArrayList<>(); int count = items.size(); @@ -93,7 +90,7 @@ public final class PlacePageButtons extends Fragment implements Observer buttons) @@ -116,9 +113,8 @@ public final class PlacePageButtons extends Fragment implements Observer { if (current.getType() == ButtonType.MORE) diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageController.java b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageController.java index cbd1fe347..086b6d668 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageController.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageController.java @@ -9,7 +9,6 @@ import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.Insets; @@ -22,32 +21,30 @@ import androidx.fragment.app.FragmentManager; import androidx.interpolator.view.animation.FastOutSlowInInterpolator; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; -import app.organicmaps.Framework; import app.organicmaps.MwmActivity; import app.organicmaps.R; import app.organicmaps.api.Const; -import app.organicmaps.bookmarks.data.BookmarkManager; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.bookmarks.data.RoadWarningMarkType; import app.organicmaps.intent.Factory; import app.organicmaps.routing.RoutingController; -import app.organicmaps.settings.RoadType; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.bookmarks.data.BookmarkManager; +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.bookmarks.data.RoadWarningMarkType; +import app.organicmaps.sdk.settings.RoadType; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.log.Logger; +import app.organicmaps.sdk.ChoosePositionMode; import app.organicmaps.util.ThemeUtils; -import app.organicmaps.util.UiUtils; import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment; import app.organicmaps.util.bottomsheet.MenuBottomSheetItem; -import app.organicmaps.util.log.Logger; import com.google.android.material.bottomsheet.BottomSheetBehavior; import com.google.android.material.shape.MaterialShapeDrawable; - import java.util.ArrayList; import java.util.List; -public class PlacePageController extends Fragment implements - PlacePageView.PlacePageViewListener, - PlacePageButtons.PlacePageButtonClickListener, - MenuBottomSheetFragment.MenuBottomSheetInterface, - Observer +public class PlacePageController + extends Fragment implements PlacePageView.PlacePageViewListener, PlacePageButtons.PlacePageButtonClickListener, + MenuBottomSheetFragment.MenuBottomSheetInterface, Observer { private static final String TAG = PlacePageController.class.getSimpleName(); private static final String PLACE_PAGE_BUTTONS_FRAGMENT_TAG = "PLACE_PAGE_BUTTONS"; @@ -78,8 +75,7 @@ public class PlacePageController extends Fragment implements private ValueAnimator mCustomPeekHeightAnimator; private PlacePageRouteSettingsListener mPlacePageRouteSettingsListener; - private final Observer mPlacePageDistanceToTopObserver = new Observer<>() - { + private final Observer mPlacePageDistanceToTopObserver = new Observer<>() { private float mPlacePageCornerRadius; // This updates mPlacePageStatusBarBackground visibility and mPlacePage corner radius @@ -125,33 +121,34 @@ public class PlacePageController extends Fragment implements } }; - private final BottomSheetBehavior.BottomSheetCallback mDefaultBottomSheetCallback = new BottomSheetBehavior.BottomSheetCallback() - { - @Override - public void onStateChanged(@NonNull View bottomSheet, int newState) - { - Logger.d(TAG, "State change, new = " + PlacePageUtils.toString(newState)); - if (PlacePageUtils.isSettlingState(newState) || PlacePageUtils.isDraggingState(newState)) - return; + private final BottomSheetBehavior.BottomSheetCallback mDefaultBottomSheetCallback = + new BottomSheetBehavior.BottomSheetCallback() { + @Override + public void onStateChanged(@NonNull View bottomSheet, int newState) + { + Logger.d(TAG, "State change, new = " + PlacePageUtils.toString(newState)); + if (PlacePageUtils.isSettlingState(newState) || PlacePageUtils.isDraggingState(newState)) + return; - PlacePageUtils.updateMapViewport(mCoordinator, mDistanceToTop, mViewportMinHeight); + PlacePageUtils.updateMapViewport(mCoordinator, mDistanceToTop, mViewportMinHeight); - if (PlacePageUtils.isHiddenState(newState)) - onHiddenInternal(); - } + if (PlacePageUtils.isHiddenState(newState)) + onHiddenInternal(); + } - @Override - public void onSlide(@NonNull View bottomSheet, float slideOffset) - { - stopCustomPeekHeightAnimation(); - mDistanceToTop = bottomSheet.getTop(); - mViewModel.setPlacePageDistanceToTop(mDistanceToTop); - } - }; + @Override + public void onSlide(@NonNull View bottomSheet, float slideOffset) + { + stopCustomPeekHeightAnimation(); + mDistanceToTop = bottomSheet.getTop(); + mViewModel.setPlacePageDistanceToTop(mDistanceToTop); + } + }; @Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.place_page_container_fragment, container, false); } @@ -167,7 +164,8 @@ public class PlacePageController extends Fragment implements mViewportMinHeight = res.getDimensionPixelSize(R.dimen.viewport_min_height); mButtonsHeight = (int) res.getDimension(R.dimen.place_page_buttons_height); mMaxButtons = res.getInteger(R.integer.pp_buttons_max); - mRoutingHeaderHeight = (int) res.getDimension(ThemeUtils.getResource(requireContext(), androidx.appcompat.R.attr.actionBarSize)); + mRoutingHeaderHeight = + (int) res.getDimension(ThemeUtils.getResource(requireContext(), androidx.appcompat.R.attr.actionBarSize)); mCoordinator = activity.findViewById(R.id.coordinator); mPlacePage = view.findViewById(R.id.placepage); @@ -189,8 +187,10 @@ public class PlacePageController extends Fragment implements ViewCompat.setOnApplyWindowInsetsListener(mPlacePage, (v, windowInsets) -> { mCurrentWindowInsets = windowInsets; final Insets insets = mCurrentWindowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); - final ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) mPlacePageStatusBarBackground.getLayoutParams(); - // Layout calculations are heavy so we compute them once then move the view from behind the place page to the status bar + final ViewGroup.MarginLayoutParams layoutParams = + (ViewGroup.MarginLayoutParams) mPlacePageStatusBarBackground.getLayoutParams(); + // Layout calculations are heavy so we compute them once then move the view from behind the place page to the + // status bar layoutParams.height = insets.top; layoutParams.width = mPlacePage.getWidth(); // Make sure the view is centered within the insets as is the place page @@ -225,7 +225,9 @@ public class PlacePageController extends Fragment implements private void onHiddenInternal() { - Framework.nativeDeactivatePopup(); + if (ChoosePositionMode.get() == ChoosePositionMode.None) + Framework.nativeDeactivatePopup(); + Framework.nativeDeactivateMapSelectionCircle(false); PlacePageUtils.updateMapViewport(mCoordinator, mDistanceToTop, mViewportMinHeight); resetPlacePageHeightBounds(); removePlacePageFragments(); @@ -241,11 +243,8 @@ public class PlacePageController extends Fragment implements for (int i = mMaxButtons - 1; i < currentItems.size(); i++) { final PlacePageButton bsItem = PlacePageButtonFactory.createButton(currentItems.get(i), requireActivity()); - items.add(new MenuBottomSheetItem( - bsItem.getTitle(), - bsItem.getIcon(), - () -> onPlacePageButtonClick(bsItem.getType()) - )); + items.add( + new MenuBottomSheetItem(bsItem.getTitle(), bsItem.getIcon(), () -> onPlacePageButtonClick(bsItem.getType()))); } return items; } @@ -281,8 +280,8 @@ public class PlacePageController extends Fragment implements { final int peekHeight = calculatePeekHeight(); final Insets insets = mCurrentWindowInsets != null - ? mCurrentWindowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - : Insets.NONE; + ? mCurrentWindowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + : Insets.NONE; // Make sure the place page can reach the peek height final int minHeight = Math.max(peekHeight, mFrameHeight); // Prevent the place page from showing under the status bar @@ -314,7 +313,8 @@ public class PlacePageController extends Fragment implements final int state = mPlacePageBehavior.getState(); // Do not animate the peek height if the place page should not be collapsed (eg: when returning from editor) - final boolean shouldAnimate = !(PlacePageUtils.isExpandedState(state) && !mShouldCollapse) && !PlacePageUtils.isHiddenState(state); + final boolean shouldAnimate = + !(PlacePageUtils.isExpandedState(state) && !mShouldCollapse) && !PlacePageUtils.isHiddenState(state); if (shouldAnimate) animatePeekHeight(peekHeight); else @@ -330,7 +330,8 @@ public class PlacePageController extends Fragment implements */ private void animatePeekHeight(int peekHeight) { - if (mCurrentWindowInsets == null) { + if (mCurrentWindowInsets == null) + { return; } final int bottomInsets = mCurrentWindowInsets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom; @@ -444,10 +445,10 @@ public class PlacePageController extends Fragment implements return; final Intent result = new Intent(); result.putExtra(Const.EXTRA_POINT_LAT, mMapObject.getLat()) - .putExtra(Const.EXTRA_POINT_LON, mMapObject.getLon()) - .putExtra(Const.EXTRA_POINT_NAME, mMapObject.getTitle()) - .putExtra(Const.EXTRA_POINT_ID, mMapObject.getApiId()) - .putExtra(Const.EXTRA_ZOOM_LEVEL, Framework.nativeGetDrawScale()); + .putExtra(Const.EXTRA_POINT_LON, mMapObject.getLon()) + .putExtra(Const.EXTRA_POINT_NAME, mMapObject.getTitle()) + .putExtra(Const.EXTRA_POINT_ID, mMapObject.getApiId()) + .putExtra(Const.EXTRA_ZOOM_LEVEL, Framework.nativeGetDrawScale()); requireActivity().setResult(Activity.RESULT_OK, result); requireActivity().finish(); } @@ -520,17 +521,11 @@ public class PlacePageController extends Fragment implements if (placePageButtonsFragment != null) { - fm.beginTransaction() - .setReorderingAllowed(true) - .remove(placePageButtonsFragment) - .commit(); + fm.beginTransaction().setReorderingAllowed(true).remove(placePageButtonsFragment).commit(); } if (placePageFragment != null) { - fm.beginTransaction() - .setReorderingAllowed(true) - .remove(placePageFragment) - .commit(); + fm.beginTransaction().setReorderingAllowed(true).remove(placePageFragment).commit(); } mViewModel.setMapObject(null); } @@ -541,16 +536,16 @@ public class PlacePageController extends Fragment implements if (fm.findFragmentByTag(PLACE_PAGE_FRAGMENT_TAG) == null) { fm.beginTransaction() - .setReorderingAllowed(true) - .add(R.id.placepage_fragment, PlacePageView.class, null, PLACE_PAGE_FRAGMENT_TAG) - .commit(); + .setReorderingAllowed(true) + .add(R.id.placepage_fragment, PlacePageView.class, null, PLACE_PAGE_FRAGMENT_TAG) + .commit(); } if (fm.findFragmentByTag(PLACE_PAGE_BUTTONS_FRAGMENT_TAG) == null) { fm.beginTransaction() - .setReorderingAllowed(true) - .add(R.id.pp_buttons_fragment, PlacePageButtons.class, null, PLACE_PAGE_BUTTONS_FRAGMENT_TAG) - .commit(); + .setReorderingAllowed(true) + .add(R.id.pp_buttons_fragment, PlacePageButtons.class, null, PLACE_PAGE_BUTTONS_FRAGMENT_TAG) + .commit(); } } @@ -582,17 +577,15 @@ public class PlacePageController extends Fragment implements if (needToShowRoutingButtons && RoutingController.get().isStopPointAllowed()) buttons.add(PlacePageButtons.ButtonType.ROUTE_ADD); else - buttons.add(mapObject.isBookmark() - ? PlacePageButtons.ButtonType.BOOKMARK_DELETE - : PlacePageButtons.ButtonType.BOOKMARK_SAVE); + buttons.add(mapObject.isBookmark() ? PlacePageButtons.ButtonType.BOOKMARK_DELETE + : PlacePageButtons.ButtonType.BOOKMARK_SAVE); if (needToShowRoutingButtons) { buttons.add(PlacePageButtons.ButtonType.ROUTE_TO); if (RoutingController.get().isStopPointAllowed()) - buttons.add(mapObject.isBookmark() - ? PlacePageButtons.ButtonType.BOOKMARK_DELETE - : PlacePageButtons.ButtonType.BOOKMARK_SAVE); + buttons.add(mapObject.isBookmark() ? PlacePageButtons.ButtonType.BOOKMARK_DELETE + : PlacePageButtons.ButtonType.BOOKMARK_SAVE); } } mViewModel.setCurrentButtons(buttons); @@ -603,21 +596,20 @@ public class PlacePageController extends Fragment implements { final Activity activity = requireActivity(); final Intent intent = activity.getIntent(); - final boolean showBackButton = (intent != null && (Factory.isStartedForApiResult(intent) || - !TextUtils.isEmpty(Framework.nativeGetParsedBackUrl()))); + final boolean showBackButton = + (intent != null + && (Factory.isStartedForApiResult(intent) || !TextUtils.isEmpty(Framework.nativeGetParsedBackUrl()))); mMapObject = mapObject; if (mapObject != null) { setPlacePageInteractions(true); // Only collapse the place page if the data is different from the one already available - mShouldCollapse = PlacePageUtils.isHiddenState(mPlacePageBehavior.getState()) || !MapObject.same(mPreviousMapObject, mMapObject); + mShouldCollapse = PlacePageUtils.isHiddenState(mPlacePageBehavior.getState()) + || !MapObject.same(mPreviousMapObject, mMapObject); mPreviousMapObject = mMapObject; // Place page will automatically open when the bottom sheet content is loaded so we can compute the peek height createPlacePageFragments(); - updateButtons( - mapObject, - showBackButton, - !mMapObject.isMyPosition()); + updateButtons(mapObject, showBackButton, !mMapObject.isMyPosition()); } else close(); diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageStateListener.java b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageStateListener.java index d24be5e0d..e4de98695 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageStateListener.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageStateListener.java @@ -1,5 +1,4 @@ package app.organicmaps.widget.placepage; public interface PlacePageStateListener -{ -} +{} diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageUtils.java b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageUtils.java index 0073d6275..ff3b05d6e 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageUtils.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageUtils.java @@ -6,14 +6,12 @@ import android.os.Build; import android.view.Menu; import android.view.View; import android.widget.PopupMenu; - import androidx.annotation.NonNull; -import app.organicmaps.Framework; +import app.organicmaps.MwmApplication; import app.organicmaps.R; +import app.organicmaps.sdk.Framework; import app.organicmaps.util.Utils; -import app.organicmaps.display.DisplayManager; import com.google.android.material.bottomsheet.BottomSheetBehavior; - import java.util.List; public class PlacePageUtils @@ -21,8 +19,9 @@ public class PlacePageUtils static void updateMapViewport(@NonNull View parent, int placePageDistanceToTop, int viewportMinHeight) { parent.post(() -> { - // Because of the post(), this lambda is called after the car.SurfaceRenderer.onStableAreaChanged() and breaks the visibleRect configuration - if (DisplayManager.from(parent.getContext()).isCarDisplayUsed()) + // Because of the post(), this lambda is called after the car.SurfaceRenderer.onStableAreaChanged() and breaks the + // visibleRect configuration + if (MwmApplication.from(parent.getContext()).getDisplayManager().isCarDisplayUsed()) return; final int screenWidth = parent.getWidth(); if (placePageDistanceToTop >= viewportMinHeight) @@ -83,8 +82,7 @@ public class PlacePageUtils // Starting from API 33, the automatic system control that shows copied text is displayed. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU || keyguardManager.isDeviceLocked()) { - Utils.showSnackbarAbove(snackbarContainer, frame, - context.getString(R.string.copied_to_clipboard, text)); + Utils.showSnackbarAbove(snackbarContainer, frame, context.getString(R.string.copied_to_clipboard, text)); } } @@ -95,8 +93,7 @@ public class PlacePageUtils final String copyText = context.getResources().getString(android.R.string.copy); // A menu item can be clicked after PlacePageButtons is removed from the Views hierarchy so // let's find a container for the snackbar outside of PlacePageButtons and in advance. - final View snackbarTarget = (View) - popupAnchor.getRootView().findViewById(R.id.pp_buttons_layout).getParent(); + final View snackbarTarget = (View) popupAnchor.getRootView().findViewById(R.id.pp_buttons_layout).getParent(); for (int i = 0; i < items.size(); i++) menu.add(Menu.NONE, i, i, String.format("%s %s", copyText, items.get(i))); diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageView.java b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageView.java index 14e8db52a..5f9ebf711 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageView.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageView.java @@ -1,5 +1,10 @@ package app.organicmaps.widget.placepage; +import static android.view.View.GONE; +import static android.view.View.VISIBLE; +import static app.organicmaps.sdk.util.Utils.getLocalizedFeatureType; +import static app.organicmaps.sdk.util.Utils.getTagValueLocalized; + import android.content.Context; import android.location.Location; import android.net.Uri; @@ -13,7 +18,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.RelativeLayout; - import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -22,43 +26,39 @@ import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; -import app.organicmaps.Framework; import app.organicmaps.MwmActivity; import app.organicmaps.MwmApplication; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.DistanceAndAzimut; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.bookmarks.data.Metadata; -import app.organicmaps.downloader.CountryItem; import app.organicmaps.downloader.DownloaderStatusIcon; -import app.organicmaps.downloader.MapManager; -import app.organicmaps.editor.Editor; -import app.organicmaps.editor.OhState; -import app.organicmaps.editor.OpeningHours; -import app.organicmaps.editor.data.HoursMinutes; -import app.organicmaps.editor.data.Timetable; -import app.organicmaps.location.LocationHelper; -import app.organicmaps.location.LocationListener; -import app.organicmaps.location.SensorHelper; -import app.organicmaps.location.SensorListener; +import app.organicmaps.editor.OhState; //pastk: move? import app.organicmaps.routing.RoutingController; -import app.organicmaps.util.DateUtils; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.bookmarks.data.DistanceAndAzimut; +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.bookmarks.data.Metadata; +import app.organicmaps.sdk.downloader.CountryItem; +import app.organicmaps.sdk.downloader.MapManager; +import app.organicmaps.sdk.editor.Editor; +import app.organicmaps.sdk.editor.OpeningHours; //pastk: a part of Editor? +import app.organicmaps.sdk.editor.data.HoursMinutes; +import app.organicmaps.sdk.editor.data.Timetable; +import app.organicmaps.sdk.location.LocationListener; +import app.organicmaps.sdk.location.SensorListener; +import app.organicmaps.sdk.util.DateUtils; +import app.organicmaps.sdk.util.StringUtils; +import app.organicmaps.sdk.util.UiUtils; +import app.organicmaps.sdk.util.concurrency.UiThread; import app.organicmaps.util.SharingUtils; -import app.organicmaps.util.StringUtils; -import app.organicmaps.util.UiUtils; import app.organicmaps.util.Utils; -import app.organicmaps.util.concurrency.UiThread; import app.organicmaps.widget.ArrowView; import app.organicmaps.widget.placepage.sections.PlacePageBookmarkFragment; import app.organicmaps.widget.placepage.sections.PlacePageLinksFragment; import app.organicmaps.widget.placepage.sections.PlacePageOpeningHoursFragment; import app.organicmaps.widget.placepage.sections.PlacePagePhoneFragment; import app.organicmaps.widget.placepage.sections.PlacePageWikipediaFragment; - import com.google.android.material.appbar.MaterialToolbar; import com.google.android.material.button.MaterialButton; import com.google.android.material.textview.MaterialTextView; - import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; @@ -66,14 +66,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import static android.view.View.GONE; -import static android.view.View.VISIBLE; - -public class PlacePageView extends Fragment implements View.OnClickListener, - View.OnLongClickListener, - LocationListener, - SensorListener, - Observer +public class PlacePageView extends Fragment + implements View.OnClickListener, View.OnLongClickListener, LocationListener, SensorListener, Observer { private static final String PREF_COORDINATES_FORMAT = "coordinates_format"; @@ -84,12 +78,8 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private static final String LINKS_FRAGMENT_TAG = "LINKS_FRAGMENT_TAG"; private static final List visibleCoordsFormat = - Arrays.asList(CoordinatesFormat.LatLonDMS, - CoordinatesFormat.LatLonDecimal, - CoordinatesFormat.OLCFull, - CoordinatesFormat.UTM, - CoordinatesFormat.MGRS, - CoordinatesFormat.OSMLink); + Arrays.asList(CoordinatesFormat.LatLonDMS, CoordinatesFormat.LatLonDecimal, CoordinatesFormat.OLCFull, + CoordinatesFormat.UTM, CoordinatesFormat.MGRS, CoordinatesFormat.OSMLink); private View mFrame; private Context mContext; @@ -142,8 +132,7 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private int mStorageCallbackSlot; @Nullable private CountryItem mCurrentCountry; - private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback() - { + private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback() { @Override public void onStatusChanged(List data) { @@ -170,7 +159,8 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private PlacePageViewModel mViewModel; private MapObject mMapObject; - private static void refreshMetadataOrHide(@Nullable String metadata, @NonNull View metaLayout, @NonNull MaterialTextView metaTv) + private static void refreshMetadataOrHide(@Nullable String metadata, @NonNull View metaLayout, + @NonNull MaterialTextView metaTv) { if (!TextUtils.isEmpty(metadata)) { @@ -183,17 +173,15 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private static boolean isInvalidDownloaderStatus(int status) { - return (status != CountryItem.STATUS_DOWNLOADABLE && - status != CountryItem.STATUS_ENQUEUED && - status != CountryItem.STATUS_FAILED && - status != CountryItem.STATUS_PARTLY && - status != CountryItem.STATUS_PROGRESS && - status != CountryItem.STATUS_APPLYING); + return (status != CountryItem.STATUS_DOWNLOADABLE && status != CountryItem.STATUS_ENQUEUED + && status != CountryItem.STATUS_FAILED && status != CountryItem.STATUS_PARTLY + && status != CountryItem.STATUS_PROGRESS && status != CountryItem.STATUS_APPLYING); } @Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { mViewModel = new ViewModelProvider(requireActivity()).get(PlacePageViewModel.class); return inflater.inflate(R.layout.place_page, container, false); @@ -203,9 +191,9 @@ public class PlacePageView extends Fragment implements View.OnClickListener, public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - mCoordsFormat = CoordinatesFormat.fromId( - MwmApplication.prefs(requireContext()).getInt( - PREF_COORDINATES_FORMAT, CoordinatesFormat.LatLonDecimal.getId())); + mCoordsFormat = + CoordinatesFormat.fromId(MwmApplication.prefs(requireContext()) + .getInt(PREF_COORDINATES_FORMAT, CoordinatesFormat.LatLonDecimal.getId())); Fragment parentFragment = getParentFragment(); mPlacePageViewListener = (PlacePageViewListener) parentFragment; @@ -312,8 +300,8 @@ public class PlacePageView extends Fragment implements View.OnClickListener, { super.onStart(); mViewModel.getMapObject().observe(requireActivity(), this); - LocationHelper.from(requireContext()).addListener(this); - SensorHelper.from(requireContext()).addListener(this); + MwmApplication.from(requireContext()).getLocationHelper().addListener(this); + MwmApplication.from(requireContext()).getSensorHelper().addListener(this); } @Override @@ -321,8 +309,8 @@ public class PlacePageView extends Fragment implements View.OnClickListener, { super.onStop(); mViewModel.getMapObject().removeObserver(this); - LocationHelper.from(requireContext()).removeListener(this); - SensorHelper.from(requireContext()).removeListener(this); + MwmApplication.from(requireContext()).getLocationHelper().removeListener(this); + MwmApplication.from(requireContext()).getSensorHelper().removeListener(this); UiThread.cancelDelayedTasks(updateOpenState); detachCountry(); } @@ -340,30 +328,25 @@ public class PlacePageView extends Fragment implements View.OnClickListener, { refreshPreview(); refreshDetails(); - final Location loc = LocationHelper.from(requireContext()).getSavedLocation(); + final Location loc = MwmApplication.from(requireContext()).getLocationHelper().getSavedLocation(); if (mMapObject.isMyPosition()) refreshMyPosition(loc); else refreshDistanceToObject(loc); } - private void updateViewFragment(Class controllerClass, String fragmentTag, @IdRes int containerId, boolean enabled) + private void updateViewFragment(Class controllerClass, String fragmentTag, + @IdRes int containerId, boolean enabled) { final FragmentManager fm = getChildFragmentManager(); final Fragment fragment = fm.findFragmentByTag(fragmentTag); if (enabled && fragment == null) { - fm.beginTransaction() - .setReorderingAllowed(true) - .add(containerId, controllerClass, null, fragmentTag) - .commit(); + fm.beginTransaction().setReorderingAllowed(true).add(containerId, controllerClass, null, fragmentTag).commit(); } else if (!enabled && fragment != null) { - fm.beginTransaction() - .setReorderingAllowed(true) - .remove(fragment) - .commit(); + fm.beginTransaction().setReorderingAllowed(true).remove(fragment).commit(); } } @@ -376,18 +359,19 @@ public class PlacePageView extends Fragment implements View.OnClickListener, { final String ohStr = mMapObject.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS); updateViewFragment(PlacePageOpeningHoursFragment.class, OPENING_HOURS_FRAGMENT_TAG, - R.id.place_page_opening_hours_fragment, !TextUtils.isEmpty(ohStr)); + R.id.place_page_opening_hours_fragment, !TextUtils.isEmpty(ohStr)); } private void updatePhoneView() { - updateViewFragment(PlacePagePhoneFragment.class, PHONE_FRAGMENT_TAG, R.id.place_page_phone_fragment, mMapObject.hasPhoneNumber()); + updateViewFragment(PlacePagePhoneFragment.class, PHONE_FRAGMENT_TAG, R.id.place_page_phone_fragment, + mMapObject.hasPhoneNumber()); } private void updateBookmarkView() { updateViewFragment(PlacePageBookmarkFragment.class, BOOKMARK_FRAGMENT_TAG, R.id.place_page_bookmark_fragment, - mMapObject.isBookmark()); + mMapObject.isBookmark()); } private boolean hasWikipediaEntry() @@ -399,7 +383,8 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private void updateWikipediaView() { - updateViewFragment(PlacePageWikipediaFragment.class, WIKIPEDIA_FRAGMENT_TAG, R.id.place_page_wikipedia_fragment, hasWikipediaEntry()); + updateViewFragment(PlacePageWikipediaFragment.class, WIKIPEDIA_FRAGMENT_TAG, R.id.place_page_wikipedia_fragment, + hasWikipediaEntry()); } private void setTextAndColorizeSubtitle() @@ -413,8 +398,8 @@ public class PlacePageView extends Fragment implements View.OnClickListener, int end = text.lastIndexOf("★") + 1; if (start > -1) { - sb.setSpan(new ForegroundColorSpan(ContextCompat.getColor(requireContext(), R.color.base_yellow)), - start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); + sb.setSpan(new ForegroundColorSpan(ContextCompat.getColor(requireContext(), R.color.base_yellow)), start, end, + Spanned.SPAN_INCLUSIVE_EXCLUSIVE); } mTvSubtitle.setText(sb); } @@ -437,10 +422,12 @@ public class PlacePageView extends Fragment implements View.OnClickListener, refreshLatLon(); final String operator = mMapObject.getMetadata(Metadata.MetadataType.FMD_OPERATOR); - refreshMetadataOrHide(!TextUtils.isEmpty(operator) ? getString(R.string.operator, operator) : "", mOperator, mTvOperator); + refreshMetadataOrHide(!TextUtils.isEmpty(operator) ? getString(R.string.operator, operator) : "", mOperator, + mTvOperator); final String network = mMapObject.getMetadata(Metadata.MetadataType.FMD_NETWORK); - refreshMetadataOrHide(!TextUtils.isEmpty(network) ? getString(R.string.network, network) : "", mNetwork, mTvNetwork); + refreshMetadataOrHide(!TextUtils.isEmpty(network) ? getString(R.string.network, network) : "", mNetwork, + mTvNetwork); /// @todo I don't like it when we take all data from mapObject, but for cuisines, we should /// go into JNI Framework and rely on some "active object". @@ -455,19 +442,23 @@ public class PlacePageView extends Fragment implements View.OnClickListener, refreshMetadataOrHide(mMapObject.hasAtm() ? getString(R.string.type_amenity_atm) : "", mAtm, mTvAtm); - final String wheelchair = Utils.getLocalizedFeatureType(getContext(), mMapObject.getMetadata(Metadata.MetadataType.FMD_WHEELCHAIR)); + final String wheelchair = + getLocalizedFeatureType(getContext(), mMapObject.getMetadata(Metadata.MetadataType.FMD_WHEELCHAIR)); refreshMetadataOrHide(wheelchair, mWheelchair, mTvWheelchair); final String driveThrough = mMapObject.getMetadata(Metadata.MetadataType.FMD_DRIVE_THROUGH); - refreshMetadataOrHide(driveThrough.equals("yes") ? getString(R.string.drive_through) : "", mDriveThrough, mTvDriveThrough); + refreshMetadataOrHide(driveThrough.equals("yes") ? getString(R.string.drive_through) : "", mDriveThrough, + mTvDriveThrough); final String selfService = mMapObject.getMetadata(Metadata.MetadataType.FMD_SELF_SERVICE); - refreshMetadataOrHide(Utils.getTagValueLocalized(getContext(), "self_service", selfService), mSelfService, mTvSelfService); + refreshMetadataOrHide(getTagValueLocalized(getContext(), "self_service", selfService), mSelfService, + mTvSelfService); final String outdoorSeating = mMapObject.getMetadata(Metadata.MetadataType.FMD_OUTDOOR_SEATING); - refreshMetadataOrHide(outdoorSeating.equals("yes") ? getString(R.string.outdoor_seating) : "", mOutdoorSeating, mTvOutdoorSeating); + refreshMetadataOrHide(outdoorSeating.equals("yes") ? getString(R.string.outdoor_seating) : "", mOutdoorSeating, + mTvOutdoorSeating); -// showTaxiOffer(mapObject); + // showTaxiOffer(mapObject); if (RoutingController.get().isNavigating() || RoutingController.get().isPlanning()) { @@ -484,13 +475,17 @@ public class PlacePageView extends Fragment implements View.OnClickListener, MaterialTextView mTvEditPlace = mEditPlace.findViewById(R.id.tv__editor); MaterialTextView mTvAddBusiness = mAddPlace.findViewById(R.id.tv__editor); MaterialTextView mTvAddPlace = mAddPlace.findViewById(R.id.tv__editor); - final int editPlaceButtonColor = Editor.nativeShouldEnableEditPlace() ? ContextCompat.getColor(getContext(), UiUtils.getStyledResourceId(getContext(), androidx.appcompat.R.attr.colorAccent)) : getResources().getColor(R.color.button_accent_text_disabled); + final int editPlaceButtonColor = + Editor.nativeShouldEnableEditPlace() + ? ContextCompat.getColor(getContext(), + UiUtils.getStyledResourceId(getContext(), androidx.appcompat.R.attr.colorAccent)) + : getResources().getColor(R.color.button_accent_text_disabled); mTvEditPlace.setTextColor(editPlaceButtonColor); mTvAddBusiness.setTextColor(editPlaceButtonColor); mTvAddPlace.setTextColor(editPlaceButtonColor); - UiUtils.showIf(UiUtils.isVisible(mEditPlace) - || UiUtils.isVisible(mAddOrganisation) - || UiUtils.isVisible(mAddPlace), mEditTopSpace); + UiUtils.showIf( + UiUtils.isVisible(mEditPlace) || UiUtils.isVisible(mAddOrganisation) || UiUtils.isVisible(mAddPlace), + mEditTopSpace); } updateLinksView(); updateOpeningHoursView(); @@ -576,11 +571,16 @@ public class PlacePageView extends Fragment implements View.OnClickListener, // Ignore unknown rule state if (poiState.state == OhState.State.Unknown) - { UiUtils.hide(mTvOpenState); return; } + { + UiUtils.hide(mTvOpenState); + return; + } // Get colours - final ForegroundColorSpan colorGreen = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_green)); - final ForegroundColorSpan colorYellow = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_yellow)); + final ForegroundColorSpan colorGreen = + new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_green)); + final ForegroundColorSpan colorYellow = + new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_yellow)); final ForegroundColorSpan colorRed = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.base_red)); // Get next state info @@ -594,20 +594,21 @@ public class PlacePageView extends Fragment implements View.OnClickListener, final String minsToChangeStr = minsToNextState + " " + getString(R.string.minute); final String nextChangeFormatted = getString(isOpen ? R.string.closes_in : R.string.opens_in, minsToChangeStr); final ForegroundColorSpan nextChangeColor = isOpen ? colorYellow : colorRed; - //TODO: We should check closed/open time for specific feature's timezone. + // TODO: We should check closed/open time for specific feature's timezone. ZonedDateTime time = ZonedDateTime.ofInstant(Instant.ofEpochSecond(nextStateTime), ZoneId.systemDefault()); - String localizedTime = new HoursMinutes(time.getHour(), time.getMinute(), DateUtils.is24HourFormat(context)).toString(); + String localizedTime = + new HoursMinutes(time.getHour(), time.getMinute(), DateUtils.is24HourFormat(context)).toString(); openStateString.append(nextChangeFormatted, nextChangeColor, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) - .append(" • ") // Add spacer - .append(getString(R.string.at, localizedTime)); + .append(" • ") // Add spacer + .append(getString(R.string.at, localizedTime)); } else if (isOpen) openStateString.append(getString(R.string.open_now), colorGreen, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - //TODO: Add "Closes at 18:00" etc + // TODO: Add "Closes at 18:00" etc else // Closed openStateString.append(getString(R.string.closed_now), colorRed, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - //TODO: Add "Opens at 18:00" etc + // TODO: Add "Opens at 18:00" etc UiUtils.setTextAndHideIfEmpty(mTvOpenState, openStateString); return; @@ -618,7 +619,7 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private void addOrganisation() { - ((MwmActivity) requireActivity()).showPositionChooserForEditor(true, false); + ((MwmActivity) requireActivity()).showPositionChooserForEditor(true, true); } private void addPlace() @@ -646,16 +647,13 @@ public class PlacePageView extends Fragment implements View.OnClickListener, { final int formatIndex = visibleCoordsFormat.indexOf(mCoordsFormat); mCoordsFormat = visibleCoordsFormat.get((formatIndex + 1) % visibleCoordsFormat.size()); - MwmApplication.prefs(context) - .edit() - .putInt(PREF_COORDINATES_FORMAT, mCoordsFormat.getId()) - .apply(); + MwmApplication.prefs(context).edit().putInt(PREF_COORDINATES_FORMAT, mCoordsFormat.getId()).apply(); refreshLatLon(); } else if (id == R.id.ll__place_open_in) { - final String uri = Framework.nativeGetGeoUri(mMapObject.getLat(), mMapObject.getLon(), - mMapObject.getScale(), mMapObject.getName()); + final String uri = Framework.nativeGetGeoUri(mMapObject.getLat(), mMapObject.getLon(), mMapObject.getScale(), + mMapObject.getName()); Utils.openUri(requireContext(), Uri.parse(uri), R.string.uri_open_location_failed); } else if (id == R.id.direction_frame) @@ -665,8 +663,8 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private void showBigDirection() { final FragmentManager fragmentManager = requireActivity().getSupportFragmentManager(); - final DirectionFragment fragment = (DirectionFragment) fragmentManager.getFragmentFactory() - .instantiate(requireContext().getClassLoader(), DirectionFragment.class.getName()); + final DirectionFragment fragment = (DirectionFragment) fragmentManager.getFragmentFactory().instantiate( + requireContext().getClassLoader(), DirectionFragment.class.getName()); fragment.setMapObject(mMapObject); fragment.show(fragmentManager, null); } @@ -695,8 +693,8 @@ public class PlacePageView extends Fragment implements View.OnClickListener, } else if (id == R.id.ll__place_open_in) { - final String uri = Framework.nativeGetGeoUri(mMapObject.getLat(), mMapObject.getLon(), - mMapObject.getScale(), mMapObject.getName()); + final String uri = Framework.nativeGetGeoUri(mMapObject.getLat(), mMapObject.getLon(), mMapObject.getScale(), + mMapObject.getName()); PlacePageUtils.copyToClipboard(requireContext(), mFrame, uri); } else if (id == R.id.ll__place_operator) @@ -738,8 +736,8 @@ public class PlacePageView extends Fragment implements View.OnClickListener, StringBuilder sb = new StringBuilder(StringUtils.getFileSizeString(requireContext(), country.totalSize)); if (country.isExpandable()) - sb.append(StringUtils.formatUsingUsLocale(" • %s: %d", requireContext().getString(R.string.downloader_status_maps), - country.totalChildCount)); + sb.append(StringUtils.formatUsingUsLocale( + " • %s: %d", requireContext().getString(R.string.downloader_status_maps), country.totalChildCount)); mDownloaderInfo.setText(sb.toString()); } @@ -763,8 +761,9 @@ public class PlacePageView extends Fragment implements View.OnClickListener, if (mStorageCallbackSlot == 0) mStorageCallbackSlot = MapManager.nativeSubscribe(mStorageCallback); - mDownloaderIcon.setOnIconClickListener((v) -> MapManager.warn3gAndDownload(requireActivity(), mCurrentCountry.id, null)) - .setOnCancelClickListener((v) -> MapManager.nativeCancel(mCurrentCountry.id)); + mDownloaderIcon + .setOnIconClickListener((v) -> MapManager.warn3gAndDownload(requireActivity(), mCurrentCountry.id, null)) + .setOnCancelClickListener((v) -> MapManager.nativeCancel(mCurrentCountry.id)); mDownloaderIcon.show(true); UiUtils.show(mDownloaderInfo); updateDownloader(mCurrentCountry); @@ -778,8 +777,7 @@ public class PlacePageView extends Fragment implements View.OnClickListener, MapManager.nativeUnsubscribe(mStorageCallbackSlot); mStorageCallbackSlot = 0; mCurrentCountry = null; - mDownloaderIcon.setOnIconClickListener(null) - .setOnCancelClickListener(null); + mDownloaderIcon.setOnIconClickListener(null).setOnCancelClickListener(null); mDownloaderIcon.show(false); UiUtils.hide(mDownloaderInfo); } @@ -821,19 +819,18 @@ public class PlacePageView extends Fragment implements View.OnClickListener, if (mMapObject == null || mMapObject.isMyPosition()) return; - final Location location = LocationHelper.from(requireContext()).getSavedLocation(); + final Location location = MwmApplication.from(requireContext()).getLocationHelper().getSavedLocation(); if (location == null) { UiUtils.hide(mAvDirection); return; } - final double azimuth = Framework.nativeGetDistanceAndAzimuthFromLatLon(mMapObject.getLat(), - mMapObject.getLon(), - location.getLatitude(), - location.getLongitude(), - north) - .getAzimuth(); + final double azimuth = + Framework + .nativeGetDistanceAndAzimuthFromLatLon(mMapObject.getLat(), mMapObject.getLon(), location.getLatitude(), + location.getLongitude(), north) + .getAzimuth(); UiUtils.showIf(azimuth >= 0, mAvDirection); if (azimuth >= 0) { diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageViewModel.java b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageViewModel.java index fa8ed2f3d..57ca04eb3 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageViewModel.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/PlacePageViewModel.java @@ -3,8 +3,7 @@ package app.organicmaps.widget.placepage; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; -import app.organicmaps.bookmarks.data.MapObject; - +import app.organicmaps.sdk.bookmarks.data.MapObject; import java.util.List; public class PlacePageViewModel extends ViewModel diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlaceOpeningHoursAdapter.java b/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlaceOpeningHoursAdapter.java index f4df69956..b1b5297f9 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlaceOpeningHoursAdapter.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlaceOpeningHoursAdapter.java @@ -1,27 +1,23 @@ package app.organicmaps.widget.placepage.sections; +import static app.organicmaps.editor.data.TimeFormatUtils.formatNonBusinessTime; +import static app.organicmaps.editor.data.TimeFormatUtils.formatWeekdaysRange; + import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import app.organicmaps.R; -import app.organicmaps.editor.data.Timespan; -import app.organicmaps.editor.data.Timetable; -import app.organicmaps.util.UiUtils; - +import app.organicmaps.sdk.editor.data.Timespan; +import app.organicmaps.sdk.editor.data.Timetable; +import app.organicmaps.sdk.util.UiUtils; +import com.google.android.material.textview.MaterialTextView; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collections; import java.util.List; - -import static app.organicmaps.editor.data.TimeFormatUtils.formatNonBusinessTime; -import static app.organicmaps.editor.data.TimeFormatUtils.formatWeekdaysRange; - -import com.google.android.material.textview.MaterialTextView; - public class PlaceOpeningHoursAdapter extends RecyclerView.Adapter { private List mWeekSchedule = Collections.emptyList(); @@ -76,18 +72,17 @@ public class PlaceOpeningHoursAdapter extends RecyclerView.Adapter buildWeekByFirstDay(int firstDayOfWeek) { if (firstDayOfWeek < 1 || firstDayOfWeek > 7) - throw new IllegalArgumentException("First day of week "+firstDayOfWeek+" is out of range [1..7]"); + throw new IllegalArgumentException("First day of week " + firstDayOfWeek + " is out of range [1..7]"); - final List list = Arrays.asList(Calendar.SUNDAY, Calendar.MONDAY, Calendar.TUESDAY, - Calendar.WEDNESDAY, Calendar.THURSDAY, Calendar.FRIDAY, - Calendar.SATURDAY); + final List list = Arrays.asList(Calendar.SUNDAY, Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, + Calendar.THURSDAY, Calendar.FRIDAY, Calendar.SATURDAY); Collections.rotate(list, 1 - firstDayOfWeek); return list; } public static Timetable findScheduleForWeekDay(Timetable[] tables, int weekDay) { - for(Timetable tt : tables) + for (Timetable tt : tables) if (tt.containsWeekday(weekDay)) return tt; @@ -98,8 +93,8 @@ public class PlaceOpeningHoursAdapter extends RecyclerView.Adapter, EditBookmarkFragment.EditBookmarkListener { @@ -49,7 +45,8 @@ public class PlacePageBookmarkFragment extends Fragment implements View.OnClickL @Nullable @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { mViewModel = new ViewModelProvider(requireActivity()).get(PlacePageViewModel.class); return inflater.inflate(R.layout.place_page_bookmark_fragment, container, false); @@ -126,11 +123,8 @@ public class PlacePageBookmarkFragment extends Fragment implements View.OnClickL public void onClick(View v) { final FragmentActivity activity = requireActivity(); - EditBookmarkFragment.editBookmark(currentBookmark.getCategoryId(), - currentBookmark.getBookmarkId(), - activity, - getChildFragmentManager(), - PlacePageBookmarkFragment.this); + EditBookmarkFragment.editBookmark(currentBookmark.getCategoryId(), currentBookmark.getBookmarkId(), activity, + getChildFragmentManager(), PlacePageBookmarkFragment.this); } @Override diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePageLinksFragment.java b/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePageLinksFragment.java index 796e0f3ee..9a3c15aaa 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePageLinksFragment.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePageLinksFragment.java @@ -1,33 +1,29 @@ package app.organicmaps.widget.placepage.sections; +import static android.view.View.GONE; +import static android.view.View.VISIBLE; + import android.os.Bundle; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; - -import app.organicmaps.Framework; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.bookmarks.data.Metadata; +import app.organicmaps.sdk.Framework; +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.bookmarks.data.Metadata; import app.organicmaps.util.Utils; import app.organicmaps.widget.placepage.PlacePageUtils; import app.organicmaps.widget.placepage.PlacePageViewModel; - +import com.google.android.material.textview.MaterialTextView; import java.util.ArrayList; import java.util.List; -import static android.view.View.GONE; -import static android.view.View.VISIBLE; - -import com.google.android.material.textview.MaterialTextView; - public class PlacePageLinksFragment extends Fragment implements Observer { private static final String TAG = PlacePageLinksFragment.class.getSimpleName(); @@ -80,12 +76,10 @@ public class PlacePageLinksFragment extends Fragment implements Observer - mMapObject.getWebsiteUrl(false /* strip */, Metadata.MetadataType.FMD_WEBSITE); - case FMD_WEBSITE_MENU -> - mMapObject.getWebsiteUrl(false /* strip */, Metadata.MetadataType.FMD_WEBSITE_MENU); - case FMD_CONTACT_FACEBOOK, FMD_CONTACT_INSTAGRAM, FMD_CONTACT_TWITTER, - FMD_CONTACT_FEDIVERSE, FMD_CONTACT_BLUESKY, FMD_CONTACT_VK, FMD_CONTACT_LINE, FMD_PANORAMAX -> + case FMD_WEBSITE -> mMapObject.getWebsiteUrl(false /* strip */, Metadata.MetadataType.FMD_WEBSITE); + case FMD_WEBSITE_MENU -> mMapObject.getWebsiteUrl(false /* strip */, Metadata.MetadataType.FMD_WEBSITE_MENU); + case FMD_CONTACT_FACEBOOK, FMD_CONTACT_INSTAGRAM, FMD_CONTACT_TWITTER, FMD_CONTACT_FEDIVERSE, FMD_CONTACT_BLUESKY, + FMD_CONTACT_VK, FMD_CONTACT_LINE, FMD_PANORAMAX -> { if (TextUtils.isEmpty(mMapObject.getMetadata(type))) yield ""; @@ -97,7 +91,8 @@ public class PlacePageLinksFragment extends Fragment implements Observer items = new ArrayList<>(); items.add(url); - final String title = switch (type){ + final String title = switch (type) + { case FMD_WEBSITE -> mMapObject.getWebsiteUrl(false /* strip */, Metadata.MetadataType.FMD_WEBSITE); case FMD_WEBSITE_MENU -> mMapObject.getWebsiteUrl(false /* strip */, Metadata.MetadataType.FMD_WEBSITE_MENU); case FMD_PANORAMAX -> null; // Don't add raw ID to list, as it's useless for users. default -> mMapObject.getMetadata(type); }; - // Add user names for social media if available - if (!TextUtils.isEmpty(title) && !title.equals(url) && !title.contains("/")) - items.add(title); + // Add user names for social media if available + if (!TextUtils.isEmpty(title) && !title.equals(url) && !title.contains("/")) items.add(title); if (items.size() == 1) PlacePageUtils.copyToClipboard(requireContext(), mFrame, items.get(0)); @@ -208,11 +203,14 @@ public class PlacePageLinksFragment extends Fragment implements Observer { - PlacePageUtils.copyToClipboard(requireContext(), mFrame, TimeFormatUtils.formatTimetables(getResources(), ohStr, timetables)); + PlacePageUtils.copyToClipboard(requireContext(), mFrame, + TimeFormatUtils.formatTimetables(getResources(), ohStr, timetables)); return true; }); @@ -172,7 +171,8 @@ public class PlacePageOpeningHoursFragment extends Fragment implements Observer< // Show that place is closed today. if (!containsCurrentWeekday) { - refreshTodayOpeningHours(resources.getString(R.string.day_off_today), ContextCompat.getColor(requireContext(), R.color.base_red)); + refreshTodayOpeningHours(resources.getString(R.string.day_off_today), + ContextCompat.getColor(requireContext(), R.color.base_red)); UiUtils.hide(mTodayNonBusinessTime); } } diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePagePhoneFragment.java b/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePagePhoneFragment.java index fe4dacc56..c2d7e4b26 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePagePhoneFragment.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePagePhoneFragment.java @@ -4,7 +4,6 @@ import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; @@ -12,8 +11,8 @@ import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.RecyclerView; import app.organicmaps.R; -import app.organicmaps.bookmarks.data.MapObject; -import app.organicmaps.bookmarks.data.Metadata; +import app.organicmaps.sdk.bookmarks.data.MapObject; +import app.organicmaps.sdk.bookmarks.data.Metadata; import app.organicmaps.widget.placepage.PlacePageViewModel; public class PlacePagePhoneFragment extends Fragment implements Observer @@ -24,7 +23,8 @@ public class PlacePagePhoneFragment extends Fragment implements Observer { @@ -41,7 +38,8 @@ public class PlacePageWikipediaFragment extends Fragment implements Observer mDescriptionMaxLength) { description = (Spanned) new SpannableStringBuilder(description) - .insert(mDescriptionMaxLength - 3, "...") - .subSequence(0, mDescriptionMaxLength); + .insert(mDescriptionMaxLength - 3, "...") + .subSequence(0, mDescriptionMaxLength); } return description; @@ -89,7 +87,6 @@ public class PlacePageWikipediaFragment extends Fragment implements Observer { - PlacePageUtils.copyToClipboard(requireContext(), mFrame, descriptionString); - return true; + PlacePageUtils.copyToClipboard(requireContext(), mFrame, descriptionString); + return true; }); } diff --git a/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePhoneAdapter.java b/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePhoneAdapter.java index 36c4ed2ea..12e8933f5 100644 --- a/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePhoneAdapter.java +++ b/android/app/src/main/java/app/organicmaps/widget/placepage/sections/PlacePhoneAdapter.java @@ -7,25 +7,21 @@ import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; - import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.textview.MaterialTextView; - import app.organicmaps.R; import app.organicmaps.util.Utils; - +import com.google.android.material.textview.MaterialTextView; import java.util.ArrayList; public class PlacePhoneAdapter extends RecyclerView.Adapter { - private final ArrayList mPhoneData = new ArrayList<>(); public PlacePhoneAdapter() {} - public void refreshPhones(String phones) { + public void refreshPhones(String phones) + { if (TextUtils.isEmpty(phones)) return; @@ -45,8 +41,8 @@ public class PlacePhoneAdapter extends RecyclerView.Adapter @@ -31,221 +28,259 @@ import javax.annotation.concurrent.NotThreadSafe; * * @param The type of observers that this list should hold. */ -@NotThreadSafe -public class ObserverList implements Iterable { - /** Extended iterator interface that provides rewind functionality. */ - public interface RewindableIterator extends Iterator { - /** - * Rewind the iterator back to the beginning. - * - * If we need to iterate multiple times, we can avoid iterator object reallocation by using - * this method. - */ - public void rewind(); - } - - public final List mObservers = new ArrayList(); - private int mIterationDepth; - private int mCount; - private boolean mNeedsCompact; - +public class ObserverList implements Iterable +{ + /** Extended iterator interface that provides rewind functionality. */ + public interface RewindableIterator extends Iterator + { /** - * Add an observer to the list. - *

- * An observer should not be added to the same list more than once. If an iteration is already - * in progress, this observer will be not be visible during that iteration. + * Rewind the iterator back to the beginning. * - * @return true if the observer list changed as a result of the call. + * If we need to iterate multiple times, we can avoid iterator object reallocation by using + * this method. */ - public boolean addObserver(@Nullable E obs) { - // Avoid adding null elements to the list as they may be removed on a compaction. - if (obs == null || mObservers.contains(obs)) { - return false; - } + public void rewind(); + } - // Structurally modifying the underlying list here. This means we - // cannot use the underlying list's iterator to iterate over the list. - boolean result = mObservers.add(obs); - assert result; + public final List mObservers = new ArrayList(); + private int mIterationDepth; + private int mCount; + private boolean mNeedsCompact; - ++mCount; - return true; + /** + * Add an observer to the list. + *

+ * An observer should not be added to the same list more than once. If an iteration is already + * in progress, this observer will be not be visible during that iteration. + * + * @return true if the observer list changed as a result of the call. + */ + public boolean addObserver(@Nullable E obs) + { + // Avoid adding null elements to the list as they may be removed on a compaction. + if (obs == null || mObservers.contains(obs)) + { + return false; } - /** - * Remove an observer from the list if it is in the list. - * - * @return true if an element was removed as a result of this call. - */ - public boolean removeObserver(@Nullable E obs) { - if (obs == null) { - return false; - } + // Structurally modifying the underlying list here. This means we + // cannot use the underlying list's iterator to iterate over the list. + boolean result = mObservers.add(obs); + assert result; - int index = mObservers.indexOf(obs); - if (index == -1) { - return false; - } + ++mCount; + return true; + } - if (mIterationDepth == 0) { - // No one is iterating over the list. - mObservers.remove(index); - } else { - mNeedsCompact = true; - mObservers.set(index, null); - } - --mCount; - assert mCount >= 0; - - return true; + /** + * Remove an observer from the list if it is in the list. + * + * @return true if an element was removed as a result of this call. + */ + public boolean removeObserver(@Nullable E obs) + { + if (obs == null) + { + return false; } - public boolean hasObserver(@Nullable E obs) { - if (obs == null) { - return false; - } - - return mObservers.contains(obs); + int index = mObservers.indexOf(obs); + if (index == -1) + { + return false; } - public void clear() { - mCount = 0; + if (mIterationDepth == 0) + { + // No one is iterating over the list. + mObservers.remove(index); + } + else + { + mNeedsCompact = true; + mObservers.set(index, null); + } + --mCount; + assert mCount >= 0; - if (mIterationDepth == 0) { - mObservers.clear(); - return; - } + return true; + } - int size = mObservers.size(); - mNeedsCompact |= size != 0; - for (int i = 0; i < size; i++) { - mObservers.set(i, null); - } + public boolean hasObserver(@Nullable E obs) + { + if (obs == null) + { + return false; + } + + return mObservers.contains(obs); + } + + public void clear() + { + mCount = 0; + + if (mIterationDepth == 0) + { + mObservers.clear(); + return; + } + + int size = mObservers.size(); + mNeedsCompact |= size != 0; + for (int i = 0; i < size; i++) + { + mObservers.set(i, null); + } + } + + @NonNull + @Override + public Iterator iterator() + { + return new ObserverListIterator(); + } + + /** + * It's the same as {@link ObserverList#iterator()} but the return type is + * {@link RewindableIterator}. Use this iterator type if you need to use + * {@link RewindableIterator#rewind()}. + */ + public RewindableIterator rewindableIterator() + { + return new ObserverListIterator(); + } + + /** + * Returns the number of observers currently registered in the ObserverList. + * This is equivalent to the number of non-empty spaces in |mObservers|. + */ + public int size() + { + return mCount; + } + + /** Returns true if the ObserverList contains no observers. */ + public boolean isEmpty() + { + return mCount == 0; + } + + /** + * Compact the underlying list be removing null elements. + *

+ * Should only be called when mIterationDepth is zero. + */ + private void compact() + { + assert mIterationDepth == 0; + for (int i = mObservers.size() - 1; i >= 0; i--) + { + if (mObservers.get(i) == null) + { + mObservers.remove(i); + } + } + } + + private void incrementIterationDepth() + { + mIterationDepth++; + } + + private void decrementIterationDepthAndCompactIfNeeded() + { + mIterationDepth--; + assert mIterationDepth >= 0; + if (mIterationDepth > 0) + return; + if (!mNeedsCompact) + return; + mNeedsCompact = false; + compact(); + } + + /** + * Returns the size of the underlying storage of the ObserverList. + * It will take into account the empty spaces inside |mObservers|. + */ + private int capacity() + { + return mObservers.size(); + } + + private E getObserverAt(int index) + { + return mObservers.get(index); + } + + private class ObserverListIterator implements RewindableIterator + { + private int mListEndMarker; + private int mIndex; + private boolean mIsExhausted; + + private ObserverListIterator() + { + ObserverList.this.incrementIterationDepth(); + mListEndMarker = ObserverList.this.capacity(); } - @NonNull @Override - public Iterator iterator() { - return new ObserverListIterator(); + public void rewind() + { + compactListIfNeeded(); + ObserverList.this.incrementIterationDepth(); + mListEndMarker = ObserverList.this.capacity(); + mIsExhausted = false; + mIndex = 0; } - /** - * It's the same as {@link ObserverList#iterator()} but the return type is - * {@link RewindableIterator}. Use this iterator type if you need to use - * {@link RewindableIterator#rewind()}. - */ - public RewindableIterator rewindableIterator() { - return new ObserverListIterator(); + @Override + public boolean hasNext() + { + int lookupIndex = mIndex; + while (lookupIndex < mListEndMarker && ObserverList.this.getObserverAt(lookupIndex) == null) + { + lookupIndex++; + } + if (lookupIndex < mListEndMarker) + return true; + + // We have reached the end of the list, allow for compaction. + compactListIfNeeded(); + return false; } - /** - * Returns the number of observers currently registered in the ObserverList. - * This is equivalent to the number of non-empty spaces in |mObservers|. - */ - public int size() { - return mCount; + @Override + public E next() + { + // Advance if the current element is null. + while (mIndex < mListEndMarker && ObserverList.this.getObserverAt(mIndex) == null) + { + mIndex++; + } + if (mIndex < mListEndMarker) + return ObserverList.this.getObserverAt(mIndex++); + + // We have reached the end of the list, allow for compaction. + compactListIfNeeded(); + throw new NoSuchElementException(); } - /** Returns true if the ObserverList contains no observers. */ - public boolean isEmpty() { - return mCount == 0; + @Override + public void remove() + { + throw new UnsupportedOperationException(); } - /** - * Compact the underlying list be removing null elements. - *

- * Should only be called when mIterationDepth is zero. - */ - private void compact() { - assert mIterationDepth == 0; - for (int i = mObservers.size() - 1; i >= 0; i--) { - if (mObservers.get(i) == null) { - mObservers.remove(i); - } - } - } - - private void incrementIterationDepth() { - mIterationDepth++; - } - - private void decrementIterationDepthAndCompactIfNeeded() { - mIterationDepth--; - assert mIterationDepth >= 0; - if (mIterationDepth > 0) return; - if (!mNeedsCompact) return; - mNeedsCompact = false; - compact(); - } - - /** - * Returns the size of the underlying storage of the ObserverList. - * It will take into account the empty spaces inside |mObservers|. - */ - private int capacity() { - return mObservers.size(); - } - - private E getObserverAt(int index) { - return mObservers.get(index); - } - - private class ObserverListIterator implements RewindableIterator { - private int mListEndMarker; - private int mIndex; - private boolean mIsExhausted; - - private ObserverListIterator() { - ObserverList.this.incrementIterationDepth(); - mListEndMarker = ObserverList.this.capacity(); - } - - @Override - public void rewind() { - compactListIfNeeded(); - ObserverList.this.incrementIterationDepth(); - mListEndMarker = ObserverList.this.capacity(); - mIsExhausted = false; - mIndex = 0; - } - - @Override - public boolean hasNext() { - int lookupIndex = mIndex; - while (lookupIndex < mListEndMarker - && ObserverList.this.getObserverAt(lookupIndex) == null) { - lookupIndex++; - } - if (lookupIndex < mListEndMarker) return true; - - // We have reached the end of the list, allow for compaction. - compactListIfNeeded(); - return false; - } - - @Override - public E next() { - // Advance if the current element is null. - while (mIndex < mListEndMarker && ObserverList.this.getObserverAt(mIndex) == null) { - mIndex++; - } - if (mIndex < mListEndMarker) return ObserverList.this.getObserverAt(mIndex++); - - // We have reached the end of the list, allow for compaction. - compactListIfNeeded(); - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - private void compactListIfNeeded() { - if (!mIsExhausted) { - mIsExhausted = true; - ObserverList.this.decrementIterationDepthAndCompactIfNeeded(); - } - } + private void compactListIfNeeded() + { + if (!mIsExhausted) + { + mIsExhausted = true; + ObserverList.this.decrementIterationDepthAndCompactIfNeeded(); + } } + } } diff --git a/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_lightrail.webp b/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_lightrail.webp deleted file mode 100644 index 04d68eb77..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_lightrail.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_metro.webp b/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_metro.webp deleted file mode 100644 index e74402e79..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_metro.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_monorail.webp b/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_monorail.webp deleted file mode 100644 index 8fb256828..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_monorail.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_train.webp b/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_train.webp deleted file mode 100644 index 6deb546af..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_20px_route_planning_train.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_downloader_done.webp b/android/app/src/main/res/drawable-hdpi/ic_downloader_done.webp deleted file mode 100644 index ee1b878cf..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_downloader_done.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_downloader_done_night.webp b/android/app/src/main/res/drawable-hdpi/ic_downloader_done_night.webp deleted file mode 100644 index 1689fec81..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_downloader_done_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_downloader_download.webp b/android/app/src/main/res/drawable-hdpi/ic_downloader_download.webp deleted file mode 100644 index 39f6e9902..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_downloader_download.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_downloader_download_night.webp b/android/app/src/main/res/drawable-hdpi/ic_downloader_download_night.webp deleted file mode 100644 index 29aae450e..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_downloader_download_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_downloader_folder.webp b/android/app/src/main/res/drawable-hdpi/ic_downloader_folder.webp deleted file mode 100644 index 02465212b..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_downloader_folder.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_downloader_folder_done.webp b/android/app/src/main/res/drawable-hdpi/ic_downloader_folder_done.webp deleted file mode 100644 index fd57e66d4..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_downloader_folder_done.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_downloader_folder_done_night.webp b/android/app/src/main/res/drawable-hdpi/ic_downloader_folder_done_night.webp deleted file mode 100644 index d322ff2c2..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_downloader_folder_done_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_downloader_folder_night.webp b/android/app/src/main/res/drawable-hdpi/ic_downloader_folder_night.webp deleted file mode 100644 index 3d14cd660..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_downloader_folder_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_downloader_retry.webp b/android/app/src/main/res/drawable-hdpi/ic_downloader_retry.webp deleted file mode 100644 index 199017a3f..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_downloader_retry.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-hdpi/ic_transit.webp b/android/app/src/main/res/drawable-hdpi/ic_transit.webp deleted file mode 100644 index 5a68ef97e..000000000 Binary files a/android/app/src/main/res/drawable-hdpi/ic_transit.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_lightrail.webp b/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_lightrail.webp deleted file mode 100644 index a411d2d0c..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_lightrail.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_metro.webp b/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_metro.webp deleted file mode 100644 index 6fce1dcf5..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_metro.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_monorail.webp b/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_monorail.webp deleted file mode 100644 index ee0389121..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_monorail.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_train.webp b/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_train.webp deleted file mode 100644 index 348d5f8e0..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_20px_route_planning_train.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_downloader_done.webp b/android/app/src/main/res/drawable-mdpi/ic_downloader_done.webp deleted file mode 100644 index 659ab85b3..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_downloader_done.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_downloader_done_night.webp b/android/app/src/main/res/drawable-mdpi/ic_downloader_done_night.webp deleted file mode 100644 index 5d94f9fce..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_downloader_done_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_downloader_download.webp b/android/app/src/main/res/drawable-mdpi/ic_downloader_download.webp deleted file mode 100644 index 15bf1197d..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_downloader_download.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_downloader_download_night.webp b/android/app/src/main/res/drawable-mdpi/ic_downloader_download_night.webp deleted file mode 100644 index 9940e4572..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_downloader_download_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_downloader_folder.webp b/android/app/src/main/res/drawable-mdpi/ic_downloader_folder.webp deleted file mode 100644 index 4202e08dd..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_downloader_folder.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_downloader_folder_done.webp b/android/app/src/main/res/drawable-mdpi/ic_downloader_folder_done.webp deleted file mode 100644 index 856f77945..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_downloader_folder_done.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_downloader_folder_done_night.webp b/android/app/src/main/res/drawable-mdpi/ic_downloader_folder_done_night.webp deleted file mode 100644 index 03aa0d1f6..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_downloader_folder_done_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_downloader_folder_night.webp b/android/app/src/main/res/drawable-mdpi/ic_downloader_folder_night.webp deleted file mode 100644 index 6adc47ec8..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_downloader_folder_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_downloader_retry.webp b/android/app/src/main/res/drawable-mdpi/ic_downloader_retry.webp deleted file mode 100644 index 60f238615..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_downloader_retry.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/ic_transit.webp b/android/app/src/main/res/drawable-mdpi/ic_transit.webp deleted file mode 100644 index dfbdd6c94..000000000 Binary files a/android/app/src/main/res/drawable-mdpi/ic_transit.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_lightrail.webp b/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_lightrail.webp deleted file mode 100644 index cf8e1a220..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_lightrail.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_metro.webp b/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_metro.webp deleted file mode 100644 index df0be2dd4..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_metro.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_monorail.webp b/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_monorail.webp deleted file mode 100644 index 977a7ded5..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_monorail.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_train.webp b/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_train.webp deleted file mode 100644 index 80d002403..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_20px_route_planning_train.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_downloader_done.webp b/android/app/src/main/res/drawable-xhdpi/ic_downloader_done.webp deleted file mode 100644 index b0929f66e..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_downloader_done.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_downloader_done_night.webp b/android/app/src/main/res/drawable-xhdpi/ic_downloader_done_night.webp deleted file mode 100644 index 673e38815..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_downloader_done_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_downloader_download.webp b/android/app/src/main/res/drawable-xhdpi/ic_downloader_download.webp deleted file mode 100644 index 473a6f03d..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_downloader_download.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_downloader_download_night.webp b/android/app/src/main/res/drawable-xhdpi/ic_downloader_download_night.webp deleted file mode 100644 index 108ccb684..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_downloader_download_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder.webp b/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder.webp deleted file mode 100644 index f6ef4929e..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder_done.webp b/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder_done.webp deleted file mode 100644 index bc3e760a5..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder_done.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder_done_night.webp b/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder_done_night.webp deleted file mode 100644 index b0b2fd9cb..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder_done_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder_night.webp b/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder_night.webp deleted file mode 100644 index a084f560a..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_downloader_folder_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_downloader_retry.webp b/android/app/src/main/res/drawable-xhdpi/ic_downloader_retry.webp deleted file mode 100644 index 031336382..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_downloader_retry.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xhdpi/ic_transit.webp b/android/app/src/main/res/drawable-xhdpi/ic_transit.webp deleted file mode 100644 index 2aa1b2827..000000000 Binary files a/android/app/src/main/res/drawable-xhdpi/ic_transit.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_lightrail.webp b/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_lightrail.webp deleted file mode 100644 index 6cf5e7936..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_lightrail.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_metro.webp b/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_metro.webp deleted file mode 100644 index ffbd1f527..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_metro.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_monorail.webp b/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_monorail.webp deleted file mode 100644 index 7c539d301..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_monorail.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_train.webp b/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_train.webp deleted file mode 100644 index 83b385625..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_20px_route_planning_train.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_done.webp b/android/app/src/main/res/drawable-xxhdpi/ic_downloader_done.webp deleted file mode 100644 index 896729ad0..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_done.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_done_night.webp b/android/app/src/main/res/drawable-xxhdpi/ic_downloader_done_night.webp deleted file mode 100644 index bc289eece..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_done_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_download.webp b/android/app/src/main/res/drawable-xxhdpi/ic_downloader_download.webp deleted file mode 100644 index 82102a222..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_download.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_download_night.webp b/android/app/src/main/res/drawable-xxhdpi/ic_downloader_download_night.webp deleted file mode 100644 index 72a08c83a..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_download_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder.webp b/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder.webp deleted file mode 100644 index bec0d95dc..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder_done.webp b/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder_done.webp deleted file mode 100644 index 3389e6f72..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder_done.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder_done_night.webp b/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder_done_night.webp deleted file mode 100644 index 67690eb41..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder_done_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder_night.webp b/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder_night.webp deleted file mode 100644 index 9c0bae4d5..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_folder_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_retry.webp b/android/app/src/main/res/drawable-xxhdpi/ic_downloader_retry.webp deleted file mode 100644 index 799264736..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_downloader_retry.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/ic_transit.webp b/android/app/src/main/res/drawable-xxhdpi/ic_transit.webp deleted file mode 100644 index 16449f1cb..000000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/ic_transit.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_lightrail.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_lightrail.webp deleted file mode 100644 index e9fcf2241..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_lightrail.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_metro.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_metro.webp deleted file mode 100644 index 72f5f4f67..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_metro.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_monorail.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_monorail.webp deleted file mode 100644 index 1ede0100c..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_monorail.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_train.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_train.webp deleted file mode 100644 index 240b4aae4..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_20px_route_planning_train.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_done.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_done.webp deleted file mode 100644 index 87bfaaa5c..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_done.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_done_night.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_done_night.webp deleted file mode 100644 index 315c033b3..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_done_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_download.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_download.webp deleted file mode 100644 index eb9a8b07a..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_download.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_download_night.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_download_night.webp deleted file mode 100644 index ecebfdb0d..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_download_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder.webp deleted file mode 100644 index 1f8a96155..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder_done.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder_done.webp deleted file mode 100644 index 7dda7cc96..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder_done.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder_done_night.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder_done_night.webp deleted file mode 100644 index 194e831c2..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder_done_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder_night.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder_night.webp deleted file mode 100644 index 89f01ac43..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_folder_night.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_retry.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_retry.webp deleted file mode 100644 index 39f503ba7..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_downloader_retry.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/ic_transit.webp b/android/app/src/main/res/drawable-xxxhdpi/ic_transit.webp deleted file mode 100644 index 93442cbc6..000000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/ic_transit.webp and /dev/null differ diff --git a/android/app/src/main/res/drawable/downloader_done.xml b/android/app/src/main/res/drawable/downloader_done.xml new file mode 100644 index 000000000..73b3b0b80 --- /dev/null +++ b/android/app/src/main/res/drawable/downloader_done.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/downloader_done_night.xml b/android/app/src/main/res/drawable/downloader_done_night.xml new file mode 100644 index 000000000..74ae3d345 --- /dev/null +++ b/android/app/src/main/res/drawable/downloader_done_night.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/downloader_download.xml b/android/app/src/main/res/drawable/downloader_download.xml new file mode 100644 index 000000000..656bd5c41 --- /dev/null +++ b/android/app/src/main/res/drawable/downloader_download.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/downloader_download_night.xml b/android/app/src/main/res/drawable/downloader_download_night.xml new file mode 100644 index 000000000..de8b69c3c --- /dev/null +++ b/android/app/src/main/res/drawable/downloader_download_night.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/downloader_failed.xml b/android/app/src/main/res/drawable/downloader_failed.xml index e0afcf1ff..084bd4f0a 100644 --- a/android/app/src/main/res/drawable/downloader_failed.xml +++ b/android/app/src/main/res/drawable/downloader_failed.xml @@ -4,8 +4,16 @@ + - + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/downloader_folder.xml b/android/app/src/main/res/drawable/downloader_folder.xml new file mode 100644 index 000000000..8596f39fa --- /dev/null +++ b/android/app/src/main/res/drawable/downloader_folder.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/downloader_folder_done.xml b/android/app/src/main/res/drawable/downloader_folder_done.xml new file mode 100644 index 000000000..e8a9b0952 --- /dev/null +++ b/android/app/src/main/res/drawable/downloader_folder_done.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/downloader_folder_done_night.xml b/android/app/src/main/res/drawable/downloader_folder_done_night.xml new file mode 100644 index 000000000..7745e86f9 --- /dev/null +++ b/android/app/src/main/res/drawable/downloader_folder_done_night.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/downloader_folder_night.xml b/android/app/src/main/res/drawable/downloader_folder_night.xml new file mode 100644 index 000000000..00fa330a4 --- /dev/null +++ b/android/app/src/main/res/drawable/downloader_folder_night.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/android/app/src/main/res/drawable/downloader_update.xml b/android/app/src/main/res/drawable/downloader_update.xml index deffe9b3a..805387bcb 100644 --- a/android/app/src/main/res/drawable/downloader_update.xml +++ b/android/app/src/main/res/drawable/downloader_update.xml @@ -3,9 +3,17 @@ xmlns:android="http://schemas.android.com/apk/res/android"> - + + - + \ No newline at end of file diff --git a/android/app/src/main/res/drawable/ic_category_atm.xml b/android/app/src/main/res/drawable/ic_category_atm.xml index fd1e8f5f9..a35bd22ca 100644 --- a/android/app/src/main/res/drawable/ic_category_atm.xml +++ b/android/app/src/main/res/drawable/ic_category_atm.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M20,8 C20.82725,8 21.5,8.67275 21.5,9.5 L21.5,18.5 C21.5,19.32725 20.82725,20 20,20 L8,20 C7.17275,20 6.5,19.32725 6.5,18.5 L6.5,9.5 C6.5,8.67275 7.17275,8 8,8 L20,8 Z M20.00075,14 L8,14 L8,18.5 L20.0015,18.5 L20.00075,14 Z M14,15.5 L14,17 L9.5,17 L9.5,15.5 L14,15.5 Z M20,9.5 L8,9.5 L8,11 L20,11 L20,9.5 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_atm_night.xml b/android/app/src/main/res/drawable/ic_category_atm_night.xml index f584cdc17..15bb41f97 100644 --- a/android/app/src/main/res/drawable/ic_category_atm_night.xml +++ b/android/app/src/main/res/drawable/ic_category_atm_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M20,8 C20.82725,8 21.5,8.67275 21.5,9.5 L21.5,18.5 C21.5,19.32725 20.82725,20 20,20 L8,20 C7.17275,20 6.5,19.32725 6.5,18.5 L6.5,9.5 C6.5,8.67275 7.17275,8 8,8 L20,8 Z M20.00075,14 L8,14 L8,18.5 L20.0015,18.5 L20.00075,14 Z M14,15.5 L14,17 L9.5,17 L9.5,15.5 L14,15.5 Z M20,9.5 L8,9.5 L8,11 L20,11 L20,9.5 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_bank.xml b/android/app/src/main/res/drawable/ic_category_bank.xml index e704b123d..bd9b318cd 100644 --- a/android/app/src/main/res/drawable/ic_category_bank.xml +++ b/android/app/src/main/res/drawable/ic_category_bank.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M7,9.53073333 L14,6.3 L21,9.53073333 L21,10.60766 L19.9230733,10.60766 L19.9230733,18.68461 L21,18.68461 L21,20.2999767 L7,20.2999767 L7,18.68461 L8.07692667,18.68461 L8.07692667,10.60766 L7,10.60766 L7,9.53073333 Z M16.6923167,15.2756333 C16.6923167,14.0852833 15.4814333,13.1208 13.9976667,13.1208 C13.50468,13.1208 13.09784,12.7993017 13.09784,12.4012583 C13.09784,12.003215 13.4998967,11.6817167 13.9976667,11.6817167 C14.4954483,11.6817167 14.8974933,12.0070417 14.8974933,12.4012583 L16.69241,12.4012583 C16.69241,11.4673883 15.94096,10.6789083 14.8974933,10.3803583 L14.8974933,9.53068667 L13.1025767,9.53068667 L13.1025767,10.3803583 C12.0591567,10.6788967 11.30766,11.46733 11.30766,12.4012583 C11.30766,13.5916083 12.5185433,14.5560917 14.00231,14.5560917 C14.5000917,14.5560917 14.9021367,14.87759 14.9021367,15.2756333 C14.9021367,15.6736767 14.50008,15.995175 14.00231,15.995175 C13.5045283,15.995175 13.1024833,15.66985 13.1024833,15.2756333 L11.3075667,15.2756333 C11.3075667,16.2095033 12.0590167,16.9979833 13.1024833,17.2965333 L13.1024833,18.146205 L14.8974,18.146205 L14.8974,17.2965333 C15.94082,16.997995 16.6923167,16.2095617 16.6923167,15.2756333 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_bank_night.xml b/android/app/src/main/res/drawable/ic_category_bank_night.xml index b65c51f6e..383ee5e6f 100644 --- a/android/app/src/main/res/drawable/ic_category_bank_night.xml +++ b/android/app/src/main/res/drawable/ic_category_bank_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M7,9.53073333 L14,6.3 L21,9.53073333 L21,10.60766 L19.9230733,10.60766 L19.9230733,18.68461 L21,18.68461 L21,20.2999767 L7,20.2999767 L7,18.68461 L8.07692667,18.68461 L8.07692667,10.60766 L7,10.60766 L7,9.53073333 Z M16.6923167,15.2756333 C16.6923167,14.0852833 15.4814333,13.1208 13.9976667,13.1208 C13.50468,13.1208 13.09784,12.7993017 13.09784,12.4012583 C13.09784,12.003215 13.4998967,11.6817167 13.9976667,11.6817167 C14.4954483,11.6817167 14.8974933,12.0070417 14.8974933,12.4012583 L16.69241,12.4012583 C16.69241,11.4673883 15.94096,10.6789083 14.8974933,10.3803583 L14.8974933,9.53068667 L13.1025767,9.53068667 L13.1025767,10.3803583 C12.0591567,10.6788967 11.30766,11.46733 11.30766,12.4012583 C11.30766,13.5916083 12.5185433,14.5560917 14.00231,14.5560917 C14.5000917,14.5560917 14.9021367,14.87759 14.9021367,15.2756333 C14.9021367,15.6736767 14.50008,15.995175 14.00231,15.995175 C13.5045283,15.995175 13.1024833,15.66985 13.1024833,15.2756333 L11.3075667,15.2756333 C11.3075667,16.2095033 12.0590167,16.9979833 13.1024833,17.2965333 L13.1024833,18.146205 L14.8974,18.146205 L14.8974,17.2965333 C15.94082,16.997995 16.6923167,16.2095617 16.6923167,15.2756333 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_children.xml b/android/app/src/main/res/drawable/ic_category_children.xml index 47f0027fb..34c738fe5 100644 --- a/android/app/src/main/res/drawable/ic_category_children.xml +++ b/android/app/src/main/res/drawable/ic_category_children.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M10.7398398,14.5988166 C11.2766539,14.5988166 11.7741396,14.7668787 12.1823664,15.0532612 C11.7724801,15.4914625 11.5235582,16.0775925 11.5235582,16.7240712 L11.529303,16.8892426 L11.5491056,17.0705775 C11.6012609,17.429281 11.7280184,17.7632492 11.9167798,18.0556079 L11.9546499,18.1104694 L11.9142567,18.13405 C11.1417478,18.5947243 10.6376499,19.4380664 10.6376499,20.3887564 L10.637,21.073 L5.952,21.073 L5.95232411,17.1079171 C5.95232411,15.7221656 7.06098553,14.5988166 8.46443574,14.5988166 L10.7398398,14.5988166 Z M14.7363802,18.7647355 C15.6343829,18.7647355 16.3623501,19.4913492 16.3623501,20.3887564 L16.362,21.073 L11.637,21.073 L11.6376499,20.3887564 C11.6376499,19.4918257 12.3552335,18.7647355 13.2636198,18.7647355 L14.7363802,18.7647355 Z M19.4916069,12.4068343 C20.8792516,12.4068343 22.0041478,13.5296391 22.0041478,14.9163636 L22.004,21.073 L17.362,21.073 L17.3623501,20.3887564 L17.3567032,20.2194334 L17.3385166,20.043376 C17.2273964,19.2299207 16.7526866,18.5346787 16.0784713,18.1328785 L16.0416499,18.1124694 L16.0806774,18.0575117 C16.336328,17.665886 16.4764418,17.2070581 16.4764418,16.7240712 C16.4764418,15.6254025 15.757471,14.7010059 14.7609634,14.3838791 C15.0006762,13.2537372 15.9971232,12.4068343 17.215814,12.4068343 L19.4916069,12.4068343 Z M14,15.2664694 C14.8194057,15.2664694 15.4764418,15.9151249 15.4764418,16.7240712 C15.4764418,17.5330608 14.819449,18.1816731 14,18.1816731 C13.1805943,18.1816731 12.5235582,17.5330175 12.5235582,16.7240712 C12.5235582,15.9150816 13.1805943,15.2664694 14,15.2664694 Z M9.60213775,9.19402109 C10.8681135,9.19402109 11.8832295,10.1961892 11.8832295,11.4460053 C11.8832295,12.6958883 10.8681805,13.6979895 9.60213775,13.6979895 C8.33616197,13.6979895 7.32104605,12.6958214 7.32104605,11.4460053 C7.32104605,10.1961223 8.33616197,9.19402109 9.60213775,9.19402109 Z M18.3537105,7.00111521 C19.6199026,7.00111521 20.635192,8.00345456 20.635192,9.25348422 C20.635192,10.5035808 19.6199695,11.5058532 18.3537105,11.5058532 C17.0875184,11.5058532 16.072229,10.5035139 16.072229,9.25348422 C16.072229,8.00338763 17.0875184,7.00111521 18.3537105,7.00111521 Z" + android:fillColor="#FFF" /> diff --git a/android/app/src/main/res/drawable/ic_category_children_night.xml b/android/app/src/main/res/drawable/ic_category_children_night.xml index 27d8504c0..81e85f719 100644 --- a/android/app/src/main/res/drawable/ic_category_children_night.xml +++ b/android/app/src/main/res/drawable/ic_category_children_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M10.7398398,14.5988166 C11.2766539,14.5988166 11.7741396,14.7668787 12.1823664,15.0532612 C11.7724801,15.4914625 11.5235582,16.0775925 11.5235582,16.7240712 L11.529303,16.8892426 L11.5491056,17.0705775 C11.6012609,17.429281 11.7280184,17.7632492 11.9167798,18.0556079 L11.9546499,18.1104694 L11.9142567,18.13405 C11.1417478,18.5947243 10.6376499,19.4380664 10.6376499,20.3887564 L10.637,21.073 L5.952,21.073 L5.95232411,17.1079171 C5.95232411,15.7221656 7.06098553,14.5988166 8.46443574,14.5988166 L10.7398398,14.5988166 Z M14.7363802,18.7647355 C15.6343829,18.7647355 16.3623501,19.4913492 16.3623501,20.3887564 L16.362,21.073 L11.637,21.073 L11.6376499,20.3887564 C11.6376499,19.4918257 12.3552335,18.7647355 13.2636198,18.7647355 L14.7363802,18.7647355 Z M19.4916069,12.4068343 C20.8792516,12.4068343 22.0041478,13.5296391 22.0041478,14.9163636 L22.004,21.073 L17.362,21.073 L17.3623501,20.3887564 L17.3567032,20.2194334 L17.3385166,20.043376 C17.2273964,19.2299207 16.7526866,18.5346787 16.0784713,18.1328785 L16.0416499,18.1124694 L16.0806774,18.0575117 C16.336328,17.665886 16.4764418,17.2070581 16.4764418,16.7240712 C16.4764418,15.6254025 15.757471,14.7010059 14.7609634,14.3838791 C15.0006762,13.2537372 15.9971232,12.4068343 17.215814,12.4068343 L19.4916069,12.4068343 Z M14,15.2664694 C14.8194057,15.2664694 15.4764418,15.9151249 15.4764418,16.7240712 C15.4764418,17.5330608 14.819449,18.1816731 14,18.1816731 C13.1805943,18.1816731 12.5235582,17.5330175 12.5235582,16.7240712 C12.5235582,15.9150816 13.1805943,15.2664694 14,15.2664694 Z M9.60213775,9.19402109 C10.8681135,9.19402109 11.8832295,10.1961892 11.8832295,11.4460053 C11.8832295,12.6958883 10.8681805,13.6979895 9.60213775,13.6979895 C8.33616197,13.6979895 7.32104605,12.6958214 7.32104605,11.4460053 C7.32104605,10.1961223 8.33616197,9.19402109 9.60213775,9.19402109 Z M18.3537105,7.00111521 C19.6199026,7.00111521 20.635192,8.00345456 20.635192,9.25348422 C20.635192,10.5035808 19.6199695,11.5058532 18.3537105,11.5058532 C17.0875184,11.5058532 16.072229,10.5035139 16.072229,9.25348422 C16.072229,8.00338763 17.0875184,7.00111521 18.3537105,7.00111521 Z" + android:fillColor="#FFF" /> diff --git a/android/app/src/main/res/drawable/ic_category_eat.xml b/android/app/src/main/res/drawable/ic_category_eat.xml index 5d2a20998..f9f9e8028 100644 --- a/android/app/src/main/res/drawable/ic_category_eat.xml +++ b/android/app/src/main/res/drawable/ic_category_eat.xml @@ -4,27 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> - + android:pathData="M12.5416667,11.1416783 L12.5416667,7.70257833 C12.5416667,7.31455667 12.232395,7 11.8466717,7 L11.7783342,7 C11.3945008,7 11.0833392,7.32498667 11.0833392,7.70257833 L11.0833392,11.1416783 L9.62500583,11.1416783 L9.62500583,7.70257833 C9.62500583,7.31455667 9.31573417,7 8.93001083,7 L8.86167333,7 C8.47784,7 8.16667833,7.32498667 8.16667833,7.70257833 L8.16667833,11.1416783 C8.16667833,12.749345 9.62501167,14.0000117 11.0104283,14.0000117 L10.8211833,20.055945 C10.8048897,20.5773283 11.2048417,21 11.7169383,21 L11.9080967,21 C12.4190967,21 12.815985,20.58308 12.7940167,20.055945 L12.54169,14.0000117 C14.0000233,14.0000117 15.7500233,12.749345 15.4583567,11.1416783 L15.4583567,7.70257833 C15.4583567,7.31455667 15.149085,7 14.7633617,7 L14.6950242,7 C14.3111908,7 14.0000292,7.32498667 14.0000292,7.70257833 L14.0000292,11.1416783 L12.5416958,11.1416783 L12.5416667,11.1416783 Z M16.3333333,14.933345 L18.0833333,14.933345 L18.0833333,20.130845 C18.0833333,20.6108933 18.4717167,21.0000467 18.9583333,21.0000467 C19.4415783,21.0000467 19.8333333,20.6109983 19.8333333,20.1242883 L19.8333333,7.000455 C17.3903333,7.000455 16.275,8.69912167 16.3333333,10.0337883 L16.3333333,14.9337883 L16.3333333,14.933345 Z" + android:fillColor="#FFF" /> diff --git a/android/app/src/main/res/drawable/ic_category_eat_night.xml b/android/app/src/main/res/drawable/ic_category_eat_night.xml index 948617f6d..c8c7031f3 100644 --- a/android/app/src/main/res/drawable/ic_category_eat_night.xml +++ b/android/app/src/main/res/drawable/ic_category_eat_night.xml @@ -4,27 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> - + android:pathData="M12.5416667,11.1416783 L12.5416667,7.70257833 C12.5416667,7.31455667 12.232395,7 11.8466717,7 L11.7783342,7 C11.3945008,7 11.0833392,7.32498667 11.0833392,7.70257833 L11.0833392,11.1416783 L9.62500583,11.1416783 L9.62500583,7.70257833 C9.62500583,7.31455667 9.31573417,7 8.93001083,7 L8.86167333,7 C8.47784,7 8.16667833,7.32498667 8.16667833,7.70257833 L8.16667833,11.1416783 C8.16667833,12.749345 9.62501167,14.0000117 11.0104283,14.0000117 L10.8211833,20.055945 C10.8048897,20.5773283 11.2048417,21 11.7169383,21 L11.9080967,21 C12.4190967,21 12.815985,20.58308 12.7940167,20.055945 L12.54169,14.0000117 C14.0000233,14.0000117 15.7500233,12.749345 15.4583567,11.1416783 L15.4583567,7.70257833 C15.4583567,7.31455667 15.149085,7 14.7633617,7 L14.6950242,7 C14.3111908,7 14.0000292,7.32498667 14.0000292,7.70257833 L14.0000292,11.1416783 L12.5416958,11.1416783 L12.5416667,11.1416783 Z M16.3333333,14.933345 L18.0833333,14.933345 L18.0833333,20.130845 C18.0833333,20.6108933 18.4717167,21.0000467 18.9583333,21.0000467 C19.4415783,21.0000467 19.8333333,20.6109983 19.8333333,20.1242883 L19.8333333,7.000455 C17.3903333,7.000455 16.275,8.69912167 16.3333333,10.0337883 L16.3333333,14.9337883 L16.3333333,14.933345 Z" + android:fillColor="#FFF" /> diff --git a/android/app/src/main/res/drawable/ic_category_entertainment.xml b/android/app/src/main/res/drawable/ic_category_entertainment.xml index b6726f387..5593afa6e 100644 --- a/android/app/src/main/res/drawable/ic_category_entertainment.xml +++ b/android/app/src/main/res/drawable/ic_category_entertainment.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M14.8166667,12.2166667 L14.8166667,17.525 C14.8166667,20.0076667 12.8076667,22.0166667 10.325,22.0166667 C7.84233333,22.0166667 5.83333333,20.0076667 5.83333333,17.525 L5.83333333,12.2166667 L14.8166667,12.2166667 Z M12.3666667,17.9333333 L8.28333333,17.9333333 C8.28333333,18.6111667 9.198,19.1583333 10.325,19.1583333 C11.452,19.1583333 12.3666667,18.6111667 12.3666667,17.9333333 Z M22.1666667,6.5 L22.1666667,11.8083333 C22.1666667,14.291 20.1576667,16.3 17.675,16.3 C16.94,16.3 16.2458333,16.1121667 15.6333333,15.8018333 L15.6333333,11.4 L13.1833333,11.4 L13.1833333,6.5 L22.1666667,6.5 Z M12.3666667,14.6666667 C11.9175,14.6666667 11.55,15.0341667 11.55,15.4833333 C11.55,15.9325 11.9175,16.3 12.3666667,16.3 C12.8158333,16.3 13.1833333,15.9325 13.1833333,15.4833333 C13.1833333,15.0341667 12.8158333,14.6666667 12.3666667,14.6666667 Z M8.28333333,14.6666667 C7.83416667,14.6666667 7.46666667,15.0341667 7.46666667,15.4833333 C7.46666667,15.9325 7.83416667,16.3 8.28333333,16.3 C8.7325,16.3 9.1,15.9325 9.1,15.4833333 C9.1,15.0341667 8.7325,14.6666667 8.28333333,14.6666667 Z M17.675,12.2166667 C16.548,12.2166667 15.6333333,12.7638333 15.6333333,13.4416667 L19.7166667,13.4416667 C19.7166667,12.7638333 18.802,12.2166667 17.675,12.2166667 Z M15.6333333,9.01533333 C15.1841667,9.01533333 14.8166667,9.38283333 14.8166667,9.832 C14.8166667,10.2811667 15.1841667,10.6486667 15.6333333,10.6486667 C16.0825,10.6486667 16.45,10.2893333 16.45,9.832 C16.45,9.38283333 16.0825,9.01533333 15.6333333,9.01533333 Z M19.7166667,9.01533333 C19.2675,9.01533333 18.9,9.38283333 18.9,9.832 C18.9,10.2811667 19.2675,10.6486667 19.7166667,10.6486667 C20.1658333,10.6486667 20.5333333,10.2893333 20.5333333,9.832 C20.5333333,9.38283333 20.1658333,9.01533333 19.7166667,9.01533333 Z" + android:fillColor="#FFF" /> diff --git a/android/app/src/main/res/drawable/ic_category_entertainment_night.xml b/android/app/src/main/res/drawable/ic_category_entertainment_night.xml index 0035f9964..995b1eadb 100644 --- a/android/app/src/main/res/drawable/ic_category_entertainment_night.xml +++ b/android/app/src/main/res/drawable/ic_category_entertainment_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M14.8166667,12.2166667 L14.8166667,17.525 C14.8166667,20.0076667 12.8076667,22.0166667 10.325,22.0166667 C7.84233333,22.0166667 5.83333333,20.0076667 5.83333333,17.525 L5.83333333,12.2166667 L14.8166667,12.2166667 Z M12.3666667,17.9333333 L8.28333333,17.9333333 C8.28333333,18.6111667 9.198,19.1583333 10.325,19.1583333 C11.452,19.1583333 12.3666667,18.6111667 12.3666667,17.9333333 Z M22.1666667,6.5 L22.1666667,11.8083333 C22.1666667,14.291 20.1576667,16.3 17.675,16.3 C16.94,16.3 16.2458333,16.1121667 15.6333333,15.8018333 L15.6333333,11.4 L13.1833333,11.4 L13.1833333,6.5 L22.1666667,6.5 Z M12.3666667,14.6666667 C11.9175,14.6666667 11.55,15.0341667 11.55,15.4833333 C11.55,15.9325 11.9175,16.3 12.3666667,16.3 C12.8158333,16.3 13.1833333,15.9325 13.1833333,15.4833333 C13.1833333,15.0341667 12.8158333,14.6666667 12.3666667,14.6666667 Z M8.28333333,14.6666667 C7.83416667,14.6666667 7.46666667,15.0341667 7.46666667,15.4833333 C7.46666667,15.9325 7.83416667,16.3 8.28333333,16.3 C8.7325,16.3 9.1,15.9325 9.1,15.4833333 C9.1,15.0341667 8.7325,14.6666667 8.28333333,14.6666667 Z M17.675,12.2166667 C16.548,12.2166667 15.6333333,12.7638333 15.6333333,13.4416667 L19.7166667,13.4416667 C19.7166667,12.7638333 18.802,12.2166667 17.675,12.2166667 Z M15.6333333,9.01533333 C15.1841667,9.01533333 14.8166667,9.38283333 14.8166667,9.832 C14.8166667,10.2811667 15.1841667,10.6486667 15.6333333,10.6486667 C16.0825,10.6486667 16.45,10.2893333 16.45,9.832 C16.45,9.38283333 16.0825,9.01533333 15.6333333,9.01533333 Z M19.7166667,9.01533333 C19.2675,9.01533333 18.9,9.38283333 18.9,9.832 C18.9,10.2811667 19.2675,10.6486667 19.7166667,10.6486667 C20.1658333,10.6486667 20.5333333,10.2893333 20.5333333,9.832 C20.5333333,9.38283333 20.1658333,9.01533333 19.7166667,9.01533333 Z" + android:fillColor="#FFF" /> diff --git a/android/app/src/main/res/drawable/ic_category_food.xml b/android/app/src/main/res/drawable/ic_category_food.xml index f2a89fe73..cb83a54ef 100644 --- a/android/app/src/main/res/drawable/ic_category_food.xml +++ b/android/app/src/main/res/drawable/ic_category_food.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M11.3735667,18.307716 C10.6313217,18.307716 10.0307333,18.9134843 10.0307333,19.653816 C10.0307333,20.394206 10.631275,20.999916 11.3735667,20.999916 C12.1158117,20.999916 12.72305,20.3941477 12.72305,19.653816 C12.72305,18.913426 12.115765,18.307716 11.3735667,18.307716 Z M6.8,7.48804933 C6.8,7.813281 7.06993167,8.07692433 7.38562,8.07692433 L8.2,8.07692433 L10.3,14.5385077 C9.55654167,14.5385077 8.9539,15.3205827 8.9539,16.286291 L8.9539,16.0215277 C8.9539,16.9867927 9.739055,17.769311 10.7023833,17.769311 L18.8085,17.769311 C19.1352133,17.769311 19.4000583,17.5195393 19.4000583,17.180436 L19.4000583,17.2812663 C19.4000583,16.9560347 19.129765,16.6923913 18.8139717,16.6923913 L10.6169717,16.6923913 C10.29328,16.6923913 10.030885,16.4426197 10.030885,16.1035163 L10.030885,16.2043467 C10.030885,15.879115 10.2980983,15.6154717 10.6084667,15.6154717 L18.0620667,15.6154717 C19.2169033,15.6154717 19.113315,15.3197567 19.2870667,14.969325 L20.7161167,10.1360583 C20.7721167,10.0380583 20.8001167,9.91905833 20.8001167,9.80005833 C20.8001167,9.41505833 20.4851167,9.10005833 20.2616533,9.1539 L9.74707,9.1539 L8.90007,7 L7.37395333,7 C7.05702833,7 6.8,7.24977167 6.8,7.588875 L6.8,7.48804467 L6.8,7.48804933 Z M17.8350333,18.307716 C17.0927883,18.307716 16.4922,18.9134843 16.4922,19.653816 C16.4922,20.394206 17.0927417,20.999916 17.8350333,20.999916 C18.577325,20.999916 19.1845167,20.3941477 19.1845167,19.653816 C19.1845167,18.913426 18.5772317,18.307716 17.8350333,18.307716 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_food_night.xml b/android/app/src/main/res/drawable/ic_category_food_night.xml index e1d451e1f..6855997e2 100644 --- a/android/app/src/main/res/drawable/ic_category_food_night.xml +++ b/android/app/src/main/res/drawable/ic_category_food_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M11.3735667,18.307716 C10.6313217,18.307716 10.0307333,18.9134843 10.0307333,19.653816 C10.0307333,20.394206 10.631275,20.999916 11.3735667,20.999916 C12.1158117,20.999916 12.72305,20.3941477 12.72305,19.653816 C12.72305,18.913426 12.115765,18.307716 11.3735667,18.307716 Z M6.8,7.48804933 C6.8,7.813281 7.06993167,8.07692433 7.38562,8.07692433 L8.2,8.07692433 L10.3,14.5385077 C9.55654167,14.5385077 8.9539,15.3205827 8.9539,16.286291 L8.9539,16.0215277 C8.9539,16.9867927 9.739055,17.769311 10.7023833,17.769311 L18.8085,17.769311 C19.1352133,17.769311 19.4000583,17.5195393 19.4000583,17.180436 L19.4000583,17.2812663 C19.4000583,16.9560347 19.129765,16.6923913 18.8139717,16.6923913 L10.6169717,16.6923913 C10.29328,16.6923913 10.030885,16.4426197 10.030885,16.1035163 L10.030885,16.2043467 C10.030885,15.879115 10.2980983,15.6154717 10.6084667,15.6154717 L18.0620667,15.6154717 C19.2169033,15.6154717 19.113315,15.3197567 19.2870667,14.969325 L20.7161167,10.1360583 C20.7721167,10.0380583 20.8001167,9.91905833 20.8001167,9.80005833 C20.8001167,9.41505833 20.4851167,9.10005833 20.2616533,9.1539 L9.74707,9.1539 L8.90007,7 L7.37395333,7 C7.05702833,7 6.8,7.24977167 6.8,7.588875 L6.8,7.48804467 L6.8,7.48804933 Z M17.8350333,18.307716 C17.0927883,18.307716 16.4922,18.9134843 16.4922,19.653816 C16.4922,20.394206 17.0927417,20.999916 17.8350333,20.999916 C18.577325,20.999916 19.1845167,20.3941477 19.1845167,19.653816 C19.1845167,18.913426 18.5772317,18.307716 17.8350333,18.307716 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_fuel.xml b/android/app/src/main/res/drawable/ic_category_fuel.xml index de96fb50b..191d0b0fe 100644 --- a/android/app/src/main/res/drawable/ic_category_fuel.xml +++ b/android/app/src/main/res/drawable/ic_category_fuel.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M17.846514,4.676 C17.5575662,4.7216586 17.3186367,4.92551065 17.2280519,5.20366514 C17.1374671,5.48181964 17.2105329,5.78727723 17.4171807,5.99433333 L19.428514,8.00566667 C19.799514,8.37666667 20.062014,8.83516667 20.1973474,9.33333333 L19.523014,9.33333333 C18.2431807,9.33333333 17.1896807,10.3868333 17.1896807,11.6666667 C17.1896807,12.9465 18.2431807,14 19.523014,14 L20.300007,14 L20.300007,19.4448333 C20.300007,19.8835 19.9616807,20.2218333 19.523014,20.2218333 C19.315878,20.2250062 19.1162779,20.1442015 18.9696836,19.997827 C18.8230893,19.8514525 18.7419852,19.6519738 18.7448474,19.4448333 L18.7448474,17.8885 C18.7448474,16.6098333 17.6913474,15.5551667 16.411514,15.5551667 L15.6333474,15.5551667 L15.6333474,7.77816667 C15.6345903,7.36522389 15.4711795,6.96881891 15.1792931,6.67671349 C14.8874066,6.38460807 14.4911243,6.22090001 14.0781807,6.22183333 L7.85634735,6.22183333 C7.44320185,6.22058891 7.04661893,6.38415963 6.75447962,6.67629894 C6.46234031,6.96843825 6.2987696,7.36502117 6.30000697,7.77816667 L6.30000697,20.2218333 C6.2987696,20.6349788 6.46234031,21.0315618 6.75447962,21.3237011 C7.04661893,21.6158404 7.44320185,21.7794111 7.85634735,21.7781737 L14.0781807,21.7781737 C14.4911243,21.7791 14.8874066,21.6153919 15.1792931,21.3232865 C15.4711795,21.0311811 15.6345903,20.6347761 15.6333474,20.2218333 L15.6333474,17.1115 L16.411514,17.1115 C16.8501807,17.1115 17.1896807,17.4498333 17.1896807,17.8885 L17.1896807,19.4448333 C17.1896807,20.7235 18.2431807,21.7781737 19.523014,21.7781737 C20.8016807,21.7781737 21.8563474,20.7235 21.8563474,19.4448333 L21.8563474,10.1115 C21.8563474,8.90940677 21.3788136,7.75655029 20.5286807,6.90666667 L18.5173474,4.89416667 C18.3411731,4.71808596 18.0913541,4.63698153 17.8453474,4.676 L17.846514,4.676 Z M8.63218069,7.77816667 L13.2988474,7.77816667 C13.730514,7.77816667 14.077014,8.12466667 14.077014,8.55516667 L14.077014,12.4448333 L7.85634735,12.4448333 L7.85634735,8.55516667 C7.85634735,8.12466667 8.20284735,7.77816667 8.63334735,7.77816667 L8.63218069,7.77816667 Z M19.523014,10.5 C20.1673462,10.5 20.6896807,11.0223345 20.6896807,11.6666667 C20.6896807,12.3109989 20.1673462,12.8333333 19.523014,12.8333333 C18.8786818,12.8333333 18.3563474,12.3109989 18.3563474,11.6666667 C18.3563474,11.0223345 18.8786818,10.5 19.523014,10.5 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_fuel_night.xml b/android/app/src/main/res/drawable/ic_category_fuel_night.xml index d8a031d14..a6e3b3bc6 100644 --- a/android/app/src/main/res/drawable/ic_category_fuel_night.xml +++ b/android/app/src/main/res/drawable/ic_category_fuel_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M17.846514,4.676 C17.5575662,4.7216586 17.3186367,4.92551065 17.2280519,5.20366514 C17.1374671,5.48181964 17.2105329,5.78727723 17.4171807,5.99433333 L19.428514,8.00566667 C19.799514,8.37666667 20.062014,8.83516667 20.1973474,9.33333333 L19.523014,9.33333333 C18.2431807,9.33333333 17.1896807,10.3868333 17.1896807,11.6666667 C17.1896807,12.9465 18.2431807,14 19.523014,14 L20.300007,14 L20.300007,19.4448333 C20.300007,19.8835 19.9616807,20.2218333 19.523014,20.2218333 C19.315878,20.2250062 19.1162779,20.1442015 18.9696836,19.997827 C18.8230893,19.8514525 18.7419852,19.6519738 18.7448474,19.4448333 L18.7448474,17.8885 C18.7448474,16.6098333 17.6913474,15.5551667 16.411514,15.5551667 L15.6333474,15.5551667 L15.6333474,7.77816667 C15.6345903,7.36522389 15.4711795,6.96881891 15.1792931,6.67671349 C14.8874066,6.38460807 14.4911243,6.22090001 14.0781807,6.22183333 L7.85634735,6.22183333 C7.44320185,6.22058891 7.04661893,6.38415963 6.75447962,6.67629894 C6.46234031,6.96843825 6.2987696,7.36502117 6.30000697,7.77816667 L6.30000697,20.2218333 C6.2987696,20.6349788 6.46234031,21.0315618 6.75447962,21.3237011 C7.04661893,21.6158404 7.44320185,21.7794111 7.85634735,21.7781737 L14.0781807,21.7781737 C14.4911243,21.7791 14.8874066,21.6153919 15.1792931,21.3232865 C15.4711795,21.0311811 15.6345903,20.6347761 15.6333474,20.2218333 L15.6333474,17.1115 L16.411514,17.1115 C16.8501807,17.1115 17.1896807,17.4498333 17.1896807,17.8885 L17.1896807,19.4448333 C17.1896807,20.7235 18.2431807,21.7781737 19.523014,21.7781737 C20.8016807,21.7781737 21.8563474,20.7235 21.8563474,19.4448333 L21.8563474,10.1115 C21.8563474,8.90940677 21.3788136,7.75655029 20.5286807,6.90666667 L18.5173474,4.89416667 C18.3411731,4.71808596 18.0913541,4.63698153 17.8453474,4.676 L17.846514,4.676 Z M8.63218069,7.77816667 L13.2988474,7.77816667 C13.730514,7.77816667 14.077014,8.12466667 14.077014,8.55516667 L14.077014,12.4448333 L7.85634735,12.4448333 L7.85634735,8.55516667 C7.85634735,8.12466667 8.20284735,7.77816667 8.63334735,7.77816667 L8.63218069,7.77816667 Z M19.523014,10.5 C20.1673462,10.5 20.6896807,11.0223345 20.6896807,11.6666667 C20.6896807,12.3109989 20.1673462,12.8333333 19.523014,12.8333333 C18.8786818,12.8333333 18.3563474,12.3109989 18.3563474,11.6666667 C18.3563474,11.0223345 18.8786818,10.5 19.523014,10.5 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_hospital.xml b/android/app/src/main/res/drawable/ic_category_hospital.xml index ba07c21ac..d6d884be1 100644 --- a/android/app/src/main/res/drawable/ic_category_hospital.xml +++ b/android/app/src/main/res/drawable/ic_category_hospital.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M21.1291111,17.1111111 L17.1106444,17.1111111 L17.1106444,21.1295778 C17.1106444,21.9138422 16.4689778,22.5555089 15.6847133,22.5555089 L12.3142911,22.5555089 C11.5300267,22.5555089 10.88836,21.9138422 10.88836,21.1295778 L10.88836,17.1111111 L6.86973778,17.1111111 C6.08547333,17.1111111 5.44383778,16.4694444 5.44383778,15.68518 L5.44383778,12.3147578 C5.44383778,11.5304933 6.08550444,10.8888267 6.86973778,10.8888267 L10.88836,10.8888267 L10.88836,6.87036 C10.88836,6.08609556 11.5300267,5.44442889 12.3142911,5.44442889 L15.6847133,5.44442889 C16.4689778,5.44442889 17.1106444,6.08609556 17.1106444,6.87036 L17.1106444,10.8888267 L21.1291111,10.8888267 C21.9133756,10.8888267 22.5550422,11.5304933 22.5550422,12.3147578 L22.5550422,15.68518 C22.5550422,16.4694444 21.9133756,17.1111111 21.1291111,17.1111111 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_hospital_night.xml b/android/app/src/main/res/drawable/ic_category_hospital_night.xml index c04d87935..cded0e193 100644 --- a/android/app/src/main/res/drawable/ic_category_hospital_night.xml +++ b/android/app/src/main/res/drawable/ic_category_hospital_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M21.1291111,17.1111111 L17.1106444,17.1111111 L17.1106444,21.1295778 C17.1106444,21.9138422 16.4689778,22.5555089 15.6847133,22.5555089 L12.3142911,22.5555089 C11.5300267,22.5555089 10.88836,21.9138422 10.88836,21.1295778 L10.88836,17.1111111 L6.86973778,17.1111111 C6.08547333,17.1111111 5.44383778,16.4694444 5.44383778,15.68518 L5.44383778,12.3147578 C5.44383778,11.5304933 6.08550444,10.8888267 6.86973778,10.8888267 L10.88836,10.8888267 L10.88836,6.87036 C10.88836,6.08609556 11.5300267,5.44442889 12.3142911,5.44442889 L15.6847133,5.44442889 C16.4689778,5.44442889 17.1106444,6.08609556 17.1106444,6.87036 L17.1106444,10.8888267 L21.1291111,10.8888267 C21.9133756,10.8888267 22.5550422,11.5304933 22.5550422,12.3147578 L22.5550422,15.68518 C22.5550422,16.4694444 21.9133756,17.1111111 21.1291111,17.1111111 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_hotel.xml b/android/app/src/main/res/drawable/ic_category_hotel.xml index af6336782..b91fcd69d 100644 --- a/android/app/src/main/res/drawable/ic_category_hotel.xml +++ b/android/app/src/main/res/drawable/ic_category_hotel.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M10.2879,14.1061667 C11.5203667,14.1061667 12.5151833,13.111315 12.5151833,11.8788833 C12.5151833,10.6464167 11.5203317,9.6516 10.2879,9.6516 C9.05543333,9.6516 8.06061667,10.6464517 8.06061667,11.8788833 C8.06061667,13.11135 9.05546833,14.1061667 10.2879,14.1061667 Z M19.1970333,9.6516 L14.7424667,9.6516 C13.9258,9.6516 13.25765,10.319785 13.25765,11.1364167 L13.25765,14.8485167 L7.31826667,14.8485167 L7.31826667,8.90913333 C7.31826667,8.5008 6.98418,8.16671333 6.57584667,8.16671333 C6.16751333,8.16671333 5.83342667,8.5008 5.83342667,8.90913333 L5.83342667,18.5606167 C5.83342667,18.96895 6.16751333,19.3030367 6.57584667,19.3030367 C6.98418,19.3030367 7.31826667,18.96895 7.31826667,18.5606167 L7.31826667,17.0758 L20.6824333,17.0758 L20.6824333,18.5606167 C20.6824333,18.96895 21.01652,19.3030367 21.4248533,19.3030367 C21.8331867,19.3030367 22.1672733,18.96895 22.1672733,18.5606167 L22.1672733,12.6212333 C22.1672733,10.9804333 20.8383233,9.65148333 19.1975233,9.65148333 L19.1970333,9.6516 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_hotel_night.xml b/android/app/src/main/res/drawable/ic_category_hotel_night.xml index 9431696a3..b91fcd69d 100644 --- a/android/app/src/main/res/drawable/ic_category_hotel_night.xml +++ b/android/app/src/main/res/drawable/ic_category_hotel_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M10.2879,14.1061667 C11.5203667,14.1061667 12.5151833,13.111315 12.5151833,11.8788833 C12.5151833,10.6464167 11.5203317,9.6516 10.2879,9.6516 C9.05543333,9.6516 8.06061667,10.6464517 8.06061667,11.8788833 C8.06061667,13.11135 9.05546833,14.1061667 10.2879,14.1061667 Z M19.1970333,9.6516 L14.7424667,9.6516 C13.9258,9.6516 13.25765,10.319785 13.25765,11.1364167 L13.25765,14.8485167 L7.31826667,14.8485167 L7.31826667,8.90913333 C7.31826667,8.5008 6.98418,8.16671333 6.57584667,8.16671333 C6.16751333,8.16671333 5.83342667,8.5008 5.83342667,8.90913333 L5.83342667,18.5606167 C5.83342667,18.96895 6.16751333,19.3030367 6.57584667,19.3030367 C6.98418,19.3030367 7.31826667,18.96895 7.31826667,18.5606167 L7.31826667,17.0758 L20.6824333,17.0758 L20.6824333,18.5606167 C20.6824333,18.96895 21.01652,19.3030367 21.4248533,19.3030367 C21.8331867,19.3030367 22.1672733,18.96895 22.1672733,18.5606167 L22.1672733,12.6212333 C22.1672733,10.9804333 20.8383233,9.65148333 19.1975233,9.65148333 L19.1970333,9.6516 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_nightlife.xml b/android/app/src/main/res/drawable/ic_category_nightlife.xml index f533b64ca..ea28ded79 100644 --- a/android/app/src/main/res/drawable/ic_category_nightlife.xml +++ b/android/app/src/main/res/drawable/ic_category_nightlife.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M21,8.42778167 C21,7.80556333 20.4944483,7.3 19.8722183,7.3 L8.127385,7.3 C7.50516667,7.3 6.99960333,7.80555167 6.99960333,8.42778167 C6.99960333,8.7 7.10071483,8.97223 7.287385,9.17444833 L13.2218683,15.8555983 L13.2218683,19.7444483 L10.1107183,19.7444483 C9.68293667,19.7444483 9.33293667,20.0944483 9.33293667,20.52223 C9.33293667,20.9500117 9.68293667,21.3000117 10.1107183,21.3000117 L17.888535,21.3000117 C18.3163167,21.3000117 18.6663167,20.9500117 18.6663167,20.52223 C18.6663167,20.0944483 18.3163167,19.7444483 17.888535,19.7444483 L14.777385,19.7444483 L14.777385,15.8555983 L20.7118683,9.17444833 C20.898535,8.97223 20.99965,8.7 20.99965,8.42778167 L21,8.42778167 Z M10.4455167,10.411115 L9.06885,8.85559833 L18.93885,8.85559833 L17.5543667,10.411115 L10.4455167,10.411115 L10.4455167,10.411115 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_nightlife_night.xml b/android/app/src/main/res/drawable/ic_category_nightlife_night.xml index a640d4d82..ee4132e8c 100644 --- a/android/app/src/main/res/drawable/ic_category_nightlife_night.xml +++ b/android/app/src/main/res/drawable/ic_category_nightlife_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M21,8.42778167 C21,7.80556333 20.4944483,7.3 19.8722183,7.3 L8.127385,7.3 C7.50516667,7.3 6.99960333,7.80555167 6.99960333,8.42778167 C6.99960333,8.7 7.10071483,8.97223 7.287385,9.17444833 L13.2218683,15.8555983 L13.2218683,19.7444483 L10.1107183,19.7444483 C9.68293667,19.7444483 9.33293667,20.0944483 9.33293667,20.52223 C9.33293667,20.9500117 9.68293667,21.3000117 10.1107183,21.3000117 L17.888535,21.3000117 C18.3163167,21.3000117 18.6663167,20.9500117 18.6663167,20.52223 C18.6663167,20.0944483 18.3163167,19.7444483 17.888535,19.7444483 L14.777385,19.7444483 L14.777385,15.8555983 L20.7118683,9.17444833 C20.898535,8.97223 20.99965,8.7 20.99965,8.42778167 L21,8.42778167 Z M10.4455167,10.411115 L9.06885,8.85559833 L18.93885,8.85559833 L17.5543667,10.411115 L10.4455167,10.411115 L10.4455167,10.411115 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_parking.xml b/android/app/src/main/res/drawable/ic_category_parking.xml index a0e25254d..3c55676fe 100644 --- a/android/app/src/main/res/drawable/ic_category_parking.xml +++ b/android/app/src/main/res/drawable/ic_category_parking.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M9.35,22.3 L13.1840042,22.3 L13.1840042,16.379733 L14.4487167,16.379733 C16.4953333,16.379733 18.0936417,15.9233039 19.1939042,14.9897598 C20.3178375,14.0448193 20.85,12.6687324 20.85,10.8925278 C20.85,9.17330503 20.3522033,7.86253173 19.3111083,6.99727004 C18.2581875,6.12060241 16.709425,5.7 14.6982667,5.7 L9.3502875,5.7002873 L9.35,22.3 Z M13.1840042,8.60425301 L14.5565292,8.60425301 C15.5029792,8.60425301 16.17755,8.78662355 16.6154125,9.17371683 C17.0649667,9.57220647 17.2884404,10.1637639 17.2884404,10.9949323 C17.2884404,11.8032888 17.0518663,12.4290544 16.5076479,12.8616374 C15.9752746,13.282891 15.1586979,13.5329885 14.0820104,13.5329885 L13.1840042,13.5329885 L13.1840042,8.60425301 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_parking_night.xml b/android/app/src/main/res/drawable/ic_category_parking_night.xml index a2278618d..4d356bff7 100644 --- a/android/app/src/main/res/drawable/ic_category_parking_night.xml +++ b/android/app/src/main/res/drawable/ic_category_parking_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M9.35,22.3 L13.1840042,22.3 L13.1840042,16.379733 L14.4487167,16.379733 C16.4953333,16.379733 18.0936417,15.9233039 19.1939042,14.9897598 C20.3178375,14.0448193 20.85,12.6687324 20.85,10.8925278 C20.85,9.17330503 20.3522033,7.86253173 19.3111083,6.99727004 C18.2581875,6.12060241 16.709425,5.7 14.6982667,5.7 L9.3502875,5.7002873 L9.35,22.3 Z M13.1840042,8.60425301 L14.5565292,8.60425301 C15.5029792,8.60425301 16.17755,8.78662355 16.6154125,9.17371683 C17.0649667,9.57220647 17.2884404,10.1637639 17.2884404,10.9949323 C17.2884404,11.8032888 17.0518663,12.4290544 16.5076479,12.8616374 C15.9752746,13.282891 15.1586979,13.5329885 14.0820104,13.5329885 L13.1840042,13.5329885 L13.1840042,8.60425301 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_pharmacy.xml b/android/app/src/main/res/drawable/ic_category_pharmacy.xml index a9b9162cc..3bd6c77a8 100644 --- a/android/app/src/main/res/drawable/ic_category_pharmacy.xml +++ b/android/app/src/main/res/drawable/ic_category_pharmacy.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M16.961,6.99999417 C15.9026933,6.99999417 14.84875,7.41071333 14.0726833,8.17973333 L8.2299,13.9907833 C7.02531667,15.1842833 6.69806667,16.9171333 7.28183167,18.3600667 C7.28183167,18.3600667 7.71838667,19.382475 8.14171167,19.80195 C8.54021,20.1968083 9.021355,20.4748717 9.508695,20.675795 C9.64324667,20.7452082 9.744875,20.770512 9.86146,20.80687 C9.877112,20.8116985 9.88986133,20.8240783 9.9055565,20.8287158 C11.3082398,21.2432442 12.8732065,20.907362 13.9403565,19.8019442 L17.4680065,16.3064942 L19.7830232,13.9907775 C21.4057398,12.3828775 21.4057398,9.80501083 19.7830232,8.26711083 C19.0774815,7.42821917 18.0191398,6.99999417 16.9608565,6.99999417 L16.961,6.99999417 Z M16.961,8.39813333 C17.6665417,8.39813333 18.3852667,8.67339667 18.8792333,9.162755 C19.3732,9.65211333 19.6509133,10.364305 19.6509133,11.0633717 C19.6509133,11.76245 19.3731067,12.452755 18.8792333,12.9421717 L16.4760167,15.323455 L12.6658,11.523155 L14.9987833,9.22832167 C15.5632167,8.66905667 16.1849333,8.39813333 16.9611167,8.39813333 L16.961,8.39813333 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_pharmacy_night.xml b/android/app/src/main/res/drawable/ic_category_pharmacy_night.xml index 685452027..9142c07d1 100644 --- a/android/app/src/main/res/drawable/ic_category_pharmacy_night.xml +++ b/android/app/src/main/res/drawable/ic_category_pharmacy_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M16.961,6.99999417 C15.9026933,6.99999417 14.84875,7.41071333 14.0726833,8.17973333 L8.2299,13.9907833 C7.02531667,15.1842833 6.69806667,16.9171333 7.28183167,18.3600667 C7.28183167,18.3600667 7.71838667,19.382475 8.14171167,19.80195 C8.54021,20.1968083 9.021355,20.4748717 9.508695,20.675795 C9.64324667,20.7452082 9.744875,20.770512 9.86146,20.80687 C9.877112,20.8116985 9.88986133,20.8240783 9.9055565,20.8287158 C11.3082398,21.2432442 12.8732065,20.907362 13.9403565,19.8019442 L17.4680065,16.3064942 L19.7830232,13.9907775 C21.4057398,12.3828775 21.4057398,9.80501083 19.7830232,8.26711083 C19.0774815,7.42821917 18.0191398,6.99999417 16.9608565,6.99999417 L16.961,6.99999417 Z M16.961,8.39813333 C17.6665417,8.39813333 18.3852667,8.67339667 18.8792333,9.162755 C19.3732,9.65211333 19.6509133,10.364305 19.6509133,11.0633717 C19.6509133,11.76245 19.3731067,12.452755 18.8792333,12.9421717 L16.4760167,15.323455 L12.6658,11.523155 L14.9987833,9.22832167 C15.5632167,8.66905667 16.1849333,8.39813333 16.9611167,8.39813333 L16.961,8.39813333 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_police.xml b/android/app/src/main/res/drawable/ic_category_police.xml index 82646e31e..d3da642b6 100644 --- a/android/app/src/main/res/drawable/ic_category_police.xml +++ b/android/app/src/main/res/drawable/ic_category_police.xml @@ -4,30 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> - - + android:pathData="M14,5.833275 L7.31815,8.803025 L7.31815,13.2575917 C7.31815,17.378025 10.1690167,21.231175 14,22.166725 C17.8308667,21.2312683 20.68185,17.3781417 20.68185,13.2575917 L20.68185,8.803025 L14,5.833275 L14,5.833275 Z M15.85605,14.438025 L16.524235,17.3186417 L14.000035,15.796725 L11.475835,17.3186417 L12.14402,14.4454917 L9.91673667,12.5225917 L12.8567367,12.2701717 L14.00007,9.560355 L15.1434033,12.2628217 L18.0834033,12.5152417 L15.85612,14.4381417 L15.85605,14.438025 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_police_night.xml b/android/app/src/main/res/drawable/ic_category_police_night.xml index e525e159f..d6e34393e 100644 --- a/android/app/src/main/res/drawable/ic_category_police_night.xml +++ b/android/app/src/main/res/drawable/ic_category_police_night.xml @@ -4,30 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> - - + android:pathData="M14,5.833275 L7.31815,8.803025 L7.31815,13.2575917 C7.31815,17.378025 10.1690167,21.231175 14,22.166725 C17.8308667,21.2312683 20.68185,17.3781417 20.68185,13.2575917 L20.68185,8.803025 L14,5.833275 L14,5.833275 Z M15.85605,14.438025 L16.524235,17.3186417 L14.000035,15.796725 L11.475835,17.3186417 L12.14402,14.4454917 L9.91673667,12.5225917 L12.8567367,12.2701717 L14.00007,9.560355 L15.1434033,12.2628217 L18.0834033,12.5152417 L15.85612,14.4381417 L15.85605,14.438025 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_post.xml b/android/app/src/main/res/drawable/ic_category_post.xml index 108443173..09693a519 100644 --- a/android/app/src/main/res/drawable/ic_category_post.xml +++ b/android/app/src/main/res/drawable/ic_category_post.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M20.5333333,7 C21.4316667,7 22.1666667,7.735 22.1666667,8.63333333 L22.1666667,18.4333333 C22.1666667,19.3316667 21.4316667,20.0666667 20.5333333,20.0666667 L7.46666667,20.0666667 C6.56833333,20.0666667 5.83333333,19.3316667 5.83333333,18.4333333 L5.8415,8.63333333 C5.8415,7.735 6.56833333,7 7.46666667,7 L20.5333333,7 Z M20.5333333,9.88283333 C20.5333333,9.33566667 19.9371667,9.009 19.4716667,9.29483333 L14,12.7166667 L8.52833333,9.29483333 C8.06283333,9.009 7.46666667,9.33566667 7.46666667,9.88283333 C7.46666667,10.1196667 7.58916667,10.3401667 7.79333333,10.4708333 L13.5671667,14.0805 C13.8285,14.2438333 14.1715,14.2438333 14.4328333,14.0805 L20.2066667,10.4708333 C20.4108333,10.3401667 20.5333333,10.1196667 20.5333333,9.88283333 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_post_night.xml b/android/app/src/main/res/drawable/ic_category_post_night.xml index 15f36c641..32c20338a 100644 --- a/android/app/src/main/res/drawable/ic_category_post_night.xml +++ b/android/app/src/main/res/drawable/ic_category_post_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M20.5333333,7 C21.4316667,7 22.1666667,7.735 22.1666667,8.63333333 L22.1666667,18.4333333 C22.1666667,19.3316667 21.4316667,20.0666667 20.5333333,20.0666667 L7.46666667,20.0666667 C6.56833333,20.0666667 5.83333333,19.3316667 5.83333333,18.4333333 L5.8415,8.63333333 C5.8415,7.735 6.56833333,7 7.46666667,7 L20.5333333,7 Z M20.5333333,9.88283333 C20.5333333,9.33566667 19.9371667,9.009 19.4716667,9.29483333 L14,12.7166667 L8.52833333,9.29483333 C8.06283333,9.009 7.46666667,9.33566667 7.46666667,9.88283333 C7.46666667,10.1196667 7.58916667,10.3401667 7.79333333,10.4708333 L13.5671667,14.0805 C13.8285,14.2438333 14.1715,14.2438333 14.4328333,14.0805 L20.2066667,10.4708333 C20.4108333,10.3401667 20.5333333,10.1196667 20.5333333,9.88283333 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_recycling.xml b/android/app/src/main/res/drawable/ic_category_recycling.xml index b23328a0b..8c5452081 100644 --- a/android/app/src/main/res/drawable/ic_category_recycling.xml +++ b/android/app/src/main/res/drawable/ic_category_recycling.xml @@ -5,24 +5,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:fillColor="#FFF" + android:pathData="M9.26178239,9.86916295 L10.4193833,7.95061481 L11.2531868,6.56634591 C11.5688972,6.04016587 12.3298444,6.04016587 12.6455913,6.56634591 L13.843676,8.5577503 L12.8479738,10.2253086 L12.0384558,11.5367213 L9.26178239,9.86916295 Z M22.1731256,14.5805343 L20.8778628,12.4272676 L18.0769039,14.0462551 L19.8658893,17.0333617 L20.7806361,17.0333617 C21.3958708,17.0333617 21.9544354,16.6852666 22.2296256,16.1348011 C22.3429572,15.9081332 22.3996236,15.665279 22.3996236,15.4143378 C22.3996236,15.1229127 22.3186718,14.8395869 22.1729556,14.5805343 L22.1731256,14.5805343 Z M17.5427461,21.0808911 L18.7570171,21.0808911 C19.3722518,21.0808911 19.9308164,20.732796 20.2060066,20.1823306 L21.379806,17.8427947 L17.5427097,17.8427947 L17.5427097,16.2238072 L14.3046133,19.4619036 L17.5427097,22.7 L17.5427097,21.0810125 L17.5427461,21.0808911 Z M12.6856622,17.8427947 L9.20471166,17.8427947 L8.52471991,18.9842094 C8.28186572,19.3889623 8.26567949,19.8908691 8.47614908,20.3199075 C8.70281704,20.7813304 9.18042624,21.0808547 9.70656985,21.0808547 L12.6855408,21.0808547 L12.6855408,17.8427583 L12.6856622,17.8427947 Z M9.54470753,15.6975422 L10.9451262,16.5394327 L9.83609613,12.0952009 L5.4,13.204231 L6.77613329,14.0299353 L6.44423661,14.5884999 C6.16091076,15.0661091 6.13662534,15.6489592 6.38757022,16.1427668 L7.70711848,18.7817419 L9.54467474,15.6974936 L9.54470753,15.6975422 Z M18.3684504,8.24191842 L17.3160782,6.48523261 C17.0165539,5.99952422 16.4903739,5.7 15.9236736,5.7 L13.0661298,5.7 L15.5918134,9.90951317 L14.1994089,10.7433166 L18.6436406,11.8523467 L19.7526707,7.40811497 L18.3684018,8.24191842 L18.3684504,8.24191842 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_recycling_night.xml b/android/app/src/main/res/drawable/ic_category_recycling_night.xml index cf39d5641..174d3c5d8 100644 --- a/android/app/src/main/res/drawable/ic_category_recycling_night.xml +++ b/android/app/src/main/res/drawable/ic_category_recycling_night.xml @@ -5,24 +5,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:fillColor="#FFF" + android:pathData="M9.26178239,9.86916295 L10.4193833,7.95061481 L11.2531868,6.56634591 C11.5688972,6.04016587 12.3298444,6.04016587 12.6455913,6.56634591 L13.843676,8.5577503 L12.8479738,10.2253086 L12.0384558,11.5367213 L9.26178239,9.86916295 Z M22.1731256,14.5805343 L20.8778628,12.4272676 L18.0769039,14.0462551 L19.8658893,17.0333617 L20.7806361,17.0333617 C21.3958708,17.0333617 21.9544354,16.6852666 22.2296256,16.1348011 C22.3429572,15.9081332 22.3996236,15.665279 22.3996236,15.4143378 C22.3996236,15.1229127 22.3186718,14.8395869 22.1729556,14.5805343 L22.1731256,14.5805343 Z M17.5427461,21.0808911 L18.7570171,21.0808911 C19.3722518,21.0808911 19.9308164,20.732796 20.2060066,20.1823306 L21.379806,17.8427947 L17.5427097,17.8427947 L17.5427097,16.2238072 L14.3046133,19.4619036 L17.5427097,22.7 L17.5427097,21.0810125 L17.5427461,21.0808911 Z M12.6856622,17.8427947 L9.20471166,17.8427947 L8.52471991,18.9842094 C8.28186572,19.3889623 8.26567949,19.8908691 8.47614908,20.3199075 C8.70281704,20.7813304 9.18042624,21.0808547 9.70656985,21.0808547 L12.6855408,21.0808547 L12.6855408,17.8427583 L12.6856622,17.8427947 Z M9.54470753,15.6975422 L10.9451262,16.5394327 L9.83609613,12.0952009 L5.4,13.204231 L6.77613329,14.0299353 L6.44423661,14.5884999 C6.16091076,15.0661091 6.13662534,15.6489592 6.38757022,16.1427668 L7.70711848,18.7817419 L9.54467474,15.6974936 L9.54470753,15.6975422 Z M18.3684504,8.24191842 L17.3160782,6.48523261 C17.0165539,5.99952422 16.4903739,5.7 15.9236736,5.7 L13.0661298,5.7 L15.5918134,9.90951317 L14.1994089,10.7433166 L18.6436406,11.8523467 L19.7526707,7.40811497 L18.3684018,8.24191842 L18.3684504,8.24191842 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_rv.xml b/android/app/src/main/res/drawable/ic_category_rv.xml index 874bc99cf..11a63ce2f 100644 --- a/android/app/src/main/res/drawable/ic_category_rv.xml +++ b/android/app/src/main/res/drawable/ic_category_rv.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M8.33758333,7.43983333 C6.95648333,7.43983333 5.83333333,8.590085 5.83333333,10.0056833 L5.83333333,16.9397667 C5.83333333,18.0495583 6.52384833,18.99765 7.48766667,19.3551167 C7.45779982,19.1965237 7.44027578,19.0357487 7.43526,18.87431 C7.43522971,18.0654358 7.74879599,17.2897014 8.30693531,16.7178646 C8.86507462,16.1460278 9.62203578,15.8249626 10.4111933,15.8253433 C12.0537082,15.8258056 13.3849729,17.1907579 13.38491,18.87431 C13.3830282,19.0874192 13.3593515,19.2997388 13.3142683,19.5077867 L23.3312683,19.5077867 C23.6679333,19.5077867 23.9419483,19.2262233 23.9419483,18.8811467 C23.9419483,18.53607 23.6679217,18.2567933 23.3312683,18.2567933 L21.4741683,18.2567933 C21.6999883,17.87135 21.82964,17.4210517 21.82964,16.9397433 L21.82964,13.3690433 C21.82964,10.09841 19.2349733,7.43983333 16.04414,7.43983333 L8.33772333,7.43983333 L8.33758333,7.43983333 Z M8.88445833,9.60225 L10.9944917,9.60225 C11.3312033,9.60225 11.6051833,9.88155 11.6051833,10.226615 L11.6051833,12.391365 C11.6051833,12.7364417 11.3311567,13.0157183 10.9944917,13.0157183 L8.88445833,13.0157183 C8.54779333,13.0157183 8.27376667,12.7364183 8.27376667,12.391365 L8.27376667,10.226615 C8.27376667,9.88153833 8.54779333,9.60225 8.88445833,9.60225 Z M16.647925,10.684625 L16.8097067,10.684625 C18.2658233,10.684625 19.4484733,11.8992417 19.4484733,13.3916417 L19.4484733,18.2566417 L18.2294233,18.2566417 L18.2294233,13.3916417 C18.2294233,12.5883683 17.5935433,11.9333083 16.8098233,11.9333083 L16.6480417,11.9333083 C15.8643567,11.9333083 15.2284417,12.5883683 15.2284417,13.3916417 L15.2284417,18.2566417 L14.0070583,18.2566417 L14.0070583,13.3916417 C14.0070583,11.8992417 15.191925,10.684625 16.6480417,10.684625 L16.647925,10.684625 Z M10.4111583,17.0581247 C9.94104172,17.0578394 9.49008616,17.2490609 9.15757567,17.5896894 C8.82506518,17.9303179 8.63829167,18.3924263 8.63829167,18.874275 C8.63829167,19.3561237 8.82506518,19.8182321 9.15757567,20.1588606 C9.49008616,20.4994891 9.94104172,20.6907106 10.4111583,20.6904253 C11.3892489,20.6896989 12.1817548,19.8767746 12.1816917,18.874275 C12.1817548,17.8717754 11.3892489,17.0588511 10.4111583,17.0581247 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_rv_night.xml b/android/app/src/main/res/drawable/ic_category_rv_night.xml index 189d9c6ae..16bde5ebe 100644 --- a/android/app/src/main/res/drawable/ic_category_rv_night.xml +++ b/android/app/src/main/res/drawable/ic_category_rv_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M8.33758333,7.43983333 C6.95648333,7.43983333 5.83333333,8.590085 5.83333333,10.0056833 L5.83333333,16.9397667 C5.83333333,18.0495583 6.52384833,18.99765 7.48766667,19.3551167 C7.45779982,19.1965237 7.44027578,19.0357487 7.43526,18.87431 C7.43522971,18.0654358 7.74879599,17.2897014 8.30693531,16.7178646 C8.86507462,16.1460278 9.62203578,15.8249626 10.4111933,15.8253433 C12.0537082,15.8258056 13.3849729,17.1907579 13.38491,18.87431 C13.3830282,19.0874192 13.3593515,19.2997388 13.3142683,19.5077867 L23.3312683,19.5077867 C23.6679333,19.5077867 23.9419483,19.2262233 23.9419483,18.8811467 C23.9419483,18.53607 23.6679217,18.2567933 23.3312683,18.2567933 L21.4741683,18.2567933 C21.6999883,17.87135 21.82964,17.4210517 21.82964,16.9397433 L21.82964,13.3690433 C21.82964,10.09841 19.2349733,7.43983333 16.04414,7.43983333 L8.33772333,7.43983333 L8.33758333,7.43983333 Z M8.88445833,9.60225 L10.9944917,9.60225 C11.3312033,9.60225 11.6051833,9.88155 11.6051833,10.226615 L11.6051833,12.391365 C11.6051833,12.7364417 11.3311567,13.0157183 10.9944917,13.0157183 L8.88445833,13.0157183 C8.54779333,13.0157183 8.27376667,12.7364183 8.27376667,12.391365 L8.27376667,10.226615 C8.27376667,9.88153833 8.54779333,9.60225 8.88445833,9.60225 Z M16.647925,10.684625 L16.8097067,10.684625 C18.2658233,10.684625 19.4484733,11.8992417 19.4484733,13.3916417 L19.4484733,18.2566417 L18.2294233,18.2566417 L18.2294233,13.3916417 C18.2294233,12.5883683 17.5935433,11.9333083 16.8098233,11.9333083 L16.6480417,11.9333083 C15.8643567,11.9333083 15.2284417,12.5883683 15.2284417,13.3916417 L15.2284417,18.2566417 L14.0070583,18.2566417 L14.0070583,13.3916417 C14.0070583,11.8992417 15.191925,10.684625 16.6480417,10.684625 L16.647925,10.684625 Z M10.4111583,17.0581247 C9.94104172,17.0578394 9.49008616,17.2490609 9.15757567,17.5896894 C8.82506518,17.9303179 8.63829167,18.3924263 8.63829167,18.874275 C8.63829167,19.3561237 8.82506518,19.8182321 9.15757567,20.1588606 C9.49008616,20.4994891 9.94104172,20.6907106 10.4111583,20.6904253 C11.3892489,20.6896989 12.1817548,19.8767746 12.1816917,18.874275 C12.1817548,17.8717754 11.3892489,17.0588511 10.4111583,17.0581247 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_secondhand.xml b/android/app/src/main/res/drawable/ic_category_secondhand.xml index 77f7b4a34..c4e5afdaf 100644 --- a/android/app/src/main/res/drawable/ic_category_secondhand.xml +++ b/android/app/src/main/res/drawable/ic_category_secondhand.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M13.9999526,5 C11.853286,5 10.110286,6.743 10.110286,8.88966667 L8.55628597,8.88966667 C7.7007343,8.88966667 7.00683597,9.58815 7.00683597,10.4436667 L7,19.777 C7,20.6325517 7.70075833,21.3333333 8.55633333,21.3333333 L19.4436667,21.3333333 C20.2992183,21.3333333 21,20.632575 21,19.777 L21,10.4436667 C21,9.588115 20.2992417,8.88966667 19.4436667,8.88966667 L17.8896667,8.88966667 C17.8896667,6.743 16.1466667,5 14,5 L13.9999526,5 Z M13.9999526,6.55633333 C15.2911026,6.55633333 16.333286,7.59855167 16.333286,8.88966667 L11.6666193,8.88966667 C11.6666193,7.59851667 12.7088376,6.55633333 13.9999526,6.55633333 Z M13.4348426,10.5098167 C13.4948839,10.5028588 13.5551031,10.5212898 13.6009647,10.5606609 C13.6468264,10.6000319 13.6741635,10.6567658 13.6763776,10.7171683 L13.7151145,11.8291533 C13.7184994,11.938957 13.6391949,12.0339269 13.5305478,12.0501783 C12.9058678,12.1446293 12.3049645,12.4314333 11.8238311,12.9160667 C10.7022678,14.04575 10.6473645,15.8238667 11.6255911,17.0426833 L12.6851578,15.97628 C12.7471434,15.914964 12.8398366,15.8967615 12.9204066,15.9300834 C13.0009766,15.9634054 13.0537346,16.0417631 13.0543028,16.12895 L13.0611383,19.2483833 C13.0611463,19.307801 13.0367599,19.3646163 12.9936828,19.4055408 C12.9506056,19.4464653 12.8926159,19.4679097 12.8332766,19.4648583 L9.88697663,19.3053517 C9.80143518,19.3012871 9.72630824,19.2472336 9.69526871,19.1674188 C9.66422918,19.0876039 9.68309816,18.996996 9.7434183,18.9362067 L10.54094,18.1295617 C8.97060663,16.3068783 9.02648997,13.5555283 10.7414666,11.829095 C11.495705,11.069245 12.4494666,10.629295 13.4348333,10.5097117 L13.4348426,10.5098167 Z M15.1711926,10.7559133 L18.1174926,10.917695 C18.2026243,10.9225973 18.2769698,10.9769641 18.3074479,11.056604 C18.3379261,11.1362439 18.3188721,11.2263546 18.2587643,11.28684 L17.4612426,12.0911983 C19.032976,13.9128317 18.980126,16.6660483 17.2652776,18.3938817 C17.2645181,18.3938777 17.2637586,18.3938777 17.2629991,18.3938817 C16.5080141,19.1533467 15.5524325,19.5913483 14.5674158,19.7109317 C14.5073745,19.7178895 14.4471553,19.6994585 14.4012937,19.6600875 C14.3554321,19.6207164 14.3280949,19.5639825 14.3258808,19.50358 L14.2894225,18.3938817 C14.2860376,18.284078 14.365342,18.1891081 14.4739891,18.1728567 C15.0982141,18.0784745 15.6977058,17.7894083 16.1783725,17.3046933 C16.179132,17.3046973 16.1798915,17.3046973 16.180651,17.3046933 C17.3022143,16.1759783 17.357351,14.4000433 16.378891,13.1802933 L15.3193243,14.2466967 C15.2573387,14.3080127 15.1646455,14.3262151 15.0840755,14.2928932 C15.0035055,14.2595713 14.9507475,14.1812135 14.9501793,14.0940267 L14.9433438,10.97226 C14.9433358,10.9128424 14.9677222,10.8560271 15.0107993,10.8151026 C15.0538765,10.7741781 15.1118662,10.7527337 15.1712055,10.755785 L15.1711926,10.7559133 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_secondhand_night.xml b/android/app/src/main/res/drawable/ic_category_secondhand_night.xml index 74c60e824..57416845e 100644 --- a/android/app/src/main/res/drawable/ic_category_secondhand_night.xml +++ b/android/app/src/main/res/drawable/ic_category_secondhand_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M13.9999526,5 C11.853286,5 10.110286,6.743 10.110286,8.88966667 L8.55628597,8.88966667 C7.7007343,8.88966667 7.00683597,9.58815 7.00683597,10.4436667 L7,19.777 C7,20.6325517 7.70075833,21.3333333 8.55633333,21.3333333 L19.4436667,21.3333333 C20.2992183,21.3333333 21,20.632575 21,19.777 L21,10.4436667 C21,9.588115 20.2992417,8.88966667 19.4436667,8.88966667 L17.8896667,8.88966667 C17.8896667,6.743 16.1466667,5 14,5 L13.9999526,5 Z M13.9999526,6.55633333 C15.2911026,6.55633333 16.333286,7.59855167 16.333286,8.88966667 L11.6666193,8.88966667 C11.6666193,7.59851667 12.7088376,6.55633333 13.9999526,6.55633333 Z M13.4348426,10.5098167 C13.4948839,10.5028588 13.5551031,10.5212898 13.6009647,10.5606609 C13.6468264,10.6000319 13.6741635,10.6567658 13.6763776,10.7171683 L13.7151145,11.8291533 C13.7184994,11.938957 13.6391949,12.0339269 13.5305478,12.0501783 C12.9058678,12.1446293 12.3049645,12.4314333 11.8238311,12.9160667 C10.7022678,14.04575 10.6473645,15.8238667 11.6255911,17.0426833 L12.6851578,15.97628 C12.7471434,15.914964 12.8398366,15.8967615 12.9204066,15.9300834 C13.0009766,15.9634054 13.0537346,16.0417631 13.0543028,16.12895 L13.0611383,19.2483833 C13.0611463,19.307801 13.0367599,19.3646163 12.9936828,19.4055408 C12.9506056,19.4464653 12.8926159,19.4679097 12.8332766,19.4648583 L9.88697663,19.3053517 C9.80143518,19.3012871 9.72630824,19.2472336 9.69526871,19.1674188 C9.66422918,19.0876039 9.68309816,18.996996 9.7434183,18.9362067 L10.54094,18.1295617 C8.97060663,16.3068783 9.02648997,13.5555283 10.7414666,11.829095 C11.495705,11.069245 12.4494666,10.629295 13.4348333,10.5097117 L13.4348426,10.5098167 Z M15.1711926,10.7559133 L18.1174926,10.917695 C18.2026243,10.9225973 18.2769698,10.9769641 18.3074479,11.056604 C18.3379261,11.1362439 18.3188721,11.2263546 18.2587643,11.28684 L17.4612426,12.0911983 C19.032976,13.9128317 18.980126,16.6660483 17.2652776,18.3938817 C17.2645181,18.3938777 17.2637586,18.3938777 17.2629991,18.3938817 C16.5080141,19.1533467 15.5524325,19.5913483 14.5674158,19.7109317 C14.5073745,19.7178895 14.4471553,19.6994585 14.4012937,19.6600875 C14.3554321,19.6207164 14.3280949,19.5639825 14.3258808,19.50358 L14.2894225,18.3938817 C14.2860376,18.284078 14.365342,18.1891081 14.4739891,18.1728567 C15.0982141,18.0784745 15.6977058,17.7894083 16.1783725,17.3046933 C16.179132,17.3046973 16.1798915,17.3046973 16.180651,17.3046933 C17.3022143,16.1759783 17.357351,14.4000433 16.378891,13.1802933 L15.3193243,14.2466967 C15.2573387,14.3080127 15.1646455,14.3262151 15.0840755,14.2928932 C15.0035055,14.2595713 14.9507475,14.1812135 14.9501793,14.0940267 L14.9433438,10.97226 C14.9433358,10.9128424 14.9677222,10.8560271 15.0107993,10.8151026 C15.0538765,10.7741781 15.1118662,10.7527337 15.1712055,10.755785 L15.1711926,10.7559133 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_shopping.xml b/android/app/src/main/res/drawable/ic_category_shopping.xml index d78e249a8..547a3649d 100644 --- a/android/app/src/main/res/drawable/ic_category_shopping.xml +++ b/android/app/src/main/res/drawable/ic_category_shopping.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M19.4443861,8.88885 L17.8888695,8.88885 C17.8888695,6.74218333 16.1466861,5 14.0000195,5 C11.8533528,5 10.1111695,6.74218333 10.1111695,8.88885 L8.55565282,8.88885 C7.70010115,8.88885 7.00783615,9.58885 7.00783615,10.4443667 L7.00005833,19.7777 C7.00005833,20.6332517 7.70005833,21.3332167 8.555575,21.3332167 L19.444425,21.3332167 C20.2999767,21.3332167 20.9999417,20.6332167 20.9999417,19.7777 L20.9999417,10.4443667 C20.9999417,9.588815 20.2999417,8.88885 19.444425,8.88885 L19.4443861,8.88885 Z M13.9999028,6.55551667 C15.2910528,6.55551667 16.3332362,7.597735 16.3332362,8.88885 L11.6665695,8.88885 C11.6665695,7.5977 12.7087878,6.55551667 13.9999028,6.55551667 Z M13.9999028,14.3333333 C11.8532362,14.3333333 10.1110528,12.59115 10.1110528,10.4444833 L11.6665695,10.4444833 C11.6665695,11.7356333 12.7087878,12.7778167 13.9999028,12.7778167 C15.2910178,12.7778167 16.3332362,11.7355983 16.3332362,10.4444833 L17.8887528,10.4444833 C17.8887528,12.59115 16.1465695,14.3333333 13.9999028,14.3333333 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_shopping_night.xml b/android/app/src/main/res/drawable/ic_category_shopping_night.xml index c9c7391f7..245ac5b3b 100644 --- a/android/app/src/main/res/drawable/ic_category_shopping_night.xml +++ b/android/app/src/main/res/drawable/ic_category_shopping_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M19.4443861,8.88885 L17.8888695,8.88885 C17.8888695,6.74218333 16.1466861,5 14.0000195,5 C11.8533528,5 10.1111695,6.74218333 10.1111695,8.88885 L8.55565282,8.88885 C7.70010115,8.88885 7.00783615,9.58885 7.00783615,10.4443667 L7.00005833,19.7777 C7.00005833,20.6332517 7.70005833,21.3332167 8.555575,21.3332167 L19.444425,21.3332167 C20.2999767,21.3332167 20.9999417,20.6332167 20.9999417,19.7777 L20.9999417,10.4443667 C20.9999417,9.588815 20.2999417,8.88885 19.444425,8.88885 L19.4443861,8.88885 Z M13.9999028,6.55551667 C15.2910528,6.55551667 16.3332362,7.597735 16.3332362,8.88885 L11.6665695,8.88885 C11.6665695,7.5977 12.7087878,6.55551667 13.9999028,6.55551667 Z M13.9999028,14.3333333 C11.8532362,14.3333333 10.1110528,12.59115 10.1110528,10.4444833 L11.6665695,10.4444833 C11.6665695,11.7356333 12.7087878,12.7778167 13.9999028,12.7778167 C15.2910178,12.7778167 16.3332362,11.7355983 16.3332362,10.4444833 L17.8887528,10.4444833 C17.8887528,12.59115 16.1465695,14.3333333 13.9999028,14.3333333 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_toilet.xml b/android/app/src/main/res/drawable/ic_category_toilet.xml index 610e9d854..16c40c0ea 100644 --- a/android/app/src/main/res/drawable/ic_category_toilet.xml +++ b/android/app/src/main/res/drawable/ic_category_toilet.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M10.3454333,8.64113333 C11.22839,8.64113333 11.9363,7.94225333 11.9363,7.07056667 C11.9363,6.19892667 11.2283433,5.5 10.3454333,5.5 C9.46252333,5.5 8.75456667,6.19888 8.75456667,7.07056667 C8.75456667,7.94220667 9.46252333,8.64113333 10.3454333,8.64113333 L10.3454333,8.64113333 Z M19.2545667,17.43605 L19.2545667,21.83345 L16.7091333,21.83345 L16.7091333,17.43605 L14.1637,17.43605 L16.3909833,10.5257667 C16.3909833,10.5257667 16.7091683,9.26938333 17.98185,9.26938333 C19.2545317,9.26938333 19.5727167,10.5257667 19.5727167,10.5257667 L21.8,17.43605 L19.2545667,17.43605 L19.2545667,17.43605 Z M11.61815,15.5514167 L11.61815,21.83345 L9.07271667,21.83345 L9.07271667,15.5514167 L7.8,15.5514167 L7.8,11.0192667 C7.8,10.0528233 8.57319667,9.26938333 9.55198333,9.26938333 L11.1388833,9.26938333 C12.1064817,9.26938333 12.8908667,10.05231 12.8908667,11.0192667 L12.8908667,15.5514167 L11.61815,15.5514167 Z M19.7362833,7.07068333 C19.7362833,7.94232333 19.00161,8.64125 18.0853333,8.64125 C17.1690567,8.64125 16.4343833,7.94237 16.4343833,7.07068333 C16.4343833,6.19904333 17.1690567,5.50011667 18.0853333,5.50011667 C19.00161,5.50011667 19.7362833,6.19899667 19.7362833,7.07068333 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_toilet_night.xml b/android/app/src/main/res/drawable/ic_category_toilet_night.xml index c72601dc0..ff8f84bb5 100644 --- a/android/app/src/main/res/drawable/ic_category_toilet_night.xml +++ b/android/app/src/main/res/drawable/ic_category_toilet_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M10.3454333,8.64113333 C11.22839,8.64113333 11.9363,7.94225333 11.9363,7.07056667 C11.9363,6.19892667 11.2283433,5.5 10.3454333,5.5 C9.46252333,5.5 8.75456667,6.19888 8.75456667,7.07056667 C8.75456667,7.94220667 9.46252333,8.64113333 10.3454333,8.64113333 L10.3454333,8.64113333 Z M19.2545667,17.43605 L19.2545667,21.83345 L16.7091333,21.83345 L16.7091333,17.43605 L14.1637,17.43605 L16.3909833,10.5257667 C16.3909833,10.5257667 16.7091683,9.26938333 17.98185,9.26938333 C19.2545317,9.26938333 19.5727167,10.5257667 19.5727167,10.5257667 L21.8,17.43605 L19.2545667,17.43605 L19.2545667,17.43605 Z M11.61815,15.5514167 L11.61815,21.83345 L9.07271667,21.83345 L9.07271667,15.5514167 L7.8,15.5514167 L7.8,11.0192667 C7.8,10.0528233 8.57319667,9.26938333 9.55198333,9.26938333 L11.1388833,9.26938333 C12.1064817,9.26938333 12.8908667,10.05231 12.8908667,11.0192667 L12.8908667,15.5514167 L11.61815,15.5514167 Z M19.7362833,7.07068333 C19.7362833,7.94232333 19.00161,8.64125 18.0853333,8.64125 C17.1690567,8.64125 16.4343833,7.94237 16.4343833,7.07068333 C16.4343833,6.19904333 17.1690567,5.50011667 18.0853333,5.50011667 C19.00161,5.50011667 19.7362833,6.19899667 19.7362833,7.07068333 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_tourism.xml b/android/app/src/main/res/drawable/ic_category_tourism.xml index 5abf359cf..e50a3e397 100644 --- a/android/app/src/main/res/drawable/ic_category_tourism.xml +++ b/android/app/src/main/res/drawable/ic_category_tourism.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M22.167,11.328l-5.717,-0.816l-2.45,-5.712l-2.45,5.712l-5.717,0.816l4.083,4.08l-0.817,5.726l4.9,-2.463l4.9,2.448l-0.817,-5.711z" /> diff --git a/android/app/src/main/res/drawable/ic_category_tourism_night.xml b/android/app/src/main/res/drawable/ic_category_tourism_night.xml index 681904378..7f972a181 100644 --- a/android/app/src/main/res/drawable/ic_category_tourism_night.xml +++ b/android/app/src/main/res/drawable/ic_category_tourism_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M22.167,11.328l-5.717,-0.816l-2.45,-5.712l-2.45,5.712l-5.717,0.816l4.083,4.08l-0.817,5.726l4.9,-2.463l4.9,2.448l-0.817,-5.711z" /> diff --git a/android/app/src/main/res/drawable/ic_category_transport.xml b/android/app/src/main/res/drawable/ic_category_transport.xml index dbff3f117..587426e54 100644 --- a/android/app/src/main/res/drawable/ic_category_transport.xml +++ b/android/app/src/main/res/drawable/ic_category_transport.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M17.7652425,5.6 C19.3205789,5.6 20.6007172,6.82330936 20.6712621,8.37700229 L21.1340668,18.5587623 C21.2018095,20.0490603 20.1357825,21.3284073 18.6981339,21.5620297 L18.2940892,21.5992497 L9.77120086,21.6 C8.27928213,21.6 7.04973517,20.4769811 6.88169744,19.0301853 L6.86287684,18.6248613 L7.3279318,8.37707196 C7.39855249,6.8233354 8.67873133,5.6 10.2339515,5.6 L17.7652425,5.6 Z M9.92695997,17.2362972 C9.28430184,17.2362972 8.76333027,17.7572687 8.76333027,18.3999268 C8.76333027,19.042585 9.28430184,19.5635566 9.92695997,19.5635566 C10.5696181,19.5635566 11.0905897,19.042585 11.0905897,18.3999268 C11.0905897,17.7572687 10.5696181,17.2362972 9.92695997,17.2362972 Z M18.0723679,17.2362972 C17.4297098,17.2362972 16.9087383,17.7572687 16.9087383,18.3999268 C16.9087383,19.042585 17.4297098,19.5635566 18.0723679,19.5635566 C18.7150261,19.5635566 19.2359977,19.042585 19.2359977,18.3999268 C19.2359977,17.7572687 18.7150261,17.2362972 18.0723679,17.2362972 Z M17.2628087,7.78180569 L10.736446,7.78180569 C9.95826161,7.78180569 9.31791619,8.39432582 9.28337093,9.17176139 L9.12032285,12.8726871 C9.12032285,13.675999 9.77154822,14.3272243 10.57486,14.3272243 L17.4890037,14.3257899 C18.2915299,14.2901216 18.9131848,13.6106375 18.8775195,12.8081258 L18.7159058,9.17178293 C18.6813533,8.39434738 18.0410005,7.78180569 17.2628087,7.78180569 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_transport_night.xml b/android/app/src/main/res/drawable/ic_category_transport_night.xml index a71232dc0..587426e54 100644 --- a/android/app/src/main/res/drawable/ic_category_transport_night.xml +++ b/android/app/src/main/res/drawable/ic_category_transport_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M17.7652425,5.6 C19.3205789,5.6 20.6007172,6.82330936 20.6712621,8.37700229 L21.1340668,18.5587623 C21.2018095,20.0490603 20.1357825,21.3284073 18.6981339,21.5620297 L18.2940892,21.5992497 L9.77120086,21.6 C8.27928213,21.6 7.04973517,20.4769811 6.88169744,19.0301853 L6.86287684,18.6248613 L7.3279318,8.37707196 C7.39855249,6.8233354 8.67873133,5.6 10.2339515,5.6 L17.7652425,5.6 Z M9.92695997,17.2362972 C9.28430184,17.2362972 8.76333027,17.7572687 8.76333027,18.3999268 C8.76333027,19.042585 9.28430184,19.5635566 9.92695997,19.5635566 C10.5696181,19.5635566 11.0905897,19.042585 11.0905897,18.3999268 C11.0905897,17.7572687 10.5696181,17.2362972 9.92695997,17.2362972 Z M18.0723679,17.2362972 C17.4297098,17.2362972 16.9087383,17.7572687 16.9087383,18.3999268 C16.9087383,19.042585 17.4297098,19.5635566 18.0723679,19.5635566 C18.7150261,19.5635566 19.2359977,19.042585 19.2359977,18.3999268 C19.2359977,17.7572687 18.7150261,17.2362972 18.0723679,17.2362972 Z M17.2628087,7.78180569 L10.736446,7.78180569 C9.95826161,7.78180569 9.31791619,8.39432582 9.28337093,9.17176139 L9.12032285,12.8726871 C9.12032285,13.675999 9.77154822,14.3272243 10.57486,14.3272243 L17.4890037,14.3257899 C18.2915299,14.2901216 18.9131848,13.6106375 18.8775195,12.8081258 L18.7159058,9.17178293 C18.6813533,8.39434738 18.0410005,7.78180569 17.2628087,7.78180569 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_water.xml b/android/app/src/main/res/drawable/ic_category_water.xml index 0567f5c6d..69cb80791 100644 --- a/android/app/src/main/res/drawable/ic_category_water.xml +++ b/android/app/src/main/res/drawable/ic_category_water.xml @@ -5,24 +5,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M14,21.8749 C11.1749,21.8749 8.5482,19.4518 8.5482,16.4231 C8.5482,13.3606 12.6876,7.8747 14,6.1251 C15.3125,7.8751 19.4518,13.3606 19.4518,16.4231 C19.4518,19.4519 16.825,21.8749 14,21.8749 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_water_night.xml b/android/app/src/main/res/drawable/ic_category_water_night.xml index 309485b10..6f4a95898 100644 --- a/android/app/src/main/res/drawable/ic_category_water_night.xml +++ b/android/app/src/main/res/drawable/ic_category_water_night.xml @@ -5,24 +5,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M14,21.8749 C11.1749,21.8749 8.5482,19.4518 8.5482,16.4231 C8.5482,13.3606 12.6876,7.8747 14,6.1251 C15.3125,7.8751 19.4518,13.3606 19.4518,16.4231 C19.4518,19.4519 16.825,21.8749 14,21.8749 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_wifi.xml b/android/app/src/main/res/drawable/ic_category_wifi.xml index 041b147be..69230dd6c 100644 --- a/android/app/src/main/res/drawable/ic_category_wifi.xml +++ b/android/app/src/main/res/drawable/ic_category_wifi.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M14,16.98 C15.1045695,16.98 16.1045695,17.4277153 16.8284271,18.1515729 L14,20.98 L11.1715729,18.1515729 C11.8954305,17.4277153 12.8954305,16.98 14,16.98 Z M14,12.48 C16.3472102,12.48 18.4722102,13.4313949 20.0104076,14.9695924 L18.2426407,16.7373593 C17.1568542,15.6515729 15.6568542,14.98 14,14.98 C12.3431458,14.98 10.8431458,15.6515729 9.75735931,16.7373593 L7.98959236,14.9695924 C9.52778981,13.4313949 11.6527898,12.48 14,12.48 Z M14,7.98 C17.5898509,7.98 20.8398509,9.43507456 23.1923882,11.7876118 L21.4251209,13.5558785 C19.5249552,11.6554586 16.8997491,10.48 14,10.48 C11.1002509,10.48 8.47504482,11.6554586 6.57487909,13.5558785 L4.80761184,11.7876118 C7.16014913,9.43507456 10.4101491,7.98 14,7.98 Z" /> diff --git a/android/app/src/main/res/drawable/ic_category_wifi_night.xml b/android/app/src/main/res/drawable/ic_category_wifi_night.xml index d99eaf165..52732cb30 100644 --- a/android/app/src/main/res/drawable/ic_category_wifi_night.xml +++ b/android/app/src/main/res/drawable/ic_category_wifi_night.xml @@ -4,24 +4,21 @@ - + + android:viewportWidth="28" + android:viewportHeight="28"> + android:pivotY="12"> + android:pathData="M14,16.98 C15.1045695,16.98 16.1045695,17.4277153 16.8284271,18.1515729 L14,20.98 L11.1715729,18.1515729 C11.8954305,17.4277153 12.8954305,16.98 14,16.98 Z M14,12.48 C16.3472102,12.48 18.4722102,13.4313949 20.0104076,14.9695924 L18.2426407,16.7373593 C17.1568542,15.6515729 15.6568542,14.98 14,14.98 C12.3431458,14.98 10.8431458,15.6515729 9.75735931,16.7373593 L7.98959236,14.9695924 C9.52778981,13.4313949 11.6527898,12.48 14,12.48 Z M14,7.98 C17.5898509,7.98 20.8398509,9.43507456 23.1923882,11.7876118 L21.4251209,13.5558785 C19.5249552,11.6554586 16.8997491,10.48 14,10.48 C11.1002509,10.48 8.47504482,11.6554586 6.57487909,13.5558785 L4.80761184,11.7876118 C7.16014913,9.43507456 10.4101491,7.98 14,7.98 Z" /> diff --git a/android/app/src/main/res/drawable/ic_christmas_tree.xml b/android/app/src/main/res/drawable/ic_christmas_tree.xml deleted file mode 100644 index bdcb7c5ab..000000000 --- a/android/app/src/main/res/drawable/ic_christmas_tree.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/android/app/src/main/res/drawable/ic_downloader_retry.xml b/android/app/src/main/res/drawable/ic_downloader_retry.xml new file mode 100644 index 000000000..59ff2c03f --- /dev/null +++ b/android/app/src/main/res/drawable/ic_downloader_retry.xml @@ -0,0 +1,9 @@ + + + diff --git a/android/app/src/main/res/drawable/ic_downloader_update.xml b/android/app/src/main/res/drawable/ic_downloader_update.xml index e2894f76d..8e9438838 100644 --- a/android/app/src/main/res/drawable/ic_downloader_update.xml +++ b/android/app/src/main/res/drawable/ic_downloader_update.xml @@ -1,6 +1,6 @@ diff --git a/android/app/src/main/res/drawable/ic_folder.xml b/android/app/src/main/res/drawable/ic_folder.xml new file mode 100644 index 000000000..c83e5ffd0 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_folder.xml @@ -0,0 +1,9 @@ + + + diff --git a/android/app/src/main/res/drawable/ic_launcher_foreground.xml b/android/app/src/main/res/drawable/ic_launcher_foreground.xml index e5feaca18..ca96e4b5c 100644 --- a/android/app/src/main/res/drawable/ic_launcher_foreground.xml +++ b/android/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -1,4 +1,15 @@ - \ No newline at end of file + + + + + diff --git a/android/app/src/main/res/drawable/ic_launcher_foreground_monochrome.xml b/android/app/src/main/res/drawable/ic_launcher_foreground_monochrome.xml index 39ee678d6..982267933 100644 --- a/android/app/src/main/res/drawable/ic_launcher_foreground_monochrome.xml +++ b/android/app/src/main/res/drawable/ic_launcher_foreground_monochrome.xml @@ -1,4 +1,12 @@ - + + + + diff --git a/android/app/src/main/res/drawable/ic_route_planning_metro.xml b/android/app/src/main/res/drawable/ic_route_planning_metro.xml new file mode 100644 index 000000000..ed9a4b964 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_route_planning_metro.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/android/app/src/main/res/drawable/ic_route_planning_metro_40px.xml b/android/app/src/main/res/drawable/ic_route_planning_metro_40px.xml new file mode 100644 index 000000000..94c6bcdca --- /dev/null +++ b/android/app/src/main/res/drawable/ic_route_planning_metro_40px.xml @@ -0,0 +1,12 @@ + + + + + diff --git a/android/app/src/main/res/drawable/ic_route_planning_monorail.xml b/android/app/src/main/res/drawable/ic_route_planning_monorail.xml new file mode 100644 index 000000000..3e4b12e87 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_route_planning_monorail.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/android/app/src/main/res/drawable/ic_route_planning_train.xml b/android/app/src/main/res/drawable/ic_route_planning_train.xml new file mode 100644 index 000000000..cf8a3b511 --- /dev/null +++ b/android/app/src/main/res/drawable/ic_route_planning_train.xml @@ -0,0 +1,11 @@ + + + + diff --git a/android/app/src/main/res/drawable/route_point_01.xml b/android/app/src/main/res/drawable/route_point_01.xml index f61bca62b..561db952c 100644 --- a/android/app/src/main/res/drawable/route_point_01.xml +++ b/android/app/src/main/res/drawable/route_point_01.xml @@ -11,7 +11,7 @@ - + app:tint="?attr/colorLogo" /> - - - - - - - - - @@ -50,6 +51,7 @@ android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" + android:textAlignment="viewStart" android:textAppearance="@style/MwmTextAppearance.Body1" tools:text="Донецкая область" tools:background="#40FF0000"/> @@ -58,6 +60,7 @@ android:id="@+id/subtitle" android:layout_width="match_parent" android:layout_height="wrap_content" + android:textAlignment="viewStart" android:textAppearance="@style/MwmTextAppearance.Body4" tools:text="Украина" tools:background="#60FFFF00"/> diff --git a/android/app/src/main/res/layout/downloader_status.xml b/android/app/src/main/res/layout/downloader_status.xml index 13b49f8fc..bc8ed9909 100644 --- a/android/app/src/main/res/layout/downloader_status.xml +++ b/android/app/src/main/res/layout/downloader_status.xml @@ -21,5 +21,5 @@ android:layout_height="match_parent" android:scaleType="center" android:background="?clickableBackground" - tools:src="@drawable/downloader_failed"/> + tools:src="@drawable/downloader_update"/> diff --git a/android/app/src/main/res/layout/edit_bookmark_common.xml b/android/app/src/main/res/layout/edit_bookmark_common.xml index 782ccab4e..47f58f170 100644 --- a/android/app/src/main/res/layout/edit_bookmark_common.xml +++ b/android/app/src/main/res/layout/edit_bookmark_common.xml @@ -33,6 +33,7 @@ android:layout_height="wrap_content" android:hint="@string/name" android:padding="@dimen/margin_half_double_plus" + android:textAlignment="viewStart" android:inputType="textCapSentences" android:singleLine="true" /> @@ -50,6 +51,7 @@ android:layout_height="wrap_content" android:layout_marginTop="@dimen/margin_base" android:layout_marginEnd="@dimen/margin_quadruple" + android:layout_marginStart="@dimen/margin_half_plus" android:text="@string/list" android:textAppearance="@style/MwmTextAppearance.Body3" /> + android:inputType="textMultiLine" + android:textAlignment="viewStart" /> diff --git a/android/app/src/main/res/layout/fragment_direction.xml b/android/app/src/main/res/layout/fragment_direction.xml index 1be4b79da..d6f465691 100644 --- a/android/app/src/main/res/layout/fragment_direction.xml +++ b/android/app/src/main/res/layout/fragment_direction.xml @@ -16,7 +16,7 @@ android:layout_marginTop="@dimen/margin_direction_small" app:srcCompat="@drawable/ic_direction_fullscreen"/> - - - - - - - - - - + - + + + \ No newline at end of file diff --git a/android/app/src/main/res/layout/fragment_routing.xml b/android/app/src/main/res/layout/fragment_routing.xml index 29768083b..96c9489c7 100644 --- a/android/app/src/main/res/layout/fragment_routing.xml +++ b/android/app/src/main/res/layout/fragment_routing.xml @@ -23,7 +23,7 @@ layout="@layout/routing_action_panel" android:visibility="gone"/> - + android:buttonTint="?accentColorSelector" + android:padding="@dimen/margin_half" /> diff --git a/android/app/src/main/res/layout/item_localized_name.xml b/android/app/src/main/res/layout/item_localized_name.xml index efcaf3956..66b869bdf 100644 --- a/android/app/src/main/res/layout/item_localized_name.xml +++ b/android/app/src/main/res/layout/item_localized_name.xml @@ -21,7 +21,8 @@ android:hint="@string/editor_edit_place_name_hint" android:inputType="textCapSentences" android:padding="@dimen/margin_base" - android:singleLine="true" /> + android:singleLine="true" + android:textAlignment="viewStart" /> - - - - - - - - - - - - - - - - - - + android:paddingStart="@dimen/margin_base" + android:animateLayoutChanges="true"> - - - + android:layout_gravity="center_vertical" + android:text="@string/cancel" + android:textColor="?android:attr/textColorPrimary" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" />