diff --git a/.drone.yml b/.drone.yml
index cfb7155..4ea35a1 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -3,7 +3,7 @@ name: default
steps:
- name: assembleRelease
- image: gradle:jdk8
+ image: nextcloudci/android:android-51
commands:
- gradle assembleRelease
diff --git a/README.md b/README.md
index b72a3f5..42ede7b 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,7 @@
ProjectLaogai is a app to access the timetable and the mensa menu of Hochschule Offenburg.
[](https://f-droid.org/packages/org.mosad.seil0.projectlaogai/)
+[](https://play.google.com/store/apps/details?id=org.mosad.seil0.projectlaogai)
## Features
* check out the mensa menu of this and next week
* access your timetable
@@ -19,4 +20,4 @@ ProjectLaogai is a app to access the timetable and the mensa menu of Hochschule
[](https://www.mosad.xyz/images/Project_Laogai/ProjectLaogai_Settings.png)
[](https://www.mosad.xyz/images/Project_Laogai/ProjectLaogai_Mensa_dark.png)
-ProjectLaogai © 2019 [@Seil0](https://git.mosad.xyz/Seil0), a [mosad](http://www.mosad.xyz) Project
+ProjectLaogai © 2019-2020 [@Seil0](https://git.mosad.xyz/Seil0), a [mosad](http://www.mosad.xyz) Project
diff --git a/app/build.gradle b/app/build.gradle
index c63918f..a634a62 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,7 +1,5 @@
apply plugin: 'com.android.application'
-
apply plugin: 'kotlin-android'
-
apply plugin: 'kotlin-android-extensions'
android {
@@ -12,8 +10,8 @@ android {
applicationId "org.mosad.seil0.projectlaogai"
minSdkVersion 23
targetSdkVersion 29
- versionCode 14
- versionName "0.5.0"
+ versionCode 15
+ versionName "0.5.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "build_time", buildTime()
setProperty("archivesBaseName", "projectlaogai-$versionName")
@@ -49,13 +47,13 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
- implementation 'org.jetbrains.anko:anko-commons:0.10.8'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta2'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta4'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
- implementation 'com.google.android.material:material:1.0.0'
- implementation 'com.google.code.gson:gson:2.8.5'
+ implementation 'com.google.android.material:material:1.1.0'
+ implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.afollestad:aesthetic:1.0.0-beta05'
implementation 'com.afollestad.material-dialogs:core:3.1.1'
implementation 'com.afollestad.material-dialogs:color:3.1.1'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2693fae..93c91fa 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -23,6 +23,9 @@
+
+
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@ import android.nfc.NfcAdapter
import android.nfc.NfcManager
import android.nfc.tech.NfcA
import android.os.Bundle
+import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
@@ -50,10 +51,13 @@ import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.
import org.mosad.seil0.projectlaogai.fragments.*
import kotlin.system.measureTimeMillis
-// TODO save the current fragment to show it when the app is restarted
+/**
+ * TODO save the current fragment to show it when the app is restarted
+ */
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private var activeFragment: Fragment = HomeFragment() // the currently active fragment, home at the start
+ private val className = "MainActivity"
private lateinit var adapter: NfcAdapter
private lateinit var pendingIntent: PendingIntent
@@ -62,6 +66,8 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
private var useNFC = false
override fun onCreate(savedInstanceState: Bundle?) {
+ val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
+
Aesthetic.attach(this)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
@@ -72,11 +78,6 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
initAesthetic()
initForegroundDispatch()
- //init home fragment
- val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()
- fragmentTransaction.replace(R.id.fragment_container, activeFragment)
- fragmentTransaction.commit()
-
val toggle = ActionBarDrawerToggle(
this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close
)
@@ -85,9 +86,17 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
nav_view.setNavigationItemSelectedListener(this)
- // if we get an NFC read intent while the app is closed call readBalance
- if (NfcAdapter.ACTION_TECH_DISCOVERED == intent.action)
- NFCMensaCard.readBalance(intent, this)
+ // based on the inent we get, call readBalance or open a Fragment
+ when (intent.action) {
+ NfcAdapter.ACTION_TECH_DISCOVERED -> NFCMensaCard.readBalance(intent, this)
+ "org.mosad.seil0.projectlaogai.fragments.MensaFragment" -> activeFragment = MensaFragment()
+ "org.mosad.seil0.projectlaogai.fragments.TimeTableFragment" -> activeFragment = TimeTableFragment()
+ "org.mosad.seil0.projectlaogai.fragments.MoodleFragment" -> activeFragment = MoodleFragment()
+ }
+
+ // open the activeFragment, default is the HomeFragment
+ fragmentTransaction.replace(R.id.fragment_container, activeFragment)
+ fragmentTransaction.commit()
}
override fun onNewIntent(intent: Intent) {
@@ -166,7 +175,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
PreferencesController.load(this) // load the settings, must be finished before doing anything else
CacheController(this) // load the cache
}
- println("startup completed in $startupTime ms")
+ Log.i(className, "startup completed in $startupTime ms")
}
private fun initAesthetic() {
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/CacheController.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/CacheController.kt
index 09c6aba..ad9b047 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/CacheController.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/CacheController.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,12 +23,19 @@
package org.mosad.seil0.projectlaogai.controller
import android.content.Context
+import android.util.Log
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.joinAll
+import kotlinx.coroutines.launch
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.cCourse
-import org.mosad.seil0.projectlaogai.hsoparser.*
+import org.mosad.seil0.projectlaogai.hsoparser.Course
+import org.mosad.seil0.projectlaogai.hsoparser.MensaMenu
+import org.mosad.seil0.projectlaogai.hsoparser.TimetableCourseWeek
import java.io.BufferedReader
import java.io.File
import java.io.FileReader
@@ -37,6 +44,7 @@ import kotlin.collections.ArrayList
class CacheController(cont: Context) {
+ private val className = "CacheController"
private val context = cont
init {
@@ -50,8 +58,8 @@ class CacheController(cont: Context) {
// if a) it's monday and the last cache update was on sunday or b) the cache is older than 24hr, update blocking
if ((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) || (currentTime - mensaMenu.meta.updateTime) > 86400) {
- println("update mensa blocking")
- TCoRAPIController.getMensa(context).get()
+ Log.i(className, "update mensa blocking")
+ GlobalScope.launch(Dispatchers.Default) { TCoRAPIController.getMensa(context).join() }
}
// check if we need to update the timetables before displaying them
@@ -59,23 +67,29 @@ class CacheController(cont: Context) {
cal.time = Date(timetables[0].meta.updateTime * 1000)
// if a) it`s monday and the last cache update was not on a sunday or b) the cache is older than 24hr, update blocking
- if((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) || (currentTime - timetables[0].meta.updateTime) > 86400) {
- println("updating timetable after sunday!")
- val jobA = TCoRAPIController.getTimetable(cCourse.courseName, 0, context)
- val jobB = TCoRAPIController.getTimetable(cCourse.courseName, 1, context)
+ if ((currentDay == Calendar.MONDAY && cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) || (currentTime - timetables[0].meta.updateTime) > 86400) {
+ Log.i(className, "updating timetable after sunday!")
- jobA.get()
- jobB.get()
+ GlobalScope.launch(Dispatchers.Default) {
+ val threads = listOf(
+ TCoRAPIController.getTimetable(cCourse.courseName, 0, context),
+ TCoRAPIController.getTimetable(cCourse.courseName, 1, context)
+ )
+ threads.joinAll()
+ }
+
+ TCoRAPIController.getTimetable(cCourse.courseName, 0, context)
+ TCoRAPIController.getTimetable(cCourse.courseName, 1, context)
}
// check if an update is necessary, not blocking
- if(currentTime - PreferencesController.coursesCacheTime > 86400)
+ if (currentTime - PreferencesController.coursesCacheTime > 86400)
TCoRAPIController.getCoursesList(context)
- if(currentTime - PreferencesController.mensaCacheTime > 10800)
+ if (currentTime - PreferencesController.mensaCacheTime > 10800)
TCoRAPIController.getMensa(context)
- if(currentTime - PreferencesController.timetableCacheTime > 10800) {
+ if (currentTime - PreferencesController.timetableCacheTime > 10800) {
TCoRAPIController.getTimetable(cCourse.courseName, 0, context)
TCoRAPIController.getTimetable(cCourse.courseName, 1, context)
}
@@ -97,13 +111,16 @@ class CacheController(cont: Context) {
// make sure the file exists
if (!file.exists())
- TCoRAPIController.getCoursesList(context).get()
+ GlobalScope.launch(Dispatchers.Default) { TCoRAPIController.getCoursesList(context).join() }
val fileReader = FileReader(file)
val bufferedReader = BufferedReader(fileReader)
- val coursesObject = JsonParser().parse(bufferedReader.readLine()).asJsonObject
+ val coursesObject = JsonParser.parseString(bufferedReader.readLine()).asJsonObject
- coursesList = Gson().fromJson(coursesObject.getAsJsonArray("courses"), object : TypeToken>() {}.type)
+ coursesList = Gson().fromJson(
+ coursesObject.getAsJsonArray("courses"),
+ object : TypeToken>() {}.type
+ )
}
/**
@@ -114,13 +131,12 @@ class CacheController(cont: Context) {
val file = File(context.filesDir, "mensa.json")
// make sure the file exists
- if (!file.exists()) {
- TCoRAPIController.getMensa(context).get()
- }
+ if (!file.exists())
+ GlobalScope.launch(Dispatchers.Default) { TCoRAPIController.getMensa(context).join() }
val fileReader = FileReader(file)
val bufferedReader = BufferedReader(fileReader)
- val mensaObject = JsonParser().parse(bufferedReader.readLine()).asJsonObject
+ val mensaObject = JsonParser.parseString(bufferedReader.readLine()).asJsonObject
mensaMenu = GsonBuilder().create().fromJson(mensaObject, MensaMenu().javaClass)
}
@@ -134,12 +150,15 @@ class CacheController(cont: Context) {
val file = File(context.filesDir, "timetable-$courseName-$week.json")
// make sure the file exists
- if (!file.exists())
- TCoRAPIController.getTimetable(courseName, week, context).get()
+ if (!file.exists()) {
+ GlobalScope.launch(Dispatchers.Default) {
+ TCoRAPIController.getTimetable(courseName, week, context).join()
+ }
+ }
val fileReader = FileReader(file)
val bufferedReader = BufferedReader(fileReader)
- val timetableObject = JsonParser().parse(bufferedReader.readLine()).asJsonObject
+ val timetableObject = JsonParser.parseString(bufferedReader.readLine()).asJsonObject
// make sure you add the single weeks in the exact order!
if (timetables.size > week) {
@@ -154,7 +173,7 @@ class CacheController(cont: Context) {
* read coursesList, mensa (current and next week), timetable (current and next week)
* @param courseName the course name (e.g AI1)
*/
- fun readStartCache(courseName: String) {
+ private fun readStartCache(courseName: String) {
readCoursesList(context)
readMensa(context)
readTimetable(courseName, 0, context)
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt
index e3fbb77..c19db0a 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/NFCMensaCard.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -66,7 +66,7 @@ class NFCMensaCard {
lookAtMe(context, data, settings.value).show()
}
} catch (ex: Exception) {
- Log.i(className,"could not connect to tag", ex)
+ Log.w(className,"could not connect to tag", ex)
}
}
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt
index d6a43fa..24c48ab 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/PreferencesController.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,7 +24,6 @@ package org.mosad.seil0.projectlaogai.controller
import android.content.Context
import android.graphics.Color
-import org.jetbrains.anko.defaultSharedPreferences
import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.hsoparser.Course
@@ -46,7 +45,10 @@ class PreferencesController {
// the save function
fun save(context: Context) {
- val sharedPref = context.defaultSharedPreferences
+ val sharedPref = context.getSharedPreferences(
+ context.getString(R.string.preference_file_key),
+ Context.MODE_PRIVATE
+ )
// save the update times (cache)
with (sharedPref.edit()) {
@@ -62,42 +64,89 @@ class PreferencesController {
apply()
}
- // save the course
+ }
+
+ /**
+ * save the course locally
+ */
+ fun saveCourse(context: Context, course: Course) {
+ val sharedPref = context.getSharedPreferences(
+ context.getString(R.string.preference_file_key),
+ Context.MODE_PRIVATE
+ )
+
with (sharedPref.edit()) {
- putString(context.getString(R.string.save_key_course), cCourse.courseName)
- putString(context.getString(R.string.save_key_courseTTLink), cCourse.courseLink)
+ putString(context.getString(R.string.save_key_course), course.courseName)
+ putString(context.getString(R.string.save_key_courseTTLink), course.courseLink)
apply()
}
- // save the primary color
+ cCourse = course
+ }
+
+ /**
+ * save the primary color
+ */
+ fun saveColorPrimary(context: Context, colorPrimary: Int) {
+ val sharedPref = context.getSharedPreferences(
+ context.getString(R.string.preference_file_key),
+ Context.MODE_PRIVATE
+ )
+
with (sharedPref.edit()) {
putInt(context.getString(R.string.save_key_colorPrimary),
- cColorPrimary
+ colorPrimary
)
apply()
}
- // save the accent color
+ cColorPrimary = colorPrimary
+ }
+
+ /**
+ * save the accent color
+ */
+ fun saveColorAccent(context: Context, colorAccent: Int) {
+ val sharedPref = context.getSharedPreferences(
+ context.getString(R.string.preference_file_key),
+ Context.MODE_PRIVATE
+ )
+
with (sharedPref.edit()) {
putInt(context.getString(R.string.save_key_colorAccent),
- cColorAccent
+ colorAccent
)
apply()
}
- // save showBuffet
+ cColorAccent = colorAccent
+ }
+
+ /**
+ * save showBuffet
+ */
+ fun saveShowBuffet(context: Context, showBuffet: Boolean) {
+ val sharedPref = context.getSharedPreferences(
+ context.getString(R.string.preference_file_key),
+ Context.MODE_PRIVATE
+ )
+
with (sharedPref.edit()) {
putBoolean(context.getString(R.string.save_key_showBuffet),
- cShowBuffet
+ showBuffet
)
apply()
}
+ cShowBuffet = showBuffet
}
// the load function
fun load(context: Context) {
- val sharedPref = context.defaultSharedPreferences
+ val sharedPref = context.getSharedPreferences(
+ context.getString(R.string.preference_file_key),
+ Context.MODE_PRIVATE
+ )
// load the update times (cache)
coursesCacheTime = sharedPref.getLong(context.getString(
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/TCoRAPIController.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/TCoRAPIController.kt
index 2d03274..9d90148 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/controller/TCoRAPIController.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/controller/TCoRAPIController.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@ package org.mosad.seil0.projectlaogai.controller
import android.content.Context
import android.util.Log
-import org.jetbrains.anko.doAsync
+import kotlinx.coroutines.*
import org.json.JSONObject
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.coursesCacheTime
import org.mosad.seil0.projectlaogai.controller.PreferencesController.Companion.mensaCacheTime
@@ -44,7 +44,7 @@ class TCoRAPIController {
/**
* get the json object from tcor api and write it as file (cache)
*/
- fun getCoursesList(context: Context) = doAsync {
+ fun getCoursesList(context: Context) = GlobalScope.launch {
try {
val url = URL("$tcorBaseURL/courseList")
val file = File(context.filesDir, "courses.json")
@@ -53,9 +53,11 @@ class TCoRAPIController {
val coursesObject = JSONObject(url.readText()) //JSONObject(inReader.readLine())
// write the json object to a file
- val writer = BufferedWriter(FileWriter(file))
- writer.write(coursesObject.toString())
- writer.close()
+ withContext(Dispatchers.IO) {
+ val writer = BufferedWriter(FileWriter(file))
+ writer.write(coursesObject.toString())
+ writer.close()
+ }
// update cache time
coursesCacheTime = System.currentTimeMillis() / 1000
@@ -69,7 +71,7 @@ class TCoRAPIController {
/**
* get the json object from tcor api and write it as file (cache)
*/
- fun getMensa(context: Context) = doAsync {
+ fun getMensa(context: Context) = GlobalScope.launch {
try {
val url = URL("$tcorBaseURL/mensamenu")
val file = File(context.filesDir, "mensa.json")
@@ -78,9 +80,11 @@ class TCoRAPIController {
val mensaObject = JSONObject(url.readText()) //JSONObject(inReader.readLine())
// write the json object to a file
- val writer = BufferedWriter(FileWriter(file))
- writer.write(mensaObject.toString())
- writer.close()
+ withContext(Dispatchers.IO) {
+ val writer = BufferedWriter(FileWriter(file))
+ writer.write(mensaObject.toString())
+ writer.close()
+ }
// update cache time
mensaCacheTime = System.currentTimeMillis() / 1000
@@ -94,18 +98,20 @@ class TCoRAPIController {
/**
* get the json object from tcor api and write it as file (cache)
*/
- fun getTimetable(courseName: String, week: Int, context: Context) = doAsync {
+ fun getTimetable(courseName: String, week: Int, context: Context) = GlobalScope.launch {
try {
val url = URL("$tcorBaseURL/timetable?courseName=$courseName&week=$week")
val file = File(context.filesDir, "timetable-$courseName-$week.json")
// read data from the API
- val mensaObject = JSONObject(url.readText()) //JSONObject(inReader.readLine())
+ val timetableObject = JSONObject(url.readText()) //JSONObject(inReader.readLine())
// write the json object to a file
- val writer = BufferedWriter(FileWriter(file))
- writer.write(mensaObject.toString())
- writer.close()
+ withContext(Dispatchers.IO) {
+ val writer = BufferedWriter(FileWriter(file))
+ writer.write(timetableObject.toString())
+ writer.close()
+ }
// update cache time
timetableCacheTime = System.currentTimeMillis() / 1000
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt
index 3973212..e58b8de 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/HomeFragment.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,8 +31,10 @@ import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.fragment_home.*
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.mensaMenu
import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.timetables
@@ -54,11 +56,10 @@ class HomeFragment : Fragment() {
private val formatter = SimpleDateFormat("E dd.MM", Locale.getDefault())
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
-
val view: View = inflater.inflate(R.layout.fragment_home, container, false)
- addMensaMenu().get()
- addTimeTable().get()
+ addMensaMenu()
+ addTimeTable()
// Inflate the layout for this fragment
return view
@@ -67,13 +68,13 @@ class HomeFragment : Fragment() {
/**
* add the current mensa meal to the home screens
*/
- private fun addMensaMenu() = doAsync {
+ private fun addMensaMenu() = GlobalScope.launch(Dispatchers.Default) {
var dayMeals: ArrayList
val cal = Calendar.getInstance()
val mensaCardView = DayCardView(context!!)
- uiThread {
+ withContext(Dispatchers.Main) {
if (isAdded) {
if (cal.get(Calendar.HOUR_OF_DAY) < 15) {
@@ -117,9 +118,9 @@ class HomeFragment : Fragment() {
/**
* add the current timetable to the home screen
*/
- private fun addTimeTable() = doAsync {
+ private fun addTimeTable() = GlobalScope.launch(Dispatchers.Default) {
- uiThread {
+ withContext(Dispatchers.Main) {
if (isAdded && timetables.isNotEmpty()) {
try {
@@ -140,7 +141,7 @@ class HomeFragment : Fragment() {
* @param startDayIndex the day index you want to start searching
* @return a DayCardView with all lessons added
*/
- private fun findNextDay(startDayIndex: Int) : DayCardView {
+ private fun findNextDay(startDayIndex: Int): DayCardView {
val dayCardView = DayCardView(context!!)
var dayTimetable: TimetableDay? = null
var dayIndexSearch = startDayIndex
@@ -151,7 +152,7 @@ class HomeFragment : Fragment() {
dayTimetable = timetables[weekIndexSearch].timetable.days[dayIndex]
// some wired calendar magic, calculate the correct date to be shown ((timetable week - current week * 7) + (dayIndex - dayIndex of current week)
- val daysToAdd =(timetables[weekIndexSearch].meta.weekNumberYear - NotRetardedCalendar.getWeekOfYear()) * 7 + (dayIndex - NotRetardedCalendar.getDayOfWeekIndex())
+ val daysToAdd = (timetables[weekIndexSearch].meta.weekNumberYear - NotRetardedCalendar.getWeekOfYear()) * 7 + (dayIndex - NotRetardedCalendar.getDayOfWeekIndex())
dayCardView.addTimetableDay(dayTimetable, daysToAdd)
// if there are no lessons don't show the dayCardView
@@ -179,7 +180,7 @@ class HomeFragment : Fragment() {
noLesson.textSize = 18.0F
noLesson.setTypeface(null, Typeface.BOLD)
noLesson.textAlignment = View.TEXT_ALIGNMENT_CENTER
- noLesson.setPadding(7,7,7,7)
+ noLesson.setPadding(7, 7, 7, 7)
return noLesson
}
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MensaFragment.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MensaFragment.kt
index 771637e..7bbc9d9 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MensaFragment.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MensaFragment.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,8 +28,10 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.fragment_mensa.*
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.CacheController
import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.mensaMenu
@@ -53,12 +55,14 @@ class MensaFragment : Fragment() {
// init actions
refreshAction()
- // add the current week (week starts on sunday)
- val dayCurrent = if(NotRetardedCalendar.getDayOfWeekIndex() == 6) 0 else NotRetardedCalendar.getDayOfWeekIndex()
- addWeek(mensaMenu.currentWeek, dayCurrent).get()
+ GlobalScope.launch(Dispatchers.Default) {
+ val dayCurrent = if(NotRetardedCalendar.getDayOfWeekIndex() == 6) 0 else NotRetardedCalendar.getDayOfWeekIndex()
+ addWeek(mensaMenu.currentWeek, dayCurrent).join()
+
+ // add the next week
+ addWeek(mensaMenu.nextWeek, 0)
+ }
- // add the next week
- addWeek(mensaMenu.nextWeek, 0)
// TODO should we show a info if there is no more food this & next week?
@@ -70,9 +74,9 @@ class MensaFragment : Fragment() {
* @param menusWeek menu of type MensaWeek you want to add
* @param dayStart the first day of the week to add
*/
- private fun addWeek(menusWeek: MensaWeek, dayStart: Int) = doAsync {
+ private fun addWeek(menusWeek: MensaWeek, dayStart: Int) = GlobalScope.launch(Dispatchers.Default) {
- uiThread {
+ withContext(Dispatchers.Main) {
// only add the days dayStart to Fri since the mensa is closed on Sat/Sun
for (dayIndex in dayStart..4) {
@@ -105,8 +109,8 @@ class MensaFragment : Fragment() {
/**
* initialize the refresh action
*/
- private fun refreshAction() = doAsync {
- uiThread {
+ private fun refreshAction() = GlobalScope.launch(Dispatchers.Default) {
+ withContext(Dispatchers.Main) {
// set the refresh listener
refreshLayout_Mensa.setOnRefreshListener {
updateMensaScreen()
@@ -118,18 +122,18 @@ class MensaFragment : Fragment() {
/**
* refresh the mensa cache and update the mensa screen
*/
- private fun updateMensaScreen() = doAsync {
+ private fun updateMensaScreen() = GlobalScope.launch(Dispatchers.Default) {
// update the cache
- TCoRAPIController.getMensa(context!!).get() // blocking since we want the new data
+ TCoRAPIController.getMensa(context!!).join() // blocking since we want the new data
CacheController.readMensa(context!!)
- uiThread {
+ withContext(Dispatchers.Main) {
// remove all menus from the layout
linLayout_Mensa.removeAllViews()
// add the refreshed menus
val dayCurrent = if (NotRetardedCalendar.getDayOfWeekIndex() == 6) 0 else NotRetardedCalendar.getDayOfWeekIndex()
- addWeek(mensaMenu.currentWeek, dayCurrent).get()
+ addWeek(mensaMenu.currentWeek, dayCurrent).join()
// add the next week
addWeek(mensaMenu.nextWeek, 0)
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MoodleFragment.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MoodleFragment.kt
index 920c3a1..7cbde41 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MoodleFragment.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/MoodleFragment.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt
index 50565b9..059f5e9 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/SettingsFragment.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,8 +39,7 @@ import com.afollestad.materialdialogs.list.listItems
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import de.psdev.licensesdialog.LicensesDialog
import kotlinx.android.synthetic.main.fragment_settings.*
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
+import kotlinx.coroutines.*
import org.mosad.seil0.projectlaogai.BuildConfig
import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.CacheController
@@ -54,7 +53,6 @@ import org.mosad.seil0.projectlaogai.controller.TCoRAPIController
import org.mosad.seil0.projectlaogai.hsoparser.DataTypes
import java.util.*
-
/**
* The settings controller class
* contains all needed parts to display and the settings screen
@@ -182,6 +180,7 @@ class SettingsFragment : Fragment() {
2 -> activityTheme(R.style.AppTheme_Black)
else -> activityTheme(R.style.AppTheme_Light)
}
+ apply()
}
}
}
@@ -199,8 +198,7 @@ class SettingsFragment : Fragment() {
apply()
}
- cColorPrimary = color
- PreferencesController.save(context!!)
+ PreferencesController.saveColorPrimary(context!!, color)
}
.positiveButton(R.string.select)
.show()
@@ -217,17 +215,14 @@ class SettingsFragment : Fragment() {
apply()
}
- cColorAccent = color
- PreferencesController.save(context!!)
+ PreferencesController.saveColorAccent(context!!, color)
}
.positiveButton(R.string.select)
.show()
}
switchBuffet.setOnClickListener {
- cShowBuffet = switchBuffet.isChecked
- PreferencesController.save(context!!)
- println(switchBuffet.isChecked)
+ PreferencesController.saveShowBuffet(context!!, switchBuffet.isChecked)
}
}
@@ -248,18 +243,20 @@ class SettingsFragment : Fragment() {
.customView(R.layout.dialog_loading)
dialog.show()
- doAsync {
- cCourse = coursesList[index] // set the course
- PreferencesController.save(context)
+ GlobalScope.launch(Dispatchers.Default) {
+ PreferencesController.saveCourse(context, coursesList[index]) // save the course
// update current & next weeks timetable
- TCoRAPIController.getTimetable(cCourse.courseName, 0, context).get() // blocking since we want the new data
- TCoRAPIController.getTimetable(cCourse.courseName, 1, context).get() // blocking since we want the new data
+ val threads = listOf(
+ TCoRAPIController.getTimetable(cCourse.courseName, 0, context),
+ TCoRAPIController.getTimetable(cCourse.courseName, 1, context)
+ )
+ threads.joinAll() // blocking since we want the new data
CacheController.readTimetable(cCourse.courseName, 0, context)
CacheController.readTimetable(cCourse.courseName, 1, context)
- uiThread {
+ withContext(Dispatchers.Main) {
dialog.dismiss()
txtView_Course.text = cCourse.courseName // update txtView
}
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt
index d4a2dc5..66b9148 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/fragments/TimeTableFragment.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -31,8 +31,7 @@ import androidx.fragment.app.Fragment
import com.afollestad.materialdialogs.MaterialDialog
import com.google.android.material.floatingactionbutton.FloatingActionButton
import kotlinx.android.synthetic.main.fragment_timetable.*
-import org.jetbrains.anko.doAsync
-import org.jetbrains.anko.uiThread
+import kotlinx.coroutines.*
import org.mosad.seil0.projectlaogai.R
import org.mosad.seil0.projectlaogai.controller.CacheController
import org.mosad.seil0.projectlaogai.controller.CacheController.Companion.timetables
@@ -74,16 +73,16 @@ class TimeTableFragment : Fragment() {
/**
* initialize the actions
*/
- private fun initActions() = doAsync {
+ private fun initActions() = GlobalScope.launch(Dispatchers.Default) {
- uiThread {
+ withContext(Dispatchers.Main) {
refreshLayout_Timetable.setOnRefreshListener {
updateTimetableScreen()
}
faBtnAddLesson.setOnClickListener {
MaterialDialog(context!!)
- .title(text = "Vorlesung hinzufügen")
+ .title(text = resources.getString(R.string.add_lesson))
.message(text = "wähle einen Studiengang aus:\n\nWähle eine Vorlesung aus: \n\n Diese Funktion ist noch nicht verfügbar")
.show()
}
@@ -104,18 +103,18 @@ class TimeTableFragment : Fragment() {
/**
* add the current and next weeks lessons
*/
- private fun addInitWeeks() = doAsync {
+ private fun addInitWeeks() = GlobalScope.launch(Dispatchers.Default) {
val currentDayIndex = NotRetardedCalendar.getDayOfWeekIndex()
- addWeek(currentDayIndex, 5, 0).get() // add current week
+ addWeek(currentDayIndex, 5, 0).join() // add current week
addWeek(0, currentDayIndex - 1, 1) // add next week
}
- private fun addWeek(startDayIndex: Int, dayEndIndex: Int, weekIndex: Int) = doAsync {
+ private fun addWeek(startDayIndex: Int, dayEndIndex: Int, weekIndex: Int) = GlobalScope.launch(Dispatchers.Default) {
val timetable = timetables[weekIndex].timetable
val timetableMeta = timetables[weekIndex].meta
- uiThread {
+ withContext(Dispatchers.Main) {
for (dayIndex in startDayIndex..dayEndIndex) {
val dayCardView = DayCardView(context!!)
@@ -132,15 +131,18 @@ class TimeTableFragment : Fragment() {
}
}
- private fun updateTimetableScreen() = doAsync {
+ private fun updateTimetableScreen() = GlobalScope.launch(Dispatchers.Default) {
// update the cache
- TCoRAPIController.getTimetable(cCourse.courseName, 0, context!!).get() // blocking since we want the new data
- TCoRAPIController.getTimetable(cCourse.courseName, 1, context!!).get() // blocking since we want the new data
+ val threads = listOf(
+ TCoRAPIController.getTimetable(cCourse.courseName, 0, context!!),
+ TCoRAPIController.getTimetable(cCourse.courseName, 1, context!!)
+ )
+ threads.joinAll() // blocking since we want the new data
CacheController.readTimetable(cCourse.courseName, 0, context!!)
CacheController.readTimetable(cCourse.courseName, 1, context!!)
- uiThread {
+ withContext(Dispatchers.Main) {
// remove all menus from the layout
linLayout_Timetable.removeAllViews()
@@ -148,7 +150,7 @@ class TimeTableFragment : Fragment() {
val dayIndex = NotRetardedCalendar.getDayOfWeekIndex()
// add current week
- addWeek(dayIndex, 5, 0).get()
+ addWeek(dayIndex, 5, 0).join()
// add next week
addWeek(0, dayIndex - 1, 1)
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt
index f3936f3..f1c23f5 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/hsoparser/DataTypes.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/DayCardView.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/DayCardView.kt
index b1e9a95..f1c23c8 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/DayCardView.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/DayCardView.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/LessonLinearLayout.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/LessonLinearLayout.kt
index dd47460..fbb92ba 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/LessonLinearLayout.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/LessonLinearLayout.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/MealLinearLayout.kt b/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/MealLinearLayout.kt
index 233b9fe..3fea220 100644
--- a/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/MealLinearLayout.kt
+++ b/app/src/main/java/org/mosad/seil0/projectlaogai/uicomponents/MealLinearLayout.kt
@@ -1,7 +1,7 @@
/**
* ProjectLaogai
*
- * Copyright 2019
+ * Copyright 2019-2020
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
diff --git a/app/src/main/res/layouts/activities/xml/shortcuts.xml b/app/src/main/res/layouts/activities/xml/shortcuts.xml
new file mode 100644
index 0000000..93efa2c
--- /dev/null
+++ b/app/src/main/res/layouts/activities/xml/shortcuts.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/raw/notices.xml b/app/src/main/res/raw/notices.xml
index 99c8b86..e05c044 100644
--- a/app/src/main/res/raw/notices.xml
+++ b/app/src/main/res/raw/notices.xml
@@ -19,8 +19,8 @@
Apache Software License 2.0
- anko
- https://github.com/Kotlin/anko
+ kotlinx.coroutines
+ https://github.com/Kotlin/kotlinx.coroutines
Copyright JetBrains
Apache Software License 2.0
diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de-rDE/strings.xml
index 64a267b..1a787f2 100644
--- a/app/src/main/res/values-de-rDE/strings.xml
+++ b/app/src/main/res/values-de-rDE/strings.xml
@@ -18,20 +18,23 @@
Diese Woche keine weitere Essensausgabe
heute keine Vorlesung!
+
+ Eine Vorlesung hinzufügen
+
Info
Benutzer
- Tippen, um den Kurs zu ändern
+ Tippe um den Kurs zu ändern
Über
Lizenzen
Design
Hell
Dunkel
Schwarz
- Hauptfarbe
- Die Primärfarbe, Standard ist Schwarz.
+ Primärfarbe
+ Zum Ändern tippen, Standard ist Schwarz.
Akzentfarbe
- Die Akzentfarbe, Standard ist indigo
+ Zum Ändern tippen, Standard ist Indigo.
Buffet immer anzeigen
@@ -47,4 +50,17 @@
Fehler
Stundenplan konnte nicht geladen werden!
+
+ Mensa
+ Mensa
+ Mensa deaktiviert
+
+ Stundenplan
+ Stundenplan
+ Stundenplan deaktiviert
+
+ Moodle
+ Moodle
+ Moodle deaktiviert
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 57efb0b..1a03827 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -20,12 +20,15 @@
No more Food this week
"No lecture today!"
+
+ Add a lesson
+
Info
User
Tap to change course
About
- "This software is made by @Seil0 and is published under the terms and conditions of GPL 3. For further information visit \ngit.mosad.xyz/Seil0/ProjectLaogai \n\n© 2018-2019 seil0@mosad.xyz "
+ "This software is made by @Seil0 and is published under the terms and conditions of GPL 3. For further information visit \ngit.mosad.xyz/Seil0/ProjectLaogai \n\n© 2018-2020 seil0@mosad.xyz "
hso App by @Seil0
Version %1$s (%2$s)
Licenses
@@ -34,9 +37,9 @@
Dark
Black
Primary color
- The primary color, default is black.
+ Tap to change, default is black.
Accent color
- The accent color, default is indigo.
+ Tap to change, default is indigo.
Always show buffet
@@ -59,7 +62,21 @@
Error
Could not load timetable!"
+
+ Mensa
+ Mensa
+ Mensa disabled
+
+ Timetable
+ Timetable
+ Timetable disabled
+
+ Moodle
+ Moodle
+ Moodle disabled
+
+ org.mosad.seil0.projectlaogai_preferences
org.mosad.seil0.projectlaogai.course
org.mosad.seil0.projectlaogai.courseTTLink
org.mosad.seil0.projectlaogai.colorPrimary
diff --git a/build.gradle b/build.gradle
index 8d482e6..81605cb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.3.50'
+ ext.kotlin_version = '1.3.61'
repositories {
google()
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.0'
+ classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
diff --git a/fastlane/metadata/android/en-US/changelogs/15.txt b/fastlane/metadata/android/en-US/changelogs/15.txt
new file mode 100644
index 0000000..39a72bf
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/15.txt
@@ -0,0 +1,5 @@
+This release 0.5.1 is called "artistical Apollon".
+
+* new: it's now possible to use App shortcuts for the timetable, mensa and moodle screen
+* change: updated some libs, updated kotlin to 1.3.61
+* change: the app was updated to use kotlin coroutines instead of anko for asynchronous workloads
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 7c4388a..9492014 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index 8e25e6c..83f2acf 100755
--- a/gradlew
+++ b/gradlew
@@ -125,8 +125,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`