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