Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Filip Wiesner
BlackBird
Commits
888c707d
Commit
888c707d
authored
Dec 23, 2018
by
Filip Wiesner
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Widget done
parent
0c32610d
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
197 additions
and
135 deletions
+197
-135
BlackBird/app/src/main/AndroidManifest.xml
BlackBird/app/src/main/AndroidManifest.xml
+49
-44
BlackBird/app/src/main/java/com/cvut/blackbird/BlackBirdAC.kt
...kBird/app/src/main/java/com/cvut/blackbird/BlackBirdAC.kt
+2
-13
BlackBird/app/src/main/java/com/cvut/blackbird/extensions/CoroutineScope.kt
...main/java/com/cvut/blackbird/extensions/CoroutineScope.kt
+10
-0
BlackBird/app/src/main/java/com/cvut/blackbird/extensions/Numbers.kt
...pp/src/main/java/com/cvut/blackbird/extensions/Numbers.kt
+18
-0
BlackBird/app/src/main/java/com/cvut/blackbird/extensions/RxJava.kt
...app/src/main/java/com/cvut/blackbird/extensions/RxJava.kt
+0
-24
BlackBird/app/src/main/java/com/cvut/blackbird/flows/widget/NextEventService.kt
.../java/com/cvut/blackbird/flows/widget/NextEventService.kt
+44
-0
BlackBird/app/src/main/java/com/cvut/blackbird/flows/widget/NextEventWidget.kt
...n/java/com/cvut/blackbird/flows/widget/NextEventWidget.kt
+72
-52
BlackBird/app/src/main/res/layout/next_event_widget.xml
BlackBird/app/src/main/res/layout/next_event_widget.xml
+2
-2
No files found.
BlackBird/app/src/main/AndroidManifest.xml
View file @
888c707d
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
package=
"com.cvut.blackbird"
>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.FOREGROUND_SERVICE"
/>
<application
android:name=
".BlackBirdAC"
android:allowBackup=
"true"
android:icon=
"@drawable/ic_raven"
android:label=
"@string/app_name"
android:supportsRtl=
"true"
android:theme=
"@style/AppTheme"
>
<activity
android:name=
".flows.BlackBirdMain"
>
<nav-graph
android:value=
"@navigation/nav_graph"
/>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
<intent-filter>
<action
android:name=
"android.intent.action.VIEW"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<category
android:name=
"android.intent.category.BROWSABLE"
/>
<data
android:host=
"callback"
android:scheme=
"kosapp"
/>
</intent-filter>
</activity>
<receiver
android:name=
"com.cvut.blackbird.flows.widget.NextEventWidget"
>
<intent-filter>
<action
android:name=
"android.appwidget.action.APPWIDGET_UPDATE"
/>
</intent-filter>
<meta-data
android:name=
"android.appwidget.provider"
android:resource=
"@xml/next_event_widget_info"
/>
</receiver>
</application>
package=
"com.cvut.blackbird"
>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.FOREGROUND_SERVICE"
/>
<application
android:name=
".BlackBirdAC"
android:allowBackup=
"true"
android:icon=
"@drawable/ic_raven"
android:label=
"@string/app_name"
android:supportsRtl=
"true"
android:theme=
"@style/AppTheme"
>
<activity
android:name=
".flows.BlackBirdMain"
>
<nav-graph
android:value=
"@navigation/nav_graph"
/>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
<category
android:name=
"android.intent.category.LAUNCHER"
/>
</intent-filter>
<intent-filter>
<action
android:name=
"android.intent.action.VIEW"
/>
<category
android:name=
"android.intent.category.DEFAULT"
/>
<category
android:name=
"android.intent.category.BROWSABLE"
/>
<data
android:host=
"callback"
android:scheme=
"kosapp"
/>
</intent-filter>
</activity>
<service
android:name=
"com.cvut.blackbird.flows.widget.NextEventService"
android:exported=
"true"
android:enabled=
"true"
/>
<receiver
android:name=
"com.cvut.blackbird.flows.widget.NextEventWidget"
>
<intent-filter>
<action
android:name=
"android.appwidget.action.APPWIDGET_UPDATE"
/>
</intent-filter>
<meta-data
android:name=
"android.appwidget.provider"
android:resource=
"@xml/next_event_widget_info"
/>
</receiver>
</application>
</manifest>
BlackBird/app/src/main/java/com/cvut/blackbird/BlackBirdAC.kt
View file @
888c707d
package
com.cvut.blackbird
import
android.app.Application
import
android.appwidget.AppWidgetManager
import
android.content.ComponentName
import
android.util.Log
import
androidx.fragment.app.FragmentManager
import
com.chibatching.kotpref.Kotpref
import
com.cvut.blackbird.dinjection.components.ApplicationComponent
import
com.cvut.blackbird.dinjection.components.DaggerApplicationComponent
import
com.cvut.blackbird.dinjection.modules.ServicesModule
import
com.cvut.blackbird.dinjection.modules.RoomModule
import
com.cvut.blackbird.dinjection.modules.ServicesModule
import
net.danlew.android.joda.JodaTimeAndroid
import
androidx.core.view.accessibility.AccessibilityEventCompat.setAction
import
android.content.Intent
import
com.cvut.blackbird.flows.widget.NextEventWidget
class
BlackBirdAC
:
Application
(){
class
BlackBirdAC
:
Application
()
{
companion
object
{
const
val
LOG_TAG
=
"BLACK_BIRD"
//platformStatic allow access it from java code
...
...
@@ -35,11 +30,5 @@ class BlackBirdAC: Application(){
JodaTimeAndroid
.
init
(
this
)
Kotpref
.
init
(
this
)
val
intent
=
Intent
(
this
,
NextEventWidget
::
class
.
java
)
intent
.
action
=
AppWidgetManager
.
ACTION_APPWIDGET_UPDATE
val
ids
=
AppWidgetManager
.
getInstance
(
this
).
getAppWidgetIds
(
ComponentName
(
this
,
NextEventWidget
::
class
.
java
))
intent
.
putExtra
(
AppWidgetManager
.
EXTRA_APPWIDGET_IDS
,
ids
)
sendBroadcast
(
intent
)
}
}
BlackBird/app/src/main/java/com/cvut/blackbird/extensions/CoroutineScope.kt
0 → 100644
View file @
888c707d
package
com.cvut.blackbird.extensions
import
kotlinx.coroutines.CoroutineScope
import
kotlinx.coroutines.Dispatchers
import
kotlinx.coroutines.android.Main
import
kotlinx.coroutines.withContext
suspend
fun
<
T
>
CoroutineScope
.
onMainThread
(
job
:
suspend
CoroutineScope
.()
->
T
)
=
withContext
(
Dispatchers
.
Main
,
job
)
\ No newline at end of file
BlackBird/app/src/main/java/com/cvut/blackbird/extensions/Numbers.kt
View file @
888c707d
...
...
@@ -6,3 +6,21 @@ val density = Resources.getSystem().displayMetrics.density
val
Int
.
dpToPx
:
Int
get
()
=
(
this
*
density
).
toInt
()
val
Float
.
dpToPx
:
Float
get
()
=
this
*
density
fun
Long
.
millisToTimeText
()
=
buildString
{
val
time
=
this
@millisToTimeText
/
1000
/
60
append
(
"in "
)
if
(
time
<
60
)
// Less than a hour
append
(
time
.
toString
()
+
" min"
)
else
if
(
time
<
1440
)
{
// Less than a day
if
(
time
/
60
>
0
)
append
((
time
/
60
).
toString
()
+
" h "
)
if
(
time
%
60
>
0
)
append
((
time
%
60
).
toString
()
+
" min"
)
else
delete
(
length
-
1
,
length
)
}
else
{
append
((
time
/
1440
).
toString
()
+
" d "
)
if
((
time
%
1440
)
/
60
>
0
)
append
(((
time
%
1440
)
/
60
).
toString
()
+
" h"
)
else
delete
(
length
-
1
,
length
)
}
}
BlackBird/app/src/main/java/com/cvut/blackbird/extensions/RxJava.kt
deleted
100644 → 0
View file @
0c32610d
package
com.cvut.blackbird.extensions
//import io.reactivex.Observable
//import io.reactivex.disposables.Disposable
//import io.reactivex.functions.Consumer
//import io.reactivex.schedulers.Schedulers
//import io.reactivex.subjects.BehaviorSubject
//
//
//class Variable<T>(default: T) {
// val subject: BehaviorSubject<T> = BehaviorSubject.createDefault(default)
//
// var value: T
// get() = subject.value!!
// set(value) = subject.onNext(value)
//
// fun subscribe(onNext: Consumer<in T>): Disposable = subject.subscribe(onNext)
//
// fun asObservable(): Observable<T> = subject.subscribeOn(Schedulers.newThread())
//}
//
//infix fun Disposable.disposeTo(bag: MutableList<Disposable>) {
// bag.add(this)
//}
\ No newline at end of file
BlackBird/app/src/main/java/com/cvut/blackbird/flows/widget/NextEventService.kt
0 → 100644
View file @
888c707d
package
com.cvut.blackbird.flows.widget
import
android.app.Service
import
android.appwidget.AppWidgetManager
import
android.content.ComponentName
import
android.content.Intent
import
android.os.IBinder
import
androidx.room.Room
import
com.cvut.blackbird.model.database.BlackBirdDB
import
org.jetbrains.anko.toast
class
NextEventService
:
Service
()
{
override
fun
onStartCommand
(
intent
:
Intent
?,
flags
:
Int
,
startId
:
Int
):
Int
{
sendBroadcast
(
Intent
(
this
,
NextEventWidget
::
class
.
java
).
apply
{
action
=
AppWidgetManager
.
ACTION_APPWIDGET_UPDATE
putExtra
(
AppWidgetManager
.
EXTRA_APPWIDGET_IDS
,
AppWidgetManager
.
getInstance
(
this
@NextEventService
)
.
getAppWidgetIds
(
ComponentName
(
this
@NextEventService
,
NextEventWidget
::
class
.
java
))
)
})
// val db: BlackBirdDB = Room
// .databaseBuilder(this, BlackBirdDB::class.java, "blackbird_DB")
// .fallbackToDestructiveMigration()
// .build()
//
// val appWidgetManager = AppWidgetManager.getInstance(this)
// val allWidgetIds = intent?.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS)
//
// if (allWidgetIds != null) {
// for (appWidgetId in allWidgetIds) {
// NextEventWidget.updateAppWidget(this, appWidgetManager, appWidgetId, db)
// }
// }
// toast("next service RUNNING")
return
super
.
onStartCommand
(
intent
,
flags
,
startId
)
}
override
fun
onBind
(
intent
:
Intent
):
IBinder
?
=
null
}
BlackBird/app/src/main/java/com/cvut/blackbird/flows/widget/NextEventWidget.kt
View file @
888c707d
package
com.cvut.blackbird.flows.widget
import
android.app.AlarmManager
import
android.app.PendingIntent
import
android.appwidget.AppWidgetManager
import
android.appwidget.AppWidgetProvider
import
android.content.ComponentName
import
android.content.Context
import
android.content.Intent
import
android.widget.RemoteViews
import
androidx.room.Room
import
com.cvut.blackbird.R
import
com.cvut.blackbird.extensions.courseAbbr
import
com.cvut.blackbird.extensions.millisToTimeText
import
com.cvut.blackbird.model.database.BlackBirdDB
import
com.cvut.blackbird.model.entities.EventType
import
kotlinx.coroutines.GlobalScope
import
kotlinx.coroutines.
lau
nc
h
import
kotlinx.coroutines.
asy
nc
import
kotlinx.coroutines.runBlocking
import
org.jetbrains.anko.toast
import
org.joda.time.DateTime
import
kotlin.reflect.jvm.jvmName
/**
* Implementation of App Widget functionality.
*/
class
NextEventWidget
:
AppWidgetProvider
()
{
private
var
pendingIntent
:
PendingIntent
?
=
null
override
fun
onUpdate
(
context
:
Context
,
appWidgetManager
:
AppWidgetManager
,
appWidgetIds
:
IntArray
)
{
val
db
:
BlackBirdDB
=
Room
.
databaseBuilder
(
context
,
BlackBirdDB
::
class
.
java
,
"blackbird_DB"
)
.
fallbackToDestructiveMigration
()
.
build
()
// There may be multiple widgets active, so update all of them
for
(
appWidgetId
in
appWidgetIds
)
updateAppWidget
(
context
,
appWidgetManager
,
appWidgetId
,
db
)
}
override
fun
onEnabled
(
context
:
Context
)
{
// Enter relevant functionality for when the first widget is created
}
override
fun
onDisabled
(
context
:
Context
)
{
// Enter relevant functionality for when the last widget is disabled
}
/** STATIC */
companion
object
{
private
const
val
updateInterval
:
Long
=
1000
*
60
internal
fun
updateAppWidget
(
context
:
Context
,
...
...
@@ -51,44 +37,78 @@ class NextEventWidget : AppWidgetProvider() {
database
:
BlackBirdDB
)
{
// Construct the RemoteViews object
context
.
toast
(
""
)
val
views
=
RemoteViews
(
context
.
packageName
,
R
.
layout
.
next_event_widget
)
runBlocking
{
GlobalScope
.
launch
{
val
nextEvent
=
database
.
eventDao
().
nextEvent
()
nextEvent
?.
let
{
val
time
=
(
it
.
event
.
startsAt
.
millis
-
DateTime
.
now
().
millis
)
/
1000
views
.
setTextViewText
(
R
.
id
.
widget_timeLeft
,
time
.
millisToTimeText
())
views
.
setTextViewText
(
R
.
id
.
widget_courseIcon
,
it
.
courseEnt
?.
code
?.
courseAbbr
)
views
.
setInt
(
R
.
id
.
widget_courseIcon
,
"setBackground"
,
when
(
it
.
event
.
eventType
)
{
EventType
.
LECTURE
->
R
.
drawable
.
ic_timetable_lecture
EventType
.
TUTORIAL
->
R
.
drawable
.
ic_timetable_tutorial
else
->
R
.
drawable
.
ic_timetable_info
})
}
}
}
val
event
=
runBlocking
{
GlobalScope
.
async
{
database
.
eventDao
().
nextEvent
()
}.
await
()
}
context
.
toast
(
"Widget ${event?.courseEnt?.code} updated"
)
event
?.
let
{
val
time
=
(
it
.
event
.
startsAt
.
millis
-
DateTime
.
now
().
millis
)
views
.
setTextViewText
(
R
.
id
.
widget_timeLeft
,
time
.
millisToTimeText
())
views
.
setTextViewText
(
R
.
id
.
widget_courseIcon
,
it
.
courseEnt
?.
code
?.
courseAbbr
)
views
.
setInt
(
R
.
id
.
widget_courseIcon
,
"setBackgroundResource"
,
when
(
it
.
event
.
eventType
)
{
EventType
.
LECTURE
->
R
.
drawable
.
ic_timetable_lecture
EventType
.
TUTORIAL
->
R
.
drawable
.
ic_timetable_tutorial
else
->
R
.
drawable
.
ic_timetable_info
})
}
// Instruct the widget manager to update the widget
appWidgetManager
.
updateAppWidget
(
appWidgetId
,
views
)
}
}
}
fun
Long
.
millisToTimeText
()
=
buildString
{
val
time
=
this
@millisToTimeText
append
(
"in "
)
if
(
time
<
60
)
append
(
time
.
toString
()
+
" min"
)
else
{
if
(
time
/
60
>
0
)
append
((
time
/
60
).
toString
()
+
" h "
)
if
(
time
%
60
>
0
)
append
((
time
%
60
).
toString
()
+
" min"
)
else
{
delete
(
length
-
2
,
length
)
append
(
" h"
)
/** HELPER FUNCTIONS */
private
fun
createPending
(
context
:
Context
)
=
Intent
(
context
,
NextEventService
::
class
.
java
).
let
{
PendingIntent
.
getService
(
context
,
0
,
it
,
PendingIntent
.
FLAG_CANCEL_CURRENT
)
}
private
fun
updateInMillis
(
millis
:
Long
,
pendingIntent
:
PendingIntent
,
context
:
Context
)
{
val
alarm
=
context
.
getSystemService
(
Context
.
ALARM_SERVICE
)
as
AlarmManager
alarm
.
set
(
AlarmManager
.
ELAPSED_REALTIME
,
millis
,
pendingIntent
)
}
}
/** OVERRIDDEN METHODS */
override
fun
onUpdate
(
context
:
Context
,
appWidgetManager
:
AppWidgetManager
,
appWidgetIds
:
IntArray
)
{
val
db
:
BlackBirdDB
=
Room
.
databaseBuilder
(
context
,
BlackBirdDB
::
class
.
java
,
"blackbird_DB"
)
.
fallbackToDestructiveMigration
()
.
build
()
// There may be multiple widgets active, so update all of them
for
(
appWidgetId
in
appWidgetIds
)
updateAppWidget
(
context
,
appWidgetManager
,
appWidgetId
,
db
)
if
(
pendingIntent
==
null
)
pendingIntent
=
createPending
(
context
)
updateInMillis
(
updateInterval
,
pendingIntent
!!
,
context
)
}
override
fun
onEnabled
(
context
:
Context
)
{
// if(pendingIntent == null)
// pendingIntent = createPending(context)
//
// val alarm = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
//
// alarm.setRepeating(
// AlarmManager.ELAPSED_REALTIME,
// SystemClock.elapsedRealtime() + updateInterval,
// updateInterval,
// pendingIntent
// )
// updateInMillis(5000, pendingIntent!!, context)
// alarm.setExact(AlarmManager.ELAPSED_REALTIME, 1000 * 5, pending)
}
override
fun
onDisabled
(
context
:
Context
)
{
val
alarm
=
context
.
getSystemService
(
Context
.
ALARM_SERVICE
)
as
AlarmManager
alarm
.
cancel
(
pendingIntent
?:
createPending
(
context
))
}
}
BlackBird/app/src/main/res/layout/next_event_widget.xml
View file @
888c707d
...
...
@@ -21,14 +21,14 @@
android:lines=
"1"
tools:text=
"in 8 min"
android:textColor=
"@color/colorTextLight"
android:textSize=
"1
2
sp"
android:textSize=
"1
1
sp"
android:textStyle=
"bold"
/>
<TextView
android:id=
"@+id/widget_courseIcon"
android:layout_width=
"52dp"
android:layout_height=
"52dp"
android
:background=
"@drawable/ic_timetable_lecture"
tools
:background=
"@drawable/ic_timetable_lecture"
android:fontFamily=
"sans-serif-condensed"
android:gravity=
"center"
android:textColor=
"@android:color/white"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment