{"id":50729108,"url":"https://github.com/dettinjo/myfavlocation","last_synced_at":"2026-06-10T07:01:48.599Z","repository":{"id":362261370,"uuid":"919144208","full_name":"dettinjo/myFavLocation","owner":"dettinjo","description":null,"archived":false,"fork":false,"pushed_at":"2026-06-03T09:48:29.000Z","size":407,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-03T11:22:31.845Z","etag":null,"topics":["android","android-jetpack","google-maps","kotlin","mvvm","portfolio","retrofit"],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dettinjo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-19T20:09:39.000Z","updated_at":"2026-06-03T09:48:37.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dettinjo/myFavLocation","commit_stats":null,"previous_names":["dettinjo/myfavlocation"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dettinjo/myFavLocation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dettinjo%2FmyFavLocation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dettinjo%2FmyFavLocation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dettinjo%2FmyFavLocation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dettinjo%2FmyFavLocation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dettinjo","download_url":"https://codeload.github.com/dettinjo/myFavLocation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dettinjo%2FmyFavLocation/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34140776,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-10T02:00:07.152Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","android-jetpack","google-maps","kotlin","mvvm","portfolio","retrofit"],"created_at":"2026-06-10T07:01:45.991Z","updated_at":"2026-06-10T07:01:48.583Z","avatar_url":"https://github.com/dettinjo.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- Improved compatibility of back to top link: See: https://github.com/othneildrew/Best-README-Template/pull/73 --\u003e\n\u003ca id=\"readme-top\"\u003e\u003c/a\u003e\n\n\n\u003c!-- PROJECT LOGO --\u003e\n\u003cbr /\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"#\"\u003e\n    \u003cimg src=\"app/src/main/res/mipmap-xxxhdpi/ic_launcher.png\" alt=\"Logo\" width=\"200\" height=\"200\"\u003e\n  \u003c/a\u003e\n\n  \u003ch3 align=\"center\"\u003eMyFavLocation - Android Application\u003c/h3\u003e\n\n  \u003cp align=\"center\"\u003e\n    An Android application to discover, save, and create your favorite locations.\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    Project for the course 119310 Mobile Application Development at the Media University Stuttgart.\n  \u003c/p\u003e\n\u003c/div\u003e\n\n\n\n\u003c!-- TABLE OF CONTENTS --\u003e\n\u003cdetails\u003e\n  \u003csummary\u003eTable of Contents\u003c/summary\u003e\n  \u003col\u003e\n    \u003cli\u003e\n      \u003ca href=\"#about-the-project\"\u003eAbout The Project\u003c/a\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#built-with\"\u003eBuilt With\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\n      \u003ca href=\"#getting-started\"\u003eGetting Started\u003c/a\u003e\n      \u003cul\u003e\n        \u003cli\u003e\u003ca href=\"#prerequisites\"\u003ePrerequisites\u003c/a\u003e\u003c/li\u003e\n        \u003cli\u003e\u003ca href=\"#installation\"\u003eInstallation\u003c/a\u003e\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#usage\"\u003eUsage\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#software-architecture\"\u003eSoftware Architecture\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#still-left-open\"\u003eStill Left Open\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contributing\"\u003eContributing\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#license\"\u003eLicense\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#contact\"\u003eContact\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"#acknowledgments\"\u003eAcknowledgments\u003c/a\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/details\u003e\n\n\n\n\u003c!-- ABOUT THE PROJECT --\u003e\n## About The Project\n\nThe application lets you explore the world around you, constantly showing you all locations around you (fetched from the Google Places API). You can store these locations as favorites of yours on your phone and look up information about them.\n\nYou can also create your own favorite locations, for which you need to take a picture, give them a name, description, category etc. These will be stored with your current coordinates on your phone.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n### Built With\n\nThis project was built using a modern Android development stack, focusing on a clean and scalable architecture.\n\n*   [Kotlin](https://kotlinlang.org/)\n*   [AndroidX Libraries](https://developer.android.com/jetpack/androidx) (AppCompat, Core KTX, Lifecycle, Navigation)\n*   [MVVM Architecture](https://developer.android.com/jetpack/guide)\n*   [Google Places API](https://developers.google.com/maps/documentation/places/web-service/overview)\n*   [Room Persistence Library](https://developer.android.com/training/data-storage/room)\n*   [Retrofit 2](https://square.github.io/retrofit/)\n*   [Glide](https://github.com/bumptech/glide)\n*   [Material Components for Android](https://material.io/develop/android/docs/getting-started)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n\u003c!-- GETTING STARTED --\u003e\n## Getting Started\n\nTo get a local copy up and running follow these simple steps.\n\n### Prerequisites\n\n*   Android Studio IDE\n*   An Android device or emulator with API level 26 or higher\n\n### Installation\n\n1.  **Get a Google Places API Key**\n    You will need a valid API key for the Google Places API and Google Static Maps API. You can get one from the [Google Cloud Console](https://console.cloud.google.com/).\n2.  **Clone the repo**\n    ```sh\n    git clone https://github.com/your_username/MyFavLocation.git\n    ```\n3.  **Enter your API Key**\n    Open the file `app/src/main/java/de/hdm_stuttgart/myfavlocation/backend/data/Constants.kt` and replace the placeholder key with your own:\n    ```kotlin\n    const val PLACES_API_KEY = \"YOUR_API_KEY_HERE\"\n    ```\n4.  **Open in Android Studio**\n    Open the cloned project directory in Android Studio. It will automatically sync the Gradle dependencies.\n5.  **Run the app**\n    Build and run the application on your Android device or emulator.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n\u003c!-- USAGE EXAMPLES --\u003e\n## Usage\n\n*   **Home Screen**: Upon launching, the app requests location permissions and then displays a list of interesting places nearby fetched from the Google Places API. This list automatically refreshes every 30 seconds.\n*   **Add New Location**: Use the floating action button to open the camera, take a picture of a new location, and then add details like a name, description, category, and rating. The app will save it with your current GPS coordinates.\n*   **Search**: Navigate to the search tab to find specific locations by name. The app will query both the Google Places API and your local database of favorite places.\n*   **Favorites**: The favorites tab shows a list of all the locations you have saved, either from nearby suggestions or ones you created yourself.\n*   **Location Details**: Tapping on any location in a list will open a detail view with its image, map, rating, description, and proximity. For your own created locations, you can edit these details. You can also add a location to your favorites or remove it from this screen.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n\u003c!-- ROADMAP --\u003e\n## Software Architecture\n\nWe designed our App using the **MVVM (Model-View-ViewModel)** architectural pattern.\n\n### 2.1. Basic Structure\n\n#### 2.1.1. Frontend\nThe frontend consists of the **Views** (Activities and Fragments) and of the **ViewModels**. As usual in MVVM, the views don't contain any logic themselves and only listen to updates in the `LiveData` objects that are stored in the ViewModel classes. The ViewModels can then communicate with the backend and fetch data from there.\n\n#### 2.1.2. Backend / Repositories\nThere exists a persistent, lifecycle-independent repository for each of the fragments and activities in the application, as well as so-called **Master-Repositories**, that manage backend-activity such as **API-calls**, **DatabaseAccess**, and **GPS**.\n\n### 2.2. Key Features\n\n#### 2.2.1. Service Manager\nDue to permissions being requested at runtime, we need a convenient way for all the repositories to get the information, which permission has and which hasn't been granted. This is the job of the `ServiceManager`. Repositories can register themselves with the `ServiceDependent` Interface and get notified whenever some permissions change.\n\n#### 2.2.2. Injector Utils\nThere are a lot of dependencies going on in an MVVM architecture. It is very convenient to handle all of these dependencies in a central place, so changes to the architecture will only affect this class. Also, with this scheme, you can easily provide mock-data, so you don't have to test your application with the data stored in the local DB.\n\n#### 2.2.3. DataCaches\nWe use Datacaches in order to avoid unnecessarily calling the API and the local DB all the time.\n\n#### 2.2.4. Communication Infrastructure\nAnother minor issue in the project is the communication between all the different parts of the program. Traversing vertically along our UML was really easily done using MVVM, since most classes have a direct dependency to their lower-level counterparts and thus communication via method calls and return types was easy to do.\n\nHowever, there is still a lot of communication that either needs to happen asynchronously (such as Database or HTTP-API calls) and also communication between the different repositories. This can all happen via callbacks, but the more communication is required, the less readable the code becomes.\n\nCurrently, we are using callback-interfaces for both the Google Places API and for our local DB, as well as a third interface for parameterless general-purpose communication between different parts of the application.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n## Still Left Open\n\n### 3.1. Kotlin Coroutines\nUnfortunately, we weren't able to implement our database-access using Kotlin Coroutines. Multiple asynchronous database-accesses always led to lost updates in one form or another. Also, in terms of displaying the data in an asynchronous way was many times more complicated, since we wanted all our data to be displayed in a deterministic order. We would need to use multiple buffers for the different chunks of data and then concatenate them in our specified order, once all database-calls were completed. We unfortunately weren't yet able to implement this scheme.\n\n### 3.2. Cache Tracking / Image Caching\nThe way we interact with the API is to call once for a list of locations, then generate the URLs for the images and load them separately with Glide. Currently, only the initial request is cached, while images will be retrieved every time the user switches fragments. This can lead to high data consumption, which is why it would be very convenient to cache the images somewhere and only update changes.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\u003c!-- CONTRIBUTING --\u003e\n## Contributing\n\nContributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.\n\nIf you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag \"enhancement\".\nDon't forget to give the project a star! Thanks again!\n\n1.  Fork the Project\n2.  Create your Feature Branch (`git checkout -b feature/AmazingFeature`)\n3.  Commit your Changes (`git commit -m 'Add some AmazingFeature'`)\n4.  Push to the Branch (`git push origin feature/AmazingFeature`)\n5.  Open a Pull Request\n\n### Original Contributors:\n\n*   Joel Dettinger (jd087)\n*   Sven Walter (sw201)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n\u003c!-- LICENSE --\u003e\n## License\n\nDistributed under the MIT License. See `LICENSE.txt` for more information.\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n\u003c!-- CONTACT --\u003e\n## Contact\n\nJoel Dettinger - jd087@hdm-stuttgart.de\n\nSven Walter - sw201@hdm-stuttgart.de\n\nProject Link: [https://github.com/dettinjo/MyFavLocation](https://github.com/your_username/MyFavLocation)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n\n\n\n\u003c!-- ACKNOWLEDGMENTS --\u003e\n## Acknowledgments\n\n*   This project was created as part of the course **119310 Mobile Application Development** at the Media University Stuttgart (Hochschule der Medien).\n*   README template adapted from [Best-README-Template](https://github.com/othneildrew/Best-README-Template)\n\n\u003cp align=\"right\"\u003e(\u003ca href=\"#readme-top\"\u003eback to top\u003c/a\u003e)\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdettinjo%2Fmyfavlocation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdettinjo%2Fmyfavlocation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdettinjo%2Fmyfavlocation/lists"}