diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a32ce2e..587516b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,6 +23,10 @@ + + diff --git a/app/src/main/java/com/finnmglas/launcher/FirstStartupActivity.kt b/app/src/main/java/com/finnmglas/launcher/FirstStartupActivity.kt new file mode 100644 index 0000000..d4dfb37 --- /dev/null +++ b/app/src/main/java/com/finnmglas/launcher/FirstStartupActivity.kt @@ -0,0 +1,147 @@ +package com.finnmglas.launcher + +import android.annotation.SuppressLint +import android.content.Context +import android.content.SharedPreferences +import android.os.Bundle +import android.util.TypedValue +import android.view.* +import android.view.animation.AlphaAnimation +import android.view.animation.Animation +import androidx.appcompat.app.AppCompatActivity +import kotlinx.android.synthetic.main.activity_firststartup.* + +// Taken from https://stackoverflow.com/questions/47293269 +fun View.blink( + times: Int = Animation.INFINITE, + duration: Long = 1000L, + offset: Long = 20L, + minAlpha: Float = 0.2f, + maxAlpha: Float = 1.0f, + repeatMode: Int = Animation.REVERSE +) { + startAnimation(AlphaAnimation(minAlpha, maxAlpha).also { + it.duration = duration + it.startOffset = offset + it.repeatMode = repeatMode + it.repeatCount = times + }) +} + +class FirstStartupActivity : AppCompatActivity(){ + + var menuNumber = 0 + var defaultApps = mutableListOf() + + /* Overrides */ + + @SuppressLint("SetTextI18n") // I do not care + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + // Flags + window.setFlags( + WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN + ) + window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON) + + setContentView(R.layout.activity_firststartup) + + continue_text.blink() // animate + loadMenu(this) + } + + fun clickAnywhere(view: View){ + menuNumber++ + loadMenu(this) + } + + override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { + if (keyCode == KeyEvent.KEYCODE_VOLUME_UP){ + menuNumber++ + loadMenu(this) + } + else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_BACK){ + menuNumber-- + + // prevent negative indices + if (menuNumber < 0) menuNumber = 0 + + loadMenu(this) + } + return true + } + + @SuppressLint("SetTextI18n") // I don't care! (Yet) + fun loadMenu(context :Context) { // Context needed for packageManager + + val sharedPref = this.getSharedPreferences( + getString(R.string.preference_file_key), Context.MODE_PRIVATE) + + // Intro + if (menuNumber == 0){ + heading.text = "" + description.text = "Take a few seconds to learn how to use this Launcher!\n\n" + continue_text.text = "-- Tap anywhere to continue --" + + defaultApps = resetSettings(sharedPref, context) // UP, DOWN, RIGHT, LEFT, VOLUME_UP, VOLUME_DOWN + } + // Concept + else if (menuNumber == 1){ + heading.text = "Concept" + description.text = "It is designed to be minimal, efficient and free of distraction." + } + else if (menuNumber == 2){ + heading.text = "Concept" + description.text = "It is free of payments, ads and tracking services." + continue_text.text = "-- Tap anywhere to continue --" + } + // Usage + else if (menuNumber == 3){ + heading.text = "Usage" + description.text = "Your home screen contains the local date and time. No distraction." + continue_text.text = "-- Use volume keys to navigate --" + } + else if (menuNumber == 4){ + heading.text = "Usage" + description.text = "You can open your apps with a single swipe or button press." + } + // Setup + else if (menuNumber == 5){ + heading.text = "Setup" + description.setTextSize(TypedValue.COMPLEX_UNIT_SP,36F) + description.text = "We have set up some default actions for you..." + } + else if (menuNumber == 6){ + description.setTextSize(TypedValue.COMPLEX_UNIT_SP,18F) + description.text = "Swipe Up: Open a Browser (" + defaultApps[0] + ")\n\n" + + "Swipe Down: Open internal Search App (" + defaultApps[1] + ")\n\n" + + "Swipe Right: Open Mail (" + defaultApps[2] + ")\n\n" + + "Swipe Left: Open Calendar (" + defaultApps[3] + ")\n\n" + + "Volume Up: Open a messenger (" + defaultApps[4] + ")\n\n" + + "Volume Down: Open Utilities (" + defaultApps[5] + ")" + } + else if (menuNumber == 7){ + heading.text = "Setup" + description.setTextSize(TypedValue.COMPLEX_UNIT_SP,36F) + description.text = "You can choose your own apps:\n\nOpen settings by tapping and holding the home screen." + continue_text.text = "-- Use volume keys to navigate --" + } + else if (menuNumber == 8){ + heading.text = "" + description.text = "You are ready to get started!\n\n I hope this provides great value to you!\n\n- Finn M Glas\n\n" + continue_text.text = "-- Launcher by Finn M Glas --" + } + // End Intro + else { + val editor: SharedPreferences.Editor = sharedPref.edit() + editor.putBoolean("startedBefore", true) // never run this again + editor.putLong("firstStartup", System.currentTimeMillis() / 1000L) // record first startup timestamp + editor.apply() + + finish() + } + + } +} diff --git a/app/src/main/java/com/finnmglas/launcher/MainActivity.kt b/app/src/main/java/com/finnmglas/launcher/MainActivity.kt index a9cfeac..513fb63 100644 --- a/app/src/main/java/com/finnmglas/launcher/MainActivity.kt +++ b/app/src/main/java/com/finnmglas/launcher/MainActivity.kt @@ -33,7 +33,7 @@ GestureDetector.OnDoubleTapListener { private lateinit var mDetector: GestureDetectorCompat // get device dimensions - val displayMetrics = DisplayMetrics() + private val displayMetrics = DisplayMetrics() private fun getIntent(packageName: String): Intent? { val pm = applicationContext.packageManager @@ -108,7 +108,7 @@ GestureDetector.OnDoubleTapListener { // First Startup if (!sharedPref.getBoolean("startedBefore", false)) - initSettings(sharedPref, this) + startActivity(Intent(this, FirstStartupActivity::class.java)) loadSettings(sharedPref) diff --git a/app/src/main/java/com/finnmglas/launcher/Settings.kt b/app/src/main/java/com/finnmglas/launcher/Settings.kt index cd09e16..7ac5756 100644 --- a/app/src/main/java/com/finnmglas/launcher/Settings.kt +++ b/app/src/main/java/com/finnmglas/launcher/Settings.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.SharedPreferences import android.content.pm.PackageManager +val none_msg = "None found" fun isInstalled(uri: String, context: Context): Boolean { val pm: PackageManager = context.packageManager @@ -15,146 +16,6 @@ fun isInstalled(uri: String, context: Context): Boolean { return false } -fun initSettings(sharedPref : SharedPreferences, context: Context){ - val editor: SharedPreferences.Editor = sharedPref.edit() - editor.putBoolean("startedBefore", true) // never run this again - editor.apply() - - resetSettings(sharedPref, context) -} - -// Some magical default settings are set here ^^ -fun resetSettings(sharedPref : SharedPreferences, context: Context){ - val editor: SharedPreferences.Editor = sharedPref.edit() - - - /* upApp -> Browser */ - - // #1 -> Firefox - if(isInstalled("org.mozilla.firefox", context)) - editor.putString("action_upApp", "org.mozilla.firefox") - - // #2 -> Chrome - else if(isInstalled("com.android.chrome", context)) - editor.putString("action_upApp", "com.android.chrome") - - // #3 -> Samsung Internet - else if(isInstalled("com.sec.android.app.sbrowser", context)) - editor.putString("action_upApp", "com.sec.android.app.sbrowser") - - else - editor.putString("action_upApp", "") - - - /* downApp -> Search Apps */ - - // #1 -> Galaxyfinder -> newer Devices - if(isInstalled("com.samsung.android.app.galaxyfinder", context)) - editor.putString("action_downApp", "com.samsung.android.app.galaxyfinder") - - // #2 -> Speechsearch -> older Devices - else if(isInstalled("com.prometheusinteractive.voice_launcher", context)) - editor.putString("action_downApp", "com.prometheusinteractive.voice_launcher") - - else - editor.putString("action_downApp", "") - - - /* rightApp -> Mail */ - - // #1 -> Web DE Mail -> people having it installed likely want it first - if(isInstalled("de.web.mobile.android.mail", context)) - editor.putString("action_rightApp", "de.web.mobile.android.mail") - - // #2 -> Samsung Mail - else if(isInstalled("com.samsung.android.email.provider", context)) - editor.putString("action_rightApp", "com.samsung.android.email.provider") - - // #3 -> Google Mail - else if(isInstalled("com.google.android.gm", context)) - editor.putString("action_rightApp", "com.google.android.gm") - - else - editor.putString("action_rightApp", "") - - - /* leftApp, calendarApp -> Calendar */ - - // #1 -> Google Calendar - if(isInstalled("com.google.android.calendar", context)){ - editor.putString("action_leftApp", "com.google.android.calendar") - editor.putString("action_calendarApp", "com.google.android.calendar") - } - - // #2 -> Samsung Calendar - else if(isInstalled("com.samsung.android.calendar", context)){ - editor.putString("action_leftApp", "com.samsung.android.calendar") - editor.putString("action_calendarApp", "com.samsung.android.calendar") - } - - else - editor.putString("action_leftApp", "") - - - /* volumeUpApp -> Messenger */ - - // #1 -> Whatsapp - if(isInstalled("com.whatsapp", context)) - editor.putString("action_volumeUpApp", "com.whatsapp") - - // #2 -> FB Messenger - else if(isInstalled("com.facebook.orca", context)) - editor.putString("action_volumeUpApp", "com.facebook.orca") - - // #3 -> Viber - else if(isInstalled("com.viber.voip", context)) - editor.putString("action_volumeUpApp", "com.viber.voip") - - // #4 -> Skype - else if(isInstalled("com.skype.raider", context)) - editor.putString("action_volumeUpApp", "com.skype.raider") - - // #5 -> Snapchat - else if(isInstalled("com.snapchat.android", context)) - editor.putString("action_volumeUpApp", "com.snapchat.android") - - // #6 -> Instagram - else if(isInstalled("com.instagram.android", context)) - editor.putString("action_volumeUpApp", "com.instagram.android") - - // #7 -> SMS - else if(isInstalled("com.samsung.android.messaging", context)) - editor.putString("action_volumeUpApp", "com.samsung.android.messaging") - - else - editor.putString("action_volumeUpApp", "") - - - /* volumeDownApp -> Util */ - - // #1 -> Github App - if(isInstalled("com.github.android", context)) - editor.putString("action_volumeDownApp", "com.github.android") - - // #2 -> Soundbrenner App - else if(isInstalled("com.soundbrenner.pulse", context)) - editor.putString("action_volumeDownApp", "com.soundbrenner.pulse") - - // #3 -> Calculator - else if(isInstalled("com.sec.android.app.popupcalculator", context)) - editor.putString("action_volumeDownApp", "com.sec.android.app.popupcalculator") - - else - editor.putString("action_volumeDownApp", "") - - /* clockApp default */ - editor.putString("action_clockApp", "com.sec.android.app.clockpackage") - - editor.apply() - - // TODO showInfo() -} - fun loadSettings(sharedPref : SharedPreferences){ upApp = sharedPref.getString("action_upApp", "").toString() downApp = sharedPref.getString("action_downApp", "").toString() @@ -165,4 +26,120 @@ fun loadSettings(sharedPref : SharedPreferences){ calendarApp = sharedPref.getString("action_calendarApp", "").toString() clockApp = sharedPref.getString("action_clockApp", "").toString() -} \ No newline at end of file +} + +// Default settings are set here. +fun resetSettings(sharedPref : SharedPreferences, context: Context) : MutableList{ + + val defaultList :MutableList = mutableListOf() + + val editor: SharedPreferences.Editor = sharedPref.edit() + + val (chosenUpName, chosenUpPackage) = pickDefaultUpApp(context) + editor.putString("action_upApp", chosenUpPackage) + defaultList.add(chosenUpName) + + val (chosenDownName, chosenDownPackage) = pickDefaultDownApp(context) + editor.putString("action_downApp", chosenDownPackage) + defaultList.add(chosenDownName) + + val (chosenRightName, chosenRightPackage) = pickDefaultRightApp(context) + editor.putString("action_rightApp", chosenRightPackage) + defaultList.add(chosenRightName) + + val (chosenLeftName, chosenLeftPackage) = pickDefaultLeftApp(context) + editor.putString("action_leftApp", chosenLeftPackage) + editor.putString("action_calendarApp", chosenLeftPackage) + defaultList.add(chosenLeftName) + + val (chosenVolumeUpName, chosenVolumeUpPackage) = pickDefaultVolumeUpApp(context) + editor.putString("action_volumeUpApp", chosenVolumeUpPackage) + defaultList.add(chosenVolumeUpName) + + val (chosenVolumeDownName, chosenVolumeDownPackage) = pickDefaultVolumeDownApp(context) + editor.putString("action_volumeDownApp", chosenVolumeDownPackage) + defaultList.add(chosenVolumeDownName) + + // clockApp default + editor.putString("action_clockApp", "com.sec.android.app.clockpackage") + + editor.apply() + + return defaultList // UP, DOWN, RIGHT, LEFT, VOLUME_UP, VOLUME_DOWN +} + +// Default upApps are Browsers +fun pickDefaultUpApp(context :Context) : Pair{ + if(isInstalled("org.mozilla.firefox", context)) + return Pair("Firefox", "org.mozilla.firefox") + else if(isInstalled("com.android.chrome", context)) + return Pair("Chrome", "com.android.chrome") + else if(isInstalled("com.sec.android.app.sbrowser", context)) + return Pair("Samsung Internet", "com.sec.android.app.sbrowser") + else + return Pair("None, as we were unable to find one.", "") +} + +// Default downApps are Internal Search Apps +fun pickDefaultDownApp(context :Context) : Pair{ + if(isInstalled("com.samsung.android.app.galaxyfinder", context)) + return Pair("GalaxyFinder", "com.samsung.android.app.galaxyfinder") + else if(isInstalled("com.prometheusinteractive.voice_launcher", context)) + return Pair("VoiceSearch", "com.prometheusinteractive.voice_launcher") + else + return Pair(none_msg, "") +} + +// Default rightApps are Mailing Applications +fun pickDefaultRightApp(context :Context) : Pair{ + if(isInstalled("de.web.mobile.android.mail", context)) + return Pair("WebMail", "de.web.mobile.android.mail") + else if(isInstalled("com.samsung.android.email.provider", context)) + return Pair("Samsung Mail", "com.samsung.android.email.provider") + else if(isInstalled("com.google.android.gm", context)) + return Pair("Google Mail", "com.google.android.gm") + else + return Pair(none_msg, "") +} + +// Default leftApps are Calendar Applications +fun pickDefaultLeftApp(context :Context) : Pair{ + if(isInstalled("com.google.android.calendar", context)) + return Pair("Google Calendar", "com.google.android.calendar") + else if(isInstalled("com.samsung.android.calendar", context)) + return Pair("Samsung Calendar", "com.samsung.android.calendar") + else + return Pair(none_msg, "") +} + +// Default volumeUpApps are Messengers +fun pickDefaultVolumeUpApp(context: Context) : Pair{ + if(isInstalled("com.whatsapp", context)) + return Pair("WhatsApp", "com.whatsapp") + else if(isInstalled("com.facebook.orca", context)) + return Pair("Facebook Messenger", "com.facebook.orca") + else if(isInstalled("com.viber.voip", context)) + return Pair("Viber", "com.viber.voip") + else if(isInstalled("com.skype.raider", context)) + return Pair("Skype", "com.skype.raider") + else if(isInstalled("com.snapchat.android", context)) + return Pair("Snapchat", "com.snapchat.android") + else if(isInstalled("com.instagram.android", context)) + return Pair("Instagram", "com.instagram.android") + else if(isInstalled("com.samsung.android.messaging", context)) + return Pair("Samsung SMS", "com.samsung.android.messaging") + else + return Pair(none_msg, "") +} + +// Default volumeDownApps are Utilities +fun pickDefaultVolumeDownApp(context: Context) : Pair{ + if(isInstalled("com.github.android", context)) + return Pair("GitHub", "com.github.android") + else if(isInstalled("com.soundbrenner.pulse", context)) + return Pair("Soundbrenner Metronome", "com.soundbrenner.pulse") + else if(isInstalled("com.sec.android.app.popupcalculator", context)) + return Pair("Calculator", "com.sec.android.app.popupcalculator") + else + return Pair(none_msg, "") +} diff --git a/app/src/main/res/layout/activity_firststartup.xml b/app/src/main/res/layout/activity_firststartup.xml new file mode 100644 index 0000000..c933b6a --- /dev/null +++ b/app/src/main/res/layout/activity_firststartup.xml @@ -0,0 +1,65 @@ + + + + + + + + + \ No newline at end of file