{"id":23063669,"url":"https://github.com/sakuexe/mobile-programming-2022","last_synced_at":"2026-04-27T22:32:37.150Z","repository":{"id":129732634,"uuid":"559812320","full_name":"sakuexe/mobile-programming-2022","owner":"sakuexe","description":"HAMK - Mobile Programming Course's assignments, notes and other testings.","archived":false,"fork":false,"pushed_at":"2022-12-15T09:24:28.000Z","size":2693,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-03T08:14:27.950Z","etag":null,"topics":["android","android-studio","compose","hamk","jetpack-compose","kotlin"],"latest_commit_sha":null,"homepage":"","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/sakuexe.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}},"created_at":"2022-10-31T06:24:28.000Z","updated_at":"2022-12-15T09:11:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"fc626764-4eb4-43b2-8a31-0090247ddc10","html_url":"https://github.com/sakuexe/mobile-programming-2022","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sakuexe/mobile-programming-2022","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sakuexe%2Fmobile-programming-2022","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sakuexe%2Fmobile-programming-2022/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sakuexe%2Fmobile-programming-2022/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sakuexe%2Fmobile-programming-2022/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sakuexe","download_url":"https://codeload.github.com/sakuexe/mobile-programming-2022/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sakuexe%2Fmobile-programming-2022/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32358509,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-27T20:07:02.737Z","status":"ssl_error","status_checked_at":"2026-04-27T20:07:00.910Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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-studio","compose","hamk","jetpack-compose","kotlin"],"created_at":"2024-12-16T04:12:40.303Z","updated_at":"2026-04-27T22:32:37.126Z","avatar_url":"https://github.com/sakuexe.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"# **Mobile Programming 2022**\n\n*a.k.a \"Mobiiliohjelmointi 2022\"*\n\nBy **Saku Karttunen**\n\n#### **About**\n\nThis repository includes exercises from the classes and assignments from HAMK Riihimäki's \"Mobile Programming 2022\" -course.\n\n- Teacher and course organizer: **Toni Laitinen**\n- Course duration: **24/10/ - 16/12/2022**\n- Editors used: **Android Studio** and **Visual Studio Code**\n\n## Assignments\n\n#### **1) BMI-calculator part 1/3**\n\nThe program in the main window asks user's height and weight and with these calculates the weight index of the user\nafter pressing the \"Calculate\" button.\n\nThe formula for the BMI was Weight(kg)/(Height(m))^2.\n\n```kotlin\n  userHeight /= 100\n  val bmi = userWeight / (userHeight.pow(2))\n  // Round the answer using .format()\n  // https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/format.html\n  header.text = \"Your BMI is: %.2f\".format(bmi)\n```\n\n#### **2) Acceleration Sensor Ball**\n\n- Implement a ball that the user moves around the screen.\n- Use the acceleration sensors with the drawing examples in the implementation.\n- The ball cannot 'drop' beyond the screen edges.\n\nThis was the first app I built using the [Jetpack Compose](https://developer.android.com/jetpack/compose) technology.\nIt was a great test and I ended up using Compose to build all the next apps (except the second BMI assignment).\n\n```kotlin\n  var x by remember { mutableStateOf(540f) }\n  var y by remember { mutableStateOf(1024f) }\n\n  val sensorManager = LocalContext.current.getSystemService(SENSOR_SERVICE) as SensorManager\n  val mAccelerate : Sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)\n```\n\n*Initalizing the sensorManager with the Acceleration sensor. Also the initial spacing of x and y coordinates*\n\n```kotlin\n  val mAccelerateEventListener = object : SensorEventListener {\n      override fun onSensorChanged(p0: SensorEvent?) {\n        setXY(p0!!.values[0], p0.values[1])\n    }\n```\n\n*Getting the values of the Acceleration sensor and passing them forward*\n\n#### **3) BMI-calculator part 2/3**\n\nIn this assignment the plan was to build on top of the already previously made idea with a couple of new additions.\nFor example the Height of the user is now being saved in a Settings menu. This menu can be opened from the main page.\n\n```kotlin\n  // get sharedPreferences\n  val sharedPref = getDefaultSharedPreferences(this)\n  if (sharedPref != null) {\n    // get value of \"signature\", if no value, assign \"empty\"\n    userHeight = sharedPref.getString(\"height_cm\", \"0.0\")!!\n    username = sharedPref.getString(\"username\", \"Jon Doe\")!!\n  }\n```\n\n*For the height to be remembered even when user leaves and returns to the app, I used SharedPreferences. More specifically the 'DefaultSharedPreferences'*\n\n#### **4) Quiz App**\n\nThe assignment was to make a Quiz Application with a four fragment navigation. Each of the fragments needed to have at least three options.\nThe answer was chosen by clicking the button with the desired answer. The last fragment was meant to show the results of the quiz.\n\nI used Jetpack Compose by Kotlin, so I didn't have a need for fragments, so I made my Quiz App to be a single page application, until\nthe results would come up, where I would have a different page for the results. Compose made this assignment a lot of fun and\nI enjoyed making the layout and the algorithms that counted the right answers.\n\n```kotlin\n  data class Prompts (val question: String, val answers: List\u003cString\u003e, val correctAnswer: String)\n\n  var QuizQuestions = listOf\u003cPrompts\u003e(\n    Prompts(\n        \"Who was the first Formula 1 World Champion?\",\n        listOf(\n            \"Nikki Lauda\",\n            \"Graham Hill\",\n            \"Qiueseppe Farina\",\n            \"Juan Manuel Fangio\"\n        ),\n        \"Qiueseppe Farina\"\n    )\n  )\n```\n\n*I made the prompts into an object, so it would be easier to access the needed data (and having it be easier to read)*\n\n```kotlin\n  val score = intent.getStringArrayListExtra(\"userScore\")\n  val correctAnswers  = intent.getStringArrayListExtra(\"correctAnswers\")\n  var finalResult = 0\n\n  for (index in score!!.indices) {\n      if (score[index] == correctAnswers!![index]) {\n          finalResult += 1\n      }\n  }\n```\n\n*Everytime user chose an answer, the answer got saved and at the end sent with Intent. The correct answers were also sent the same way*\n*Then those two just get compared and the final result gets counted.*\n\nIf I made this quiz app now, I would've made a couple of things differently, for example:\n\n```json\n  {\n    \"question\": \"Who was the first Formula 1 World Champion?\",\n    \"answers\": {\n      { \"answer\": \"Nikki Lauda\", \"score\": 0},\n      { \"answer\": \"Graham Hill\", \"score\": 0},\n      { \"answer\": \"Qiueseppe Farina\", \"score\": 1},\n      { \"answer\": \"Juan Manuel Fangio\", \"score\": 0},\n    }\n  }\n```\n\n*I would've made the answers be in this sort of way where they also include a score.*\n*This would've made counting the score even easier and more flexible, for example if more points were given than 1 or 0*\n\n#### **5) BMI-calculator part 3/3**\n\nThe final assignment, it built on top of the previously learned parts about saving and calculating data in Kotlin.\nIn this assignment the plan was to make three different pages that would have their own uses. These were:\n\n- Home - this would be the Main page where the user would use the calculator by inserting their weight and pressing \"calulate\".\n- History - This would visualize the previously calculated BMIs.\n- Settings - Set the height that is being used in the BMI calculator.\n\nSo the most important and complex part of this assignment was how to use the different pages and how to get the data to transfer between them.\nFor this I used [Android DataStore](https://developer.android.com/topic/libraries/architecture/datastore). This was a good idea, because\nit made using the data between the Composables extremely easy.\n\nFor the navigation I used the Scaffold element. And for saving the history, I had a JSON file where the BMI values got saved into when calculated.\n\n```kotlin\n  class StoreUserData(private val context: Context) {\n    // works as another way of storing user data in the same way as shared preferences\n\n    // to make sure there is only one instance\n    companion object {\n        private val Context.dataStore: DataStore\u003cPreferences\u003e by preferencesDataStore(\"UserHeight\")\n        val USER_HEIGHT_KEY = stringPreferencesKey(\"user_height\")\n    }\n\n    // to get the height\n    val getHeight: Flow\u003cString\u003e = context.dataStore.data\n        .map { preferences -\u003e\n            preferences[USER_HEIGHT_KEY] ?: \"\"\n        }\n\n    // to save the height\n    suspend fun saveHeight(name: String) {\n        context.dataStore.edit { preferences -\u003e\n            preferences[USER_HEIGHT_KEY] = name\n        }\n    }\n  }\n```\n\n*Setting up the DataStore*\n\n```kotlin\n  fun saveToJson(context: Context, bmiValue: String) {\n    // thank you github copilot for this help\n    // first let's assign a variable for the bmi history data\n    val bmiList: MutableList\u003cString\u003e = try {\n        // if there is already a file that returns the data\n        // we will use that as a base\n        returnJsonList(context)\n    } catch (e: Exception) {\n        // if there is no file, let's assign the variable as an empty mutable list\n        mutableListOf()\n    }\n    bmiList.add(bmiValue)\n    val jsonString = Gson().toJson(bmiList)\n    val file = File(context.filesDir, \"bmi-history.json\")\n    val printWriter = PrintWriter(FileWriter(file))\n    printWriter.print(jsonString)\n    printWriter.close()\n  }\n```\n\n*Saving the value of the bmiValue to JSON*\n\n## **Self Review**\n\nFor me it felt like this course helped me a lot to understanding how mobile development happens. And my own work\ngot better during the course. I am now interested to also try programming some apps in Flutter or ReactNative.\n\n#### **About this course**\n\nThis was a great course with a lot of interesting assignments and I apprectiated that I could also do all of the assignments in Compose\nsince it felt more modern and it seemed to give me a good base knowledge of mobile development that I can use to start trying out\nReactNative and Flutter that also have similiar looking syntax to Compose.\n\nI also found myself enjoying mobile development a lot, so I am looking forward to the future where I can hopefully use what I learned\nin a bigger project.\n\n![HAMK-logo](./images/hamk-logo.png)\n![Kotlin-logo](./images/kotlin-logo.png)\n![Jetpack Compose-logo](./images/compose-logo.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsakuexe%2Fmobile-programming-2022","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsakuexe%2Fmobile-programming-2022","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsakuexe%2Fmobile-programming-2022/lists"}