diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7d98f90..1d5250d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -23,10 +23,10 @@
-
-
-
-
+
+
diff --git a/app/src/main/java/com/finnmglas/launcher/ChooseActivity.kt b/app/src/main/java/com/finnmglas/launcher/ChooseActivity.kt
index 6215afb..ee64b1e 100644
--- a/app/src/main/java/com/finnmglas/launcher/ChooseActivity.kt
+++ b/app/src/main/java/com/finnmglas/launcher/ChooseActivity.kt
@@ -2,9 +2,9 @@ package com.finnmglas.launcher
import android.annotation.SuppressLint
import android.content.Intent
-import android.content.pm.ApplicationInfo
import android.graphics.Color
import android.os.Bundle
+import android.view.View
import android.view.WindowManager
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
@@ -13,44 +13,8 @@ import kotlinx.android.synthetic.main.activity_choose.*
class ChooseActivity : AppCompatActivity() {
- private fun listApps() {
- val mainIntent = Intent(Intent.ACTION_MAIN, null)
- mainIntent.addCategory(Intent.CATEGORY_LAUNCHER)
-
- val pm = packageManager
- val apps = pm.getInstalledApplications(0)
-
- val installedApps: MutableList = ArrayList()
-
- // list
- for (app in apps) {
-
- if (app.flags and ApplicationInfo.FLAG_UPDATED_SYSTEM_APP != 0) {
- //checks for flags; if flagged, check if updated system app
- installedApps.add(app)
- } else if (app.flags and ApplicationInfo.FLAG_SYSTEM != 0) {
- //it's a system app, not interested
- } else {
- //in this case, it should be a user-installed app
- installedApps.add(app)
- }
- }
-
- // ui
- for (app in installedApps) {
- //packageInfo.sourceDir
- pm.getLaunchIntentForPackage(app.packageName)
-
- // creating TextView programmatically
- val tvdynamic = TextView(this)
- tvdynamic.textSize = 20f
- tvdynamic.text = app.loadLabel(pm).toString()
- tvdynamic.setTextColor(Color.parseColor("#cccccc"))
-
- tvdynamic.setOnClickListener { startActivity(pm.getLaunchIntentForPackage(app.packageName)) }
-
- apps_list.addView(tvdynamic)
- }
+ fun backHome(view: View) {
+ finish()
}
@SuppressLint("SetTextI18n") // I do not care
@@ -61,6 +25,51 @@ class ChooseActivity : AppCompatActivity() {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
setContentView(R.layout.activity_choose)
- listApps()
+
+ val bundle = intent.extras
+ val action = bundle!!.getString("action") // why choose an app
+ val forApp = bundle.getString("forApp") // which app we choose
+
+ /* Build Layout */
+
+ // TODO: Make this more efficient, faster, generate the list before
+
+ val mainIntent = Intent(Intent.ACTION_MAIN, null)
+ mainIntent.addCategory(Intent.CATEGORY_LAUNCHER)
+
+ val pm = packageManager
+ val i = Intent(Intent.ACTION_MAIN)
+ i.addCategory(Intent.CATEGORY_LAUNCHER)
+ val apps = pm.queryIntentActivities(i, 0)
+
+ apps.sortBy { it.activityInfo.loadLabel(pm).toString() }
+
+ for (resolveInfo in apps) {
+ val app = resolveInfo.activityInfo
+ pm.getLaunchIntentForPackage(app.packageName)
+
+ // creating TextView programmatically
+ val tvdynamic = TextView(this)
+ tvdynamic.textSize = 24f
+ tvdynamic.text = app.loadLabel(pm).toString()
+ tvdynamic.setTextColor(Color.parseColor("#cccccc"))
+
+ if (action == "run"){
+ tvdynamic.setOnClickListener { startActivity(pm.getLaunchIntentForPackage(app.packageName)) }
+ }
+ else if (action == "pick"){
+ tvdynamic.setOnClickListener {
+ val returnIntent = Intent()
+ returnIntent.putExtra("value", app.packageName)
+ returnIntent.putExtra("forApp", forApp)
+ setResult(
+ 5000,
+ returnIntent
+ )
+ finish()
+ }
+ }
+ apps_list.addView(tvdynamic)
+ }
}
}
diff --git a/app/src/main/java/com/finnmglas/launcher/MainActivity.kt b/app/src/main/java/com/finnmglas/launcher/MainActivity.kt
index 69eb915..ecf0fd3 100644
--- a/app/src/main/java/com/finnmglas/launcher/MainActivity.kt
+++ b/app/src/main/java/com/finnmglas/launcher/MainActivity.kt
@@ -1,135 +1,105 @@
package com.finnmglas.launcher
import android.annotation.SuppressLint
+import android.content.Context
import android.content.Intent
-import android.content.pm.PackageManager
-import android.content.pm.ResolveInfo
+import android.content.SharedPreferences
+import android.content.SharedPreferences.Editor
import android.os.Bundle
import android.util.DisplayMetrics
-import android.view.KeyEvent
-import android.view.MotionEvent
-import android.view.View
-import android.view.WindowManager
-import android.widget.TextView
+import android.view.*
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
-import androidx.core.view.MotionEventCompat
+import androidx.core.view.GestureDetectorCompat
import kotlinx.android.synthetic.main.activity_main.*
-import kotlin.math.abs
import java.text.SimpleDateFormat
import java.util.*
import kotlin.concurrent.fixedRateTimer
+import kotlin.math.abs
+
+// App Launch Actions
+var upApp = ""
+var downApp = ""
+var rightApp = ""
+var leftApp = ""
+var volumeUpApp = ""
+var volumeDownApp = ""
+
+class MainActivity : AppCompatActivity(),
+GestureDetector.OnGestureListener,
+GestureDetector.OnDoubleTapListener {
-class MainActivity : AppCompatActivity() {
+ private lateinit var mDetector: GestureDetectorCompat
+
// get device dimensions
val displayMetrics = DisplayMetrics()
- private fun getIntent(packageName: String) : Intent? {
+ private fun getIntent(packageName: String): Intent? {
val pm = applicationContext.packageManager
- val intent:Intent? = pm.getLaunchIntentForPackage(packageName)
+ val intent: Intent? = pm.getLaunchIntentForPackage(packageName)
intent?.addCategory(Intent.CATEGORY_LAUNCHER)
- return intent;
+ return intent
}
private fun launchApp(packageName: String, fallback: String = "") {
val intent1 = getIntent(packageName)
- if(intent1!=null){
+ if (intent1 != null) {
applicationContext.startActivity(intent1)
- overridePendingTransition(0,0)
+ overridePendingTransition(0, 0)
} else {
val intent2 = getIntent(fallback)
- if(intent2!=null){
+ if (intent2 != null) {
applicationContext.startActivity(intent2)
- overridePendingTransition(0,0)
+ overridePendingTransition(0, 0)
} else {
- Toast.makeText(this, "Package '$packageName' not found.", Toast.LENGTH_SHORT).show()
+ Toast.makeText(
+ this,
+ "Package '$packageName' not found. Change your Settings.",
+ Toast.LENGTH_SHORT
+ ).show()
}
}
}
- fun launchInstagram(v: View){ launchApp("com.instagram.android") }
- fun launchWhatsapp(v: View){ launchApp("com.whatsapp") }
+ fun launchCalendar(v: View) {
+ launchApp("com.google.android.calendar", "com.samsung.android.calendar")
+ }
- fun launchFinder(v: View){ launchApp("com.samsung.android.app.galaxyfinder") }
- fun launchMail(v: View){ launchApp("com.samsung.android.email.provider", "com.google.android.gm") }
- fun launchCalendar(v: View){ launchApp("com.google.android.calendar", "com.samsung.android.calendar") }
- fun launchClock(v: View){ launchApp("com.sec.android.app.clockpackage") }
- fun launchBrowser(v: View){ launchApp("org.mozilla.firefox", "com.sec.android.app.sbrowser") }
+ fun launchClock(v: View) {
+ launchApp("com.sec.android.app.clockpackage")
+ }
- fun launchUpApp() { launchBrowser(container) }
- fun launchDownApp() { launchFinder(container) }
- fun lauchLeftApp() { launchCalendar(container) }
- fun lauchRightApp() { launchMail(container) }
+ fun launchUpApp() {
+ launchApp(upApp)
+ }
+
+ fun launchDownApp() {
+ launchApp(downApp)
+ }
+
+ fun lauchLeftApp() {
+ launchApp(leftApp)
+ }
+
+ fun lauchRightApp() {
+ launchApp(rightApp)
+ }
+
+ fun lauchVolumeUpApp() {
+ launchApp(volumeUpApp)
+ }
- fun lauchVolumeUpApp() { }
fun lauchVolumeDownApp() {
- val intent = Intent(this, ChooseActivity::class.java)
- startActivity(intent)
+ launchApp(volumeDownApp)
}
- // Overrides
-
- var touchX : Float = 0F
- var touchY : Float = 0F
-
- override fun onTouchEvent(event: MotionEvent): Boolean {
-
- return when (MotionEventCompat.getActionMasked(event)) {
- MotionEvent.ACTION_DOWN -> {
- touchX = event.x
- touchY = event.y
- true
- }
- MotionEvent.ACTION_MOVE -> {
- true
- }
- MotionEvent.ACTION_UP -> {
- windowManager.defaultDisplay.getMetrics(displayMetrics)
-
- val width = displayMetrics.widthPixels
- val height = displayMetrics.heightPixels
-
- val diffX = touchX - event.x
- val diffY = touchY - event.y
-
- val strictness = 4 // of direction
-
- // Decide which one to open
-
- if (diffY > height/8
- && abs(diffY) > strictness * abs(diffX))
- launchUpApp()
-
- else if (diffY < -height/8
- && abs(diffY) > strictness * abs(diffX)
- && touchY > 100)
- launchDownApp()
-
- else if (diffX > width/4
- && abs(diffX) > strictness * abs(diffY))
- lauchLeftApp()
-
- else if (diffX < -width/4
- && abs(diffX) > strictness * abs(diffY))
- lauchRightApp()
-
- true
- }
- MotionEvent.ACTION_CANCEL -> {
- true
- }
- MotionEvent.ACTION_OUTSIDE -> {
- true
- }
- else -> super.onTouchEvent(event)
- }
- }
+ /* Overrides */
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
- if (keyCode == KeyEvent.KEYCODE_BACK) { return true }
+ if (keyCode == KeyEvent.KEYCODE_BACK) return true
else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) lauchVolumeUpApp()
else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) lauchVolumeDownApp()
return true
@@ -139,15 +109,27 @@ class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
+ // Preferences
+ val sharedPref = this.getSharedPreferences(
+ getString(R.string.preference_file_key), Context.MODE_PRIVATE)
+
+ // First Startup
+ if (!sharedPref.getBoolean("startedBefore", false))
+ resetSettings(sharedPref)
+
+ loadSettings(sharedPref)
+
+ // Flags
+
+ window.setFlags(
+ WindowManager.LayoutParams.FLAG_FULLSCREEN,
+ WindowManager.LayoutParams.FLAG_FULLSCREEN
+ )
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
val timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
- //dateFormat.timeZone = TimeZone.getTimeZone("GMT")
- //timeFormat.timeZone = TimeZone.getTimeZone("GMT")
-
fixedRateTimer("timer", false, 0L, 1000) {
this@MainActivity.runOnUiThread {
dateView.text = dateFormat.format(Date())
@@ -157,5 +139,85 @@ class MainActivity : AppCompatActivity() {
setContentView(R.layout.activity_main)
+ mDetector = GestureDetectorCompat(this, this)
+ mDetector.setOnDoubleTapListener(this)
}
+
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+ return if (mDetector.onTouchEvent(event)) {
+ true
+ } else {
+ super.onTouchEvent(event)
+ }
+ }
+
+ override fun onDown(event: MotionEvent): Boolean {
+ return true
+ }
+
+ override fun onFling(
+ e1: MotionEvent,
+ e2: MotionEvent,
+ differenceX: Float,
+ differenceY: Float
+ ): Boolean {
+
+ windowManager.defaultDisplay.getMetrics(displayMetrics)
+ val width = displayMetrics.widthPixels
+ val height = displayMetrics.heightPixels
+
+ val diffX = e1.x - e2.x
+ val diffY = e1.y - e2.y
+
+ val strictness = 4 // of direction
+
+ /* Decide for an action */
+
+ if (diffY > height / 8 && abs(diffY) > strictness * abs(diffX)) launchUpApp()
+ // Only open if the swipe was not from the phone edge
+ else if (diffY < -height / 8 && abs(diffY) > strictness * abs(diffX) && e1.y > 100) launchDownApp()
+ else if (diffX > width / 4 && abs(diffX) > strictness * abs(diffY)) lauchLeftApp()
+ else if (diffX < -width / 4 && abs(diffX) > strictness * abs(diffY)) lauchRightApp()
+
+ return true
+ }
+
+ // Open Settings
+ override fun onLongPress(event: MotionEvent) {
+ startActivity(Intent(this, SettingsActivity::class.java))
+ }
+
+ override fun onScroll(
+ e1: MotionEvent,
+ e2: MotionEvent,
+ diffX: Float,
+ diffY: Float
+ ): Boolean {
+ return true
+ }
+
+ override fun onShowPress(event: MotionEvent) {
+
+ }
+
+ override fun onSingleTapUp(event: MotionEvent): Boolean {
+
+ return true
+ }
+
+ override fun onDoubleTap(event: MotionEvent): Boolean {
+
+ return true
+ }
+
+ override fun onDoubleTapEvent(event: MotionEvent): Boolean {
+
+ return true
+ }
+
+ override fun onSingleTapConfirmed(event: MotionEvent): Boolean {
+
+ return true
+ }
+
}
diff --git a/app/src/main/java/com/finnmglas/launcher/Settings.kt b/app/src/main/java/com/finnmglas/launcher/Settings.kt
new file mode 100644
index 0000000..82c9595
--- /dev/null
+++ b/app/src/main/java/com/finnmglas/launcher/Settings.kt
@@ -0,0 +1,27 @@
+package com.finnmglas.launcher
+
+import android.content.SharedPreferences
+
+fun resetSettings(sharedPref : SharedPreferences){
+ val editor: SharedPreferences.Editor = sharedPref.edit()
+
+ // Set Defaults
+ editor.putString("action_upApp", "org.mozilla.firefox")
+ editor.putString("action_downApp", "com.samsung.android.app.galaxyfinder")
+ editor.putString("action_rightApp", "com.samsung.android.email.provider")
+ editor.putString("action_leftApp", "com.google.android.calendar")
+ editor.putString("action_volumeUpApp", "com.whatsapp")
+ editor.putString("action_volumeDownApp", "com.sec.android.app.popupcalculator")
+
+ editor.putBoolean("startedBefore", true) // never run this again
+ editor.apply()
+}
+
+fun loadSettings(sharedPref : SharedPreferences){
+ upApp = sharedPref.getString("action_upApp", "").toString()
+ downApp = sharedPref.getString("action_downApp", "").toString()
+ rightApp = sharedPref.getString("action_rightApp", "").toString()
+ leftApp = sharedPref.getString("action_leftApp", "").toString()
+ volumeUpApp = sharedPref.getString("action_volumeUpApp", "").toString()
+ volumeDownApp = sharedPref.getString("action_volumeDownApp", "").toString()
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/finnmglas/launcher/SettingsActivity.kt b/app/src/main/java/com/finnmglas/launcher/SettingsActivity.kt
new file mode 100644
index 0000000..01ce2d2
--- /dev/null
+++ b/app/src/main/java/com/finnmglas/launcher/SettingsActivity.kt
@@ -0,0 +1,104 @@
+package com.finnmglas.launcher
+
+import android.annotation.SuppressLint
+import android.app.AlertDialog
+import android.content.Context
+import android.content.DialogInterface
+import android.content.Intent
+import android.content.SharedPreferences
+import android.net.Uri
+import android.os.Bundle
+import android.view.View
+import android.view.WindowManager
+import androidx.appcompat.app.AppCompatActivity
+
+
+class SettingsActivity : AppCompatActivity() {
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ if(requestCode == 5000)
+ {
+ val value = data?.getStringExtra("value")
+ val forApp = data?.getStringExtra("forApp") ?: return
+
+ // Save the new App to Preferences
+ val sharedPref = this.getSharedPreferences(
+ getString(R.string.preference_file_key), Context.MODE_PRIVATE)
+
+ val editor :SharedPreferences.Editor = sharedPref.edit()
+ editor.putString("action_$forApp", value.toString())
+ editor.apply()
+
+ // Update running App
+ if (forApp == "downApp") downApp = value.toString()
+ else if (forApp == "upApp") upApp = value.toString()
+ else if (forApp == "leftApp") leftApp = value.toString()
+ else if (forApp == "rightApp") rightApp = value.toString()
+ else if (forApp == "volumeDownApp") volumeDownApp = value.toString()
+ else if (forApp == "volumeUpApp") volumeUpApp = value.toString()
+
+ }
+ else {
+ super.onActivityResult(requestCode, resultCode, data)
+ }
+ }
+
+ fun chooseDownApp(view: View) {chooseApp("downApp")}
+ fun chooseUpApp(view: View) {chooseApp("upApp")}
+ fun chooseLeftApp(view: View) {chooseApp("leftApp")}
+ fun chooseRightApp(view: View) {chooseApp("rightApp")}
+ fun chooseVolumeDownApp(view: View) {chooseApp("volumeDownApp")}
+ fun chooseVolumeUpApp(view: View) {chooseApp("volumeUpApp")}
+
+ fun chooseApp(forAction :String) {
+ val intent = Intent(this, ChooseActivity::class.java)
+ intent.putExtra("action", "pick") // why choose an app
+ intent.putExtra("forApp", forAction) // which app we choose
+ startActivityForResult(intent, 5000)
+ }
+
+ fun openNewTabWindow(urls: String, context : Context) {
+ val uris = Uri.parse(urls)
+ val intents = Intent(Intent.ACTION_VIEW, uris)
+ val b = Bundle()
+ b.putBoolean("new_window", true)
+ intents.putExtras(b)
+ context.startActivity(intents)
+ }
+
+ fun openFinnWebsite(view: View) {
+ openNewTabWindow("https://www.finnmglas.com/", this)
+ }
+
+ fun openGithubRepo(view: View) {
+ openNewTabWindow("https://github.com/finnmglas/Launcher", this)
+ }
+
+ fun backHome(view: View) {
+ finish()
+ }
+
+ // Show a dialog prompting for confirmation
+ fun resetSettingsClick(view: View) {
+ AlertDialog.Builder(this)
+ .setTitle("Reset Settings")
+ .setMessage("This will discard all your App Choices. Sure you want to continue?")
+ .setPositiveButton(android.R.string.yes,
+ DialogInterface.OnClickListener { dialog, which ->
+ resetSettings(this.getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE))
+ finish()
+ })
+ .setNegativeButton(android.R.string.no, null)
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .show()
+ }
+
+ @SuppressLint("SetTextI18n") // I do not care
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)
+ window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
+
+ setContentView(R.layout.activity_settings)
+ }
+}
diff --git a/app/src/main/res/layout/activity_choose.xml b/app/src/main/res/layout/activity_choose.xml
index 21cfda0..5183bf0 100644
--- a/app/src/main/res/layout/activity_choose.xml
+++ b/app/src/main/res/layout/activity_choose.xml
@@ -7,19 +7,33 @@
android:background="?attr/colorPrimaryDark"
tools:context=".ChooseActivity">
+
+
+ app:layout_constraintTop_toTopOf="@id/heading">
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 84c7398..d700028 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -5,6 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorPrimaryDark"
+ android:longClickable="false"
tools:context=".MainActivity">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3687611..91a5eb6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,4 @@
Launcher
+ V3RYR4ND0MK3YCR4P