Code Monkey home page Code Monkey logo

ma-sil's Introduction

๋งˆ์‹ค Ma-sil ๐Ÿ‘ต๐Ÿป๐Ÿง“๐Ÿป๐Ÿƒ๐Ÿปโ€โ™€๏ธ๐Ÿƒ๐Ÿป

Promoting walking services to promote physical and mental health and to to interact with people through walking missions.

Overview

Duration : 2020.12.28 ~ 2021.03.31 โฐ

Team member ๐Ÿ’๐Ÿปโ€โ™€๏ธ๐Ÿ’๐Ÿป

  • Designer : ์ดํ˜„์Šน(Hyunseung Lee), ์ตœ์ง€์›(Jiwon Choi)
  • Developer : ์ด์†Œ์—ฐ(Soyeon Lee), ์ตœ๋‹คํ•จ(Daham Choi)

Technology of Use ๐Ÿ’ป

  • Android
  • Kotlin
  • Firebase
  • Google Cloud Platform

Key Features ๐Ÿ’ก

  • Senior-oriented UX/UI
  • Personalized walking routes recommendation system for senior citizens using their health data and real-time location
  • Sharing routes with nearby users

Development Part

This part explains the technical structure and design of this app.

Work Flow

ํ”„๋ ˆ์  ํ…Œ์ด์…˜1


FireStore Structure

firebase

In the case of Image Path and User_thumbnail_path, FireStorage URL information is included, and the ImageURL is retrieved from within the app and displayed in the ImageView.

location contains information about locations that can be selected as a walking spot. The type contains information on the type of mission such as walk, fast walk, drink coffee, etc., and the name of the location that can be connected to the link.

share contains walking sharing data that can be checked in the neighborhood tab. User's personal information (age, gender...), user's walking record, and today's mission list are included in user. By using the time(Timestamp) and time_second of history, a query is requested to the fit api to load biometric data in real time.


Default App Architecture Design Overview

MVVM The overall structure of this app is taken from the login activity that exists in the android template. Based on the template, the structure was modified by using lambda expressions to request data from firebase and update live data.
In addition, there were unique values (firestorageurl, google fit value) that had to be found by referring to the data in Firebase, which was unavoidably implemented in a double callback method in the datasource, and then compared the size of the document to determine the end point. did.


Example)


AchievementForm

data class AchievementForm(  
    val totalSteps: Long? = null,  
    ...
)

Fragment

private lateinit var achievementViewModel: AchievementViewModel

achievementViewModel.achievementForm.observe(viewLifecycleOwner, Observer {
	...
})

ViewModel

class AchievementViewModel(private val achievementRepository: AchievementRepository) : ViewModel() {

    private val _achievementForm = MutableLiveData<AchievementForm>()  
    val achievementForm: LiveData<AchievementForm> = _achievementForm
    ...
    fun findAllHistory(context: Context) {  
        achievementRepository.findAllHistory(context) {  
      if (it is Result.Success) {  
                _achievementHistoryForm.value = it.data  
            }  
        }  
    }
    ...
}

AchievementRepository

class AchievementRepository(val dataSource: AchievementDataSource) {
	...
	fun findAllHistory(context: Context, result: (Result<AchievementHistoryForm>) -> Unit) {  
        dataSource.findAllHistory(context, fitnessOptions, result)  
    }  
    ...
}

AchievementHistory

class AchievementDataSource {
    fun findAllHistory(  
        context: Context,  
        fitnessOptions: FitnessOptions,  
        result: (Result<AchievementHistoryForm>) -> Unit  
    ) {  
        Firebase.firestore  
	        .collection("users")  
            .document(UserInfo.getInstance().uid)  
            .collection("history")  
            .get()  
            .addOnSuccessListener { querySnapshot ->
            ...
            result(Result.Success(AchievementHistoryForm(...)))
            ...
	    }
    }

AchievementViewModelFactory

class AchievementViewModelFactory : ViewModelProvider.Factory {  
    @Suppress("UNCHECKED_CAST")  
    override fun <T : ViewModel> create(modelClass: Class<T>): T {  
        if (modelClass.isAssignableFrom(AchievementViewModel::class.java)) {  
            return AchievementViewModel(  
                achievementRepository = AchievementRepository(  
                    dataSource = AchievementDataSource()  
                )  
            ) as T  
	    }  
        throw IllegalArgumentException("Unkown ViewModel class")  
    }  
}

Description of Activity/Fragment

Mission Fragment

  • First, the user -> today_mission collection is read from Firebase and the mission information is saved as a list in the repository. When all today_mission information is read, the first index value is read, the location -> image collection is read, and the image in firestorage is retrieved using the firestore path information.
  • When the mission fragment is executed, it requests weather information and stores the value in the missionstartdialog. (Uses OpenWeather API - RetrofitClient)
  • If you press the start button, missionstartdialog is displayed, and comments and weather information according to the current time and weather are displayed.
  • Yes, I did. If you click, the currently selected mission information is stored in the intent and sent to domissionactivity, and domissionactivty is executed.



Achievement Fragment

  • First, get all historty information in the user -> history collection.
  • By using the time in history, google fit's historyclient is called to get the biometric data of the time zone that the mission was performed.
  • By using the location information of history, the google map is zoomed to the location through geocoding of the google map api, and the location where the mission was executed is shown in mapview.
  • When all the history information is read, statistics are obtained by properly classifying the information by time when the today, weekly, monthely, and yearly tabs are clicked.
  • Click on the history card to launch the history activity to view more detailed information.


History Activity

  • Place the value from the achievement fragment into the ui properly.
  • Using the location information received from the achievement fragment, the information of the user who completed this mission in the location -> done_users collection is retrieved. And it uses that information to generate statistics and place it in the ui appropriately.


Neighborhood Fragment

  • First, we get all the information in the share collection. (It should be modified so that it can be imported sequentially by selecting appropriately according to the location information.)
  • When all the information is brought, a layout is dynamically created based on that information and added to the scrollview.


Information Fragment

  • Badge feature has not yet been implemented


DoMissionActivity

  • Starts a timer that runs every second in ViewModel.
  • Whenever the timer runs, it calls google fit api historyclient based on the mission start time to get and update mph/mile/kcal information.
  • Clicking the camera icon calls the ACTION_IMAGE_CAPTURE Intent, saves the picture taken in the local storage, stores the location in the Repository, and sends it to the FinishMissionActivity after the mission ends.
  • Clicking the map icon runs mapActivity that shows the current location.
  • Clicking the pause icon stops the timer.


FinishMissionActivity

  • Click the share your route button to go to shareactivity.
  • Clicking the end the mission button saves the location information received from domissionactivity, the difficulty level selected from finishmissionactivity, and the current time in users -> history collection.


ShareActivity

  • It updates the list of my photos using the file path of the photos taken from domissionactivity.
  • When you click the upload button, the photo is saved in firestorage and the url, catpion, and location route information are saved in the share collection.

ma-sil's People

Contributors

dahamchoi avatar lee-soyeon avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.