Skip to content

Commit

Permalink
Working PostStatus in app. Improved updates on changed view. LiveData…
Browse files Browse the repository at this point in the history
… implemented
  • Loading branch information
pwnpanda committed Apr 3, 2021
1 parent 2c8e6b8 commit c53ad96
Show file tree
Hide file tree
Showing 19 changed files with 412 additions and 187 deletions.
1 change: 0 additions & 1 deletion Android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ android {
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
// Android KTX
Expand Down
122 changes: 100 additions & 22 deletions Android/app/src/main/java/com/robinlunde/mailbox/MailboxApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import android.os.Build
import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.robinlunde.mailbox.alert.AlertViewModel
import com.robinlunde.mailbox.datamodel.PostLogEntry
import com.robinlunde.mailbox.datamodel.PostUpdateStatus
import com.robinlunde.mailbox.logview.PostViewModel
import com.robinlunde.mailbox.network.BlueToothLib
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
Expand All @@ -19,9 +24,13 @@ class MailboxApp : Application() {
super.onCreate()
mailboxApp = this
util = Util()
prefs = this@MailboxApp.getSharedPreferences(getString(R.string.username_pref), Context.MODE_PRIVATE)
prefs = this@MailboxApp.getSharedPreferences(
getString(R.string.username_pref),
Context.MODE_PRIVATE
)
username = prefs.getString(getString(R.string.username_pref), "").toString()

// Need to start with string long enough to not trigger fault
status = PostUpdateStatus(false, "FOOTBARBAZFOOBARBAZ", getString(R.string.no_status_yet_username))
// Create scope and start handler in coroutine
appScope = MainScope()
btConnection = BlueToothLib()
Expand All @@ -32,12 +41,17 @@ class MailboxApp : Application() {
// Setup bluetooth
val PERMISSION_CODE = getString(R.string.bt_id_integer).toInt()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (ContextCompat.checkSelfPermission(baseContext,
Manifest.permission.ACCESS_BACKGROUND_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.myActivity,
if (ContextCompat.checkSelfPermission(
baseContext,
Manifest.permission.ACCESS_BACKGROUND_LOCATION
)
!= PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
MainActivity.myActivity,
arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION),
PERMISSION_CODE)
PERMISSION_CODE
)
}
}
}
Expand All @@ -50,15 +64,20 @@ class MailboxApp : Application() {
private lateinit var mailboxApp: MailboxApp
private lateinit var username: String
private lateinit var prefs: SharedPreferences
private lateinit var model: PostViewModel
private lateinit var postViewModel: PostViewModel
private lateinit var alertViewModel: AlertViewModel
private lateinit var appScope: CoroutineScope
private lateinit var btConnection: BlueToothLib
private lateinit var status: Util.UpdateStatus
// Initialize to signal no data available
private lateinit var status: PostUpdateStatus

data class MyMessage(val title: String, val text: String)

// Get username
fun getUsername(): String {
return username
}

// Set username
fun setUsername(newUsername: String) {
username = newUsername
Expand All @@ -71,6 +90,7 @@ class MailboxApp : Application() {
apply()
}
}

// Get application instance
fun getInstance(): MailboxApp {
return mailboxApp
Expand All @@ -85,42 +105,100 @@ class MailboxApp : Application() {
fun setPostEntries(updatedPostLogEntryList: MutableList<PostLogEntry>) {
postLogEntryList = updatedPostLogEntryList
try {
model.setPostEntries(postLogEntryList)
}catch (e: UninitializedPropertyAccessException){
postViewModel.mutablePostEntries.postValue(postLogEntryList)
} catch (e: UninitializedPropertyAccessException) {
Log.d("Soft error", "Model not yet instantiated - Could not update data for view")
} catch (e: Exception){
} catch (e: Exception) {
throw e
}
}

// Get utility instance
fun getUtil(): Util {
return util
}

// Set PostViewModel
fun setModel(myModel: PostViewModel) {
model = myModel
fun setPostModel(myModel: PostViewModel) {
postViewModel = myModel
}

fun setAlertModel(myModel: AlertViewModel){
alertViewModel = myModel
}

// Get application scope
fun getAppScope(): CoroutineScope {
return appScope
}

// Get Connector for Bluetooth operations
fun getBTConn(): BlueToothLib {
return btConnection
}
// Get latest status of post
fun getStatus(): Util.UpdateStatus{

// Get latest status of post, only for initiating LiveData
fun getStatus(): PostUpdateStatus {
return status
}

// Set latest status of post
fun setStatus(newStatus: Util.UpdateStatus) {
/**
* newMail True -> True = do nothing
* newMail True -> False = remove notification view & push that X picked up the mail
* newMail: False -> True = Notification and details update
* newMail False -> False, Update timestamp and person who did last check
*/
fun setStatus(newStatus: PostUpdateStatus) {
// Check if current and previous status is the same
val isEqual = status.newMail == newStatus.newMail
// If value after update is the same as before
if (isEqual) {
Log.d("Status", "Same value as before, no push needed")
when (newStatus.newMail) {
true -> Log.d("Status", "No new information. Do nothing!")
false -> Log.d("Status", "Maybe new timestamp for last check! Arbitrary update")
}
// If value after update is different
} else {
val msg: MyMessage = when (newStatus.newMail) {
true -> {
Log.d("Status", "New mail detected! Send push and update fragment! Data: $newStatus")
// This is return value
MyMessage(
"New mail detected!",
"The mail was delivered at ${newStatus.time} on ${
newStatus.date
}!"
)
}
false -> {
Log.d("Status", "Mail picked up! Send push and update fragment")
// This is return value
MyMessage(
"Mail picked up by ${newStatus.username}!",
"Mail picked up at ${newStatus.time} on ${
newStatus.date
}! Say thanks!"
)
}
}
// Push Notification only if it is not the first run
if (status.username != getInstance().getString(R.string.no_status_yet_username) ){
Log.d("Status", "Not first run, Send push notification!")
util.pushNotification(msg)
}
}

// Update value for checking next time :)
// This needs to happen before updating fragment, as the fragment relies on getStatus()
status = newStatus
if (status.newMail){
// Push Notification
util.pushNotification(status.timestamp)
// Update fragment_alert
alertViewModel.currentStatus.postValue(newStatus)

}
// Update fragment_alert - Do for all instances, doesn't hurt!
// This happens automatically when notification is clicked.
//MainActivity.myActivity.updateAlertFragment()
}

}
}
18 changes: 11 additions & 7 deletions Android/app/src/main/java/com/robinlunde/mailbox/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ import kotlinx.coroutines.cancel


// TODO
// Name - Timestamp of post received (from BT) - Timestamp of pickup
// Get data from BT then call
// MailboxApp.pushNotification(timeStamp)
// Get data from BT, call MailboxApp.setStatus(status), and send new status to web by calling

class MainActivity : AppCompatActivity() {
private lateinit var drawerLayout: DrawerLayout
Expand Down Expand Up @@ -55,6 +53,7 @@ class MainActivity : AppCompatActivity() {
val binding =
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
drawerLayout = binding.drawerLayout
onNewIntent(intent)
}

// create and inflate menu here
Expand All @@ -69,7 +68,7 @@ class MainActivity : AppCompatActivity() {

// Handles clicks on the menu
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// if it arrives here, something went wrong
// Always arrives here first
return when (item.itemId) {
R.id.logo -> {
MailboxApp.getUtil().logButtonPress("Main - logo")
Expand All @@ -84,9 +83,15 @@ class MainActivity : AppCompatActivity() {
}

// Currently does nothing... ? TODO Check and fix
override fun onNewIntent(intent: Intent?) {
Log.d("Intent!", "Intent received")
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
Log.d("Intent!", "Intent received: $intent")

// It is my push notification intent!
if ( intent.getBooleanExtra(getString(R.string.app_name), false) ) {
Log.d("Intent!", "My intent received: $intent")
// No need to update fragment, as it does so automatically upon intent clicked ^~^
}
}

// Make sure BT is enabled when we resume app
Expand Down Expand Up @@ -121,7 +126,6 @@ class MainActivity : AppCompatActivity() {
}
}


// Cleanup when activity is dead
// TODO is this correct?
override fun onDestroy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import androidx.core.app.NotificationCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.toBitmap

class MyNotificationManager (private val ctx: Context){
class MyNotificationManager(private val ctx: Context) {
private val myNotificationManager: NotificationManager =
ctx.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

@RequiresApi(Build.VERSION_CODES.O)
private val channelId: String = createNotificationChannel()!!

private var count: Int = 0
private var count: Int = 1337

// Register the channel with the system
@RequiresApi(Build.VERSION_CODES.O)
Expand All @@ -48,40 +48,50 @@ class MyNotificationManager (private val ctx: Context){
}

fun createPush(
timeStamp: String,
message: MailboxApp.Companion.MyMessage,
@DrawableRes smallIcon: Int = R.mipmap.ic_launcher,
//@DrawableRes largeIcon: Int = R.mipmap.post_box,
) : Int {
) {
// TODO replace with logo - icon_mailbox
// TODO change message based on input. Not only timestamp
//val largeIcon = BitmapFactory.decodeResource(MailboxApp.getInstance().resources, R.mipmap.post_box)

val largeIcon = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ResourcesCompat.getDrawable(
MailboxApp.getInstance().resources,
R.mipmap.ic_launcher,
null
) as AdaptiveIconDrawable
MailboxApp.getInstance().resources,
R.mipmap.ic_launcher,
null
) as AdaptiveIconDrawable
} else {
Log.d("Notification", "Android version too old, ignoring push notifications!")
null
}

// Working setup
// Final intent that will launch action if push notification is pressed
val intent = Intent(ctx, MainActivity::class.java).apply {
flags =
Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
// Add in order to identify intent from our own app
intent.putExtra( MailboxApp.getInstance().getString(R.string.app_name), true)

// Create temporary intent for the push notification
val notifyPendingIntent =
PendingIntent.getActivity(ctx, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

// Build intent data for the push notification
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val builder = NotificationCompat.Builder(ctx, channelId).apply {
// Set small icon
this.setSmallIcon(smallIcon)
// Set big icon
.setLargeIcon(largeIcon?.toBitmap())
this.setContentTitle("The mailman has been here!")
this.setContentText("The mailman delivered the mail at: $timeStamp")
// Set big icon
.setLargeIcon(largeIcon?.toBitmap())
this.setContentTitle(message.title)
this.setContentText(message.text)
/*
this.setContentTitle("New mail detected!")
this.setContentText("The mail was delivered at: $timeStamp")
*/
priority = NotificationCompat.PRIORITY_MAX
// Removes notification when pressed
this.setAutoCancel(true)
Expand All @@ -90,12 +100,13 @@ class MyNotificationManager (private val ctx: Context){
//Set following intent
this.setContentIntent(notifyPendingIntent)
}

// notificationId is a unique int for each notification that you must define
// If static, each notification will overwrite the previous one (PERFECT!! :) )
// Send it!
myNotificationManager.notify(count, builder.build())
return count++
} else {
Log.d("Notification", "Android version too old, ignoring push notifications!")
return -1
}
}
}
27 changes: 0 additions & 27 deletions Android/app/src/main/java/com/robinlunde/mailbox/PostViewModel.kt

This file was deleted.

Loading

0 comments on commit c53ad96

Please sign in to comment.