adds firebase connection and notifications
- notification handler pushes background and foreground notifications to the phone directly - firebase connection pushes remote notifications in background and foreground - firebase unique token currently logged only, should be send directly to server via rest
This commit is contained in:
parent
51bf245f00
commit
9ea64fb460
@ -38,6 +38,7 @@ dependencies {
|
|||||||
|
|
||||||
implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:16.1.4'
|
implementation 'com.google.android.gms:play-services-mlkit-barcode-scanning:16.1.4'
|
||||||
implementation 'com.android.volley:volley:1.2.0'
|
implementation 'com.android.volley:volley:1.2.0'
|
||||||
|
implementation 'com.google.firebase:firebase-messaging-ktx:21.0.1'
|
||||||
def camerax_version = "1.0.2"
|
def camerax_version = "1.0.2"
|
||||||
implementation 'androidx.core:core-ktx:1.3.2'
|
implementation 'androidx.core:core-ktx:1.3.2'
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
@ -54,3 +55,5 @@ dependencies {
|
|||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.google.gms.google-services' // Google Play services Gradle plugin
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.example.bump
|
package com.maenle.bump
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import com.example.bump.util.LocalData
|
import com.maenle.bump.util.LocalData
|
||||||
import com.example.bump.util.MessageProcessor
|
import com.maenle.bump.util.MessageProcessor
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
@ -1,10 +1,10 @@
|
|||||||
package com.example.bump
|
package com.maenle.bump
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import com.example.bump.util.Message
|
import com.maenle.bump.util.Message
|
||||||
import com.example.bump.util.MessageProcessor
|
import com.maenle.bump.util.MessageProcessor
|
||||||
import com.example.bump.util.RestSingleton
|
import com.maenle.bump.util.RestSingleton
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
@ -7,8 +7,9 @@
|
|||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="com.example.bump.ui.MainApplication"
|
android:name=".ui.MainApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
@ -16,8 +17,29 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.BumpForAndroid">
|
android:theme="@style/Theme.BumpForAndroid">
|
||||||
|
<service
|
||||||
|
android:name=".MyFirebaseMessagingService"
|
||||||
|
android:exported="false">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||||
|
android:resource="@drawable/ic_launcher_foreground"/>
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_color"
|
||||||
|
android:resource="@color/black"/> <!-- [END fcm_default_icon] -->
|
||||||
|
<!-- [START fcm_default_channel] -->
|
||||||
|
<meta-data
|
||||||
|
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
||||||
|
android:value="@string/bump_notification_channel_id" />
|
||||||
|
<!-- [END fcm_default_channel] -->
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="com.example.bump.ui.MainActivity"
|
android:name=".ui.MainActivity"
|
||||||
tools:node="merge"
|
tools:node="merge"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
package com.example.bump.receiver
|
|
||||||
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import com.example.bump.util.sendNotification
|
|
||||||
import com.maenle.bump.R
|
|
||||||
|
|
||||||
class AlarmReceiver: BroadcastReceiver() {
|
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
|
||||||
|
|
||||||
val notificationManager = ContextCompat.getSystemService(
|
|
||||||
context,
|
|
||||||
NotificationManager::class.java
|
|
||||||
) as NotificationManager
|
|
||||||
|
|
||||||
notificationManager.sendNotification(
|
|
||||||
"Hello",
|
|
||||||
context
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package com.example.bump.receiver
|
|
||||||
|
|
||||||
import android.app.AlarmManager
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.app.PendingIntent
|
|
||||||
import android.content.BroadcastReceiver
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.SystemClock
|
|
||||||
import android.text.format.DateUtils
|
|
||||||
import androidx.core.app.AlarmManagerCompat
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
|
|
||||||
class SnoozeReceiver: BroadcastReceiver() {
|
|
||||||
private val REQUEST_CODE = 0
|
|
||||||
|
|
||||||
override fun onReceive(context: Context, intent: Intent) {
|
|
||||||
val triggerTime = SystemClock.elapsedRealtime() + DateUtils.MINUTE_IN_MILLIS
|
|
||||||
|
|
||||||
val notifyIntent = Intent(context, AlarmReceiver::class.java)
|
|
||||||
val notifyPendingIntent = PendingIntent.getBroadcast(
|
|
||||||
context,
|
|
||||||
REQUEST_CODE,
|
|
||||||
notifyIntent,
|
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT
|
|
||||||
)
|
|
||||||
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
|
||||||
AlarmManagerCompat.setExactAndAllowWhileIdle(
|
|
||||||
alarmManager,
|
|
||||||
AlarmManager.ELAPSED_REALTIME_WAKEUP,
|
|
||||||
triggerTime,
|
|
||||||
notifyPendingIntent
|
|
||||||
)
|
|
||||||
|
|
||||||
val notificationManager = ContextCompat.getSystemService(
|
|
||||||
context,
|
|
||||||
NotificationManager::class.java
|
|
||||||
) as NotificationManager
|
|
||||||
notificationManager.cancelAll()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,78 @@
|
|||||||
|
package com.maenle.bump
|
||||||
|
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.maenle.bump.util.sendNotification
|
||||||
|
import com.google.firebase.messaging.FirebaseMessagingService
|
||||||
|
import com.google.firebase.messaging.RemoteMessage
|
||||||
|
|
||||||
|
class MyFirebaseMessagingService : FirebaseMessagingService() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when message is received.
|
||||||
|
*
|
||||||
|
* @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
|
||||||
|
*/
|
||||||
|
// [START receive_message]
|
||||||
|
override fun onMessageReceived(remoteMessage: RemoteMessage) {
|
||||||
|
// Not getting messages here? See why this may be: https://goo.gl/39bRNJ
|
||||||
|
Log.d(TAG, "From: ${remoteMessage.from}")
|
||||||
|
|
||||||
|
// TODO Step 3.5 check messages for data
|
||||||
|
// Check if message contains a data payload.
|
||||||
|
remoteMessage.data.let {
|
||||||
|
Log.d(TAG, "Message data payload: " + remoteMessage.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Step 3.6 check messages for notification and call sendNotification
|
||||||
|
// Check if message contains a notification payload.
|
||||||
|
remoteMessage.notification?.let {
|
||||||
|
Log.d(TAG, "Message Notification Body: ${it.body}")
|
||||||
|
sendNotification(it.body!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// [END receive_message]
|
||||||
|
|
||||||
|
//TODO Step 3.2 log registration token
|
||||||
|
// [START on_new_token]
|
||||||
|
/**
|
||||||
|
* Called if InstanceID token is updated. This may occur if the security of
|
||||||
|
* the previous token had been compromised. Note that this is called when the InstanceID token
|
||||||
|
* is initially generated so this is where you would retrieve the token.
|
||||||
|
*/
|
||||||
|
override fun onNewToken(token: String) {
|
||||||
|
Log.d(TAG, "Refreshed token: $token")
|
||||||
|
|
||||||
|
// If you want to send messages to this application instance or
|
||||||
|
// manage this apps subscriptions on the server side, send the
|
||||||
|
// Instance ID token to your app server.
|
||||||
|
sendRegistrationToServer(token)
|
||||||
|
}
|
||||||
|
// [END on_new_token]
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Persist token to third-party servers.
|
||||||
|
*
|
||||||
|
* @param token The new token.
|
||||||
|
*/
|
||||||
|
private fun sendRegistrationToServer(token: String?) {
|
||||||
|
// TODO: Implement this method to send token to your app server.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and show a simple notification containing the received FCM message.
|
||||||
|
*
|
||||||
|
* @param messageBody FCM message body received.
|
||||||
|
*/
|
||||||
|
private fun sendNotification(messageBody: String) {
|
||||||
|
val notificationManager = ContextCompat.getSystemService(applicationContext, NotificationManager::class.java) as NotificationManager
|
||||||
|
notificationManager.sendNotification(messageBody, applicationContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "MyFirebaseMsgService"
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.bump.ui
|
package com.maenle.bump.ui
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
@ -31,8 +31,8 @@ import kotlin.math.min
|
|||||||
import android.view.WindowInsets
|
import android.view.WindowInsets
|
||||||
|
|
||||||
import android.graphics.Insets
|
import android.graphics.Insets
|
||||||
import com.example.bump.util.BumpProcessor
|
import com.maenle.bump.util.BumpProcessor
|
||||||
import com.example.bump.util.CameraXViewModel
|
import com.maenle.bump.util.CameraXViewModel
|
||||||
|
|
||||||
|
|
||||||
class CameraFragment: Fragment() {
|
class CameraFragment: Fragment() {
|
@ -1,17 +1,20 @@
|
|||||||
package com.example.bump.ui
|
package com.maenle.bump.ui
|
||||||
|
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.example.bump.util.BumpProcessor
|
import com.google.firebase.messaging.FirebaseMessaging
|
||||||
import com.example.bump.util.RestSingleton
|
import com.maenle.bump.util.BumpProcessor
|
||||||
|
import com.maenle.bump.util.RestSingleton
|
||||||
|
import com.maenle.bump.util.sendNotification
|
||||||
import com.maenle.bump.R
|
import com.maenle.bump.R
|
||||||
import com.maenle.bump.databinding.FragmentFirstBinding
|
import com.maenle.bump.databinding.FragmentFirstBinding
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
@ -30,6 +33,7 @@ class FirstFragment : Fragment() {
|
|||||||
private lateinit var rest: RestSingleton
|
private lateinit var rest: RestSingleton
|
||||||
private lateinit var log: JSONArray
|
private lateinit var log: JSONArray
|
||||||
|
|
||||||
|
|
||||||
private lateinit var bump: BumpProcessor
|
private lateinit var bump: BumpProcessor
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater, container: ViewGroup?,
|
inflater: LayoutInflater, container: ViewGroup?,
|
||||||
@ -40,12 +44,21 @@ class FirstFragment : Fragment() {
|
|||||||
bump = BumpProcessor(requireContext())
|
bump = BumpProcessor(requireContext())
|
||||||
|
|
||||||
|
|
||||||
// TODO: Step 1.7 call create channel
|
|
||||||
createChannel(
|
createChannel(
|
||||||
getString(R.string.bump_notification_channel_id),
|
getString(R.string.bump_notification_channel_id),
|
||||||
getString(R.string.bump_notification_channel_name)
|
getString(R.string.bump_notification_channel_name)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/*
|
||||||
|
val notificationManager = ContextCompat.getSystemService(
|
||||||
|
requireContext(),
|
||||||
|
NotificationManager::class.java
|
||||||
|
) as NotificationManager
|
||||||
|
notificationManager.sendNotification(getString(R.string.notification), requireContext())
|
||||||
|
*/
|
||||||
|
|
||||||
|
subscribeTopic()
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,13 +75,11 @@ class FirstFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createChannel(channelId: String, channelName: String) {
|
private fun createChannel(channelId: String, channelName: String) {
|
||||||
// TODO: Step 1.6 START create a channel
|
|
||||||
val notificationChannel = NotificationChannel(
|
val notificationChannel = NotificationChannel(
|
||||||
channelId,
|
channelId,
|
||||||
channelName,
|
channelName,
|
||||||
// TODO: Step 2.4 change importance
|
|
||||||
NotificationManager.IMPORTANCE_HIGH
|
NotificationManager.IMPORTANCE_HIGH
|
||||||
)// TODO: Step 2.6 disable badges for this channel
|
)
|
||||||
.apply {
|
.apply {
|
||||||
setShowBadge(false)
|
setShowBadge(false)
|
||||||
}
|
}
|
||||||
@ -82,12 +93,24 @@ class FirstFragment : Fragment() {
|
|||||||
NotificationManager::class.java
|
NotificationManager::class.java
|
||||||
)
|
)
|
||||||
notificationManager.createNotificationChannel(notificationChannel)
|
notificationManager.createNotificationChannel(notificationChannel)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Step 1.6 END create a channel
|
private fun subscribeTopic() {
|
||||||
|
// [START subscribe_topic]
|
||||||
|
FirebaseMessaging.getInstance().subscribeToTopic(TOPIC)
|
||||||
|
.addOnCompleteListener { task ->
|
||||||
|
var message = getString(R.string.message_subscribed)
|
||||||
|
if (!task.isSuccessful) {
|
||||||
|
message = getString(R.string.message_subscribe_failed)
|
||||||
|
}
|
||||||
|
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
// [END subscribe_topics]
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun newInstance() = FirstFragment()
|
fun newInstance() = FirstFragment()
|
||||||
|
private val TOPIC = "Bump"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.bump.ui
|
package com.maenle.bump.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
@ -1,9 +1,9 @@
|
|||||||
package com.example.bump.ui
|
package com.maenle.bump.ui
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import com.example.bump.util.BumpProcessor
|
import com.maenle.bump.util.BumpProcessor
|
||||||
import com.example.bump.util.RestSingleton
|
import com.maenle.bump.util.RestSingleton
|
||||||
|
|
||||||
// Not object class. AndroidManifest.xml error happen.
|
// Not object class. AndroidManifest.xml error happen.
|
||||||
class MainApplication : Application() {
|
class MainApplication : Application() {
|
@ -1,11 +1,10 @@
|
|||||||
package com.example.bump.ui
|
package com.maenle.bump.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.navigation.fragment.findNavController
|
|
||||||
import com.maenle.bump.databinding.FragmentSecondBinding
|
import com.maenle.bump.databinding.FragmentSecondBinding
|
||||||
|
|
||||||
/**
|
/**
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.bump.util
|
package com.maenle.bump.util
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Handler
|
import android.os.Handler
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.bump.util
|
package com.maenle.bump.util
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.util.Log
|
import android.util.Log
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.bump.util
|
package com.maenle.bump.util
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Context.MODE_PRIVATE
|
import android.content.Context.MODE_PRIVATE
|
@ -1,8 +1,7 @@
|
|||||||
package com.example.bump.util
|
package com.maenle.bump.util
|
||||||
|
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class Message(var sender: String, var data: String, timestamp: String) {
|
class Message(var sender: String, var data: String, timestamp: String) {
|
||||||
val timestamp = LocalDate.parse(timestamp, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS"))
|
val timestamp = LocalDate.parse(timestamp, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS"))
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.bump.util
|
package com.maenle.bump.util
|
||||||
|
|
||||||
import java.util.Base64
|
import java.util.Base64
|
||||||
import javax.crypto.spec.PBEKeySpec
|
import javax.crypto.spec.PBEKeySpec
|
||||||
@ -7,7 +7,7 @@ import com.macasaet.fernet.Key
|
|||||||
import com.macasaet.fernet.Token
|
import com.macasaet.fernet.Token
|
||||||
import com.macasaet.fernet.StringValidator
|
import com.macasaet.fernet.StringValidator
|
||||||
import com.macasaet.fernet.Validator
|
import com.macasaet.fernet.Validator
|
||||||
import com.example.bump.ui.MainActivity
|
import com.maenle.bump.ui.MainActivity
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import java.time.Duration
|
import java.time.Duration
|
@ -1,20 +1,19 @@
|
|||||||
package com.example.bump.util
|
package com.maenle.bump.util
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import com.example.bump.receiver.SnoozeReceiver
|
import com.maenle.bump.ui.MainActivity
|
||||||
import com.example.bump.ui.MainActivity
|
|
||||||
import com.maenle.bump.R
|
import com.maenle.bump.R
|
||||||
|
|
||||||
// Notification ID.
|
// Notification ID.
|
||||||
private val NOTIFICATION_ID = 0
|
private val NOTIFICATION_ID = 0
|
||||||
private val REQUEST_CODE = 0
|
|
||||||
private val FLAGS = 0
|
|
||||||
|
|
||||||
|
@SuppressLint("WrongConstant")
|
||||||
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
|
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
|
||||||
// Create the content intent for the notification, which launches
|
// Create the content intent for the notification, which launches
|
||||||
// this activity
|
// this activity
|
||||||
@ -33,17 +32,6 @@ fun NotificationManager.sendNotification(messageBody: String, applicationContext
|
|||||||
applicationContext.resources,
|
applicationContext.resources,
|
||||||
R.drawable.ic_launcher_foreground
|
R.drawable.ic_launcher_foreground
|
||||||
)
|
)
|
||||||
val bigPicStyle = NotificationCompat.BigPictureStyle()
|
|
||||||
.bigPicture(eggImage)
|
|
||||||
.bigLargeIcon(null)
|
|
||||||
|
|
||||||
// TODO: Step 2.2 add snooze action
|
|
||||||
val snoozeIntent = Intent(applicationContext, SnoozeReceiver::class.java)
|
|
||||||
val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(
|
|
||||||
applicationContext,
|
|
||||||
REQUEST_CODE,
|
|
||||||
snoozeIntent,
|
|
||||||
FLAGS)
|
|
||||||
|
|
||||||
// TODO: Step 1.2 get an instance of NotificationCompat.Builder
|
// TODO: Step 1.2 get an instance of NotificationCompat.Builder
|
||||||
// Build the notification
|
// Build the notification
|
||||||
@ -52,8 +40,6 @@ fun NotificationManager.sendNotification(messageBody: String, applicationContext
|
|||||||
applicationContext.getString(R.string.bump_notification_channel_id)
|
applicationContext.getString(R.string.bump_notification_channel_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: Step 1.8 use the new 'breakfast' notification channel
|
|
||||||
|
|
||||||
// TODO: Step 1.3 set title, text and icon to builder
|
// TODO: Step 1.3 set title, text and icon to builder
|
||||||
.setSmallIcon(R.drawable.ic_launcher_foreground)
|
.setSmallIcon(R.drawable.ic_launcher_foreground)
|
||||||
.setContentTitle(applicationContext
|
.setContentTitle(applicationContext
|
||||||
@ -65,16 +51,8 @@ fun NotificationManager.sendNotification(messageBody: String, applicationContext
|
|||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
|
|
||||||
// TODO: Step 2.1 add style to builder
|
// TODO: Step 2.1 add style to builder
|
||||||
.setStyle(bigPicStyle)
|
|
||||||
.setLargeIcon(eggImage)
|
.setLargeIcon(eggImage)
|
||||||
|
|
||||||
// TODO: Step 2.3 add snooze action
|
|
||||||
.addAction(
|
|
||||||
R.drawable.ic_launcher_foreground,
|
|
||||||
applicationContext.getString(R.string.snooze),
|
|
||||||
snoozePendingIntent
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: Step 2.5 set priority
|
// TODO: Step 2.5 set priority
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
// TODO: Step 1.4 call notify
|
// TODO: Step 1.4 call notify
|
@ -1,11 +1,11 @@
|
|||||||
package com.example.bump.util
|
package com.maenle.bump.util
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.android.volley.Request
|
import com.android.volley.Request
|
||||||
import com.android.volley.RequestQueue
|
import com.android.volley.RequestQueue
|
||||||
import com.android.volley.toolbox.*
|
import com.android.volley.toolbox.*
|
||||||
import com.example.bump.ui.MainActivity
|
import com.maenle.bump.ui.MainActivity
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
|
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
@ -4,7 +4,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="com.example.bump.ui.MainActivity">
|
tools:context="com.maenle.bump.ui.MainActivity">
|
||||||
|
|
||||||
<com.google.android.material.appbar.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="com.example.bump.ui.SecondFragment">
|
tools:context="com.maenle.bump.ui.SecondFragment">
|
||||||
|
|
||||||
<!--androidx.camera.view.PreviewView
|
<!--androidx.camera.view.PreviewView
|
||||||
android:id="@+id/viewFinder"
|
android:id="@+id/viewFinder"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="com.example.bump.ui.FirstFragment">
|
tools:context="com.maenle.bump.ui.FirstFragment">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textview_first"
|
android:id="@+id/textview_first"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="com.example.bump.ui.SecondFragment">
|
tools:context="com.maenle.bump.ui.SecondFragment">
|
||||||
|
|
||||||
<androidx.camera.view.PreviewView
|
<androidx.camera.view.PreviewView
|
||||||
android:id="@+id/viewFinder"
|
android:id="@+id/viewFinder"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
tools:context="com.maenle.bump.com.example.bump.ui.MainActivity">
|
tools:context="com.maenle.bump.ui.MainActivity">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_settings"
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/FirstFragment"
|
android:id="@+id/FirstFragment"
|
||||||
android:name="com.example.bump.ui.FirstFragment"
|
android:name="com.maenle.bump.ui.FirstFragment"
|
||||||
android:label="@string/first_fragment_label"
|
android:label="@string/first_fragment_label"
|
||||||
tools:layout="@layout/fragment_first">
|
tools:layout="@layout/fragment_first">
|
||||||
|
|
||||||
@ -17,7 +17,7 @@
|
|||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/SecondFragment"
|
android:id="@+id/SecondFragment"
|
||||||
android:name="com.example.bump.ui.SecondFragment"
|
android:name="com.maenle.bump.ui.SecondFragment"
|
||||||
android:label="@string/second_fragment_label"
|
android:label="@string/second_fragment_label"
|
||||||
tools:layout="@layout/fragment_second">
|
tools:layout="@layout/fragment_second">
|
||||||
|
|
||||||
@ -27,7 +27,7 @@
|
|||||||
</fragment>
|
</fragment>
|
||||||
<fragment
|
<fragment
|
||||||
android:id="@+id/CameraFragment"
|
android:id="@+id/CameraFragment"
|
||||||
android:name="com.example.bump.ui.CameraFragment"
|
android:name="com.maenle.bump.ui.CameraFragment"
|
||||||
android:label="@string/camera_fragment_label"
|
android:label="@string/camera_fragment_label"
|
||||||
tools:layout="@layout/fragment_camera">
|
tools:layout="@layout/fragment_camera">
|
||||||
|
|
||||||
|
@ -18,4 +18,7 @@
|
|||||||
<string name="bump_notification_channel_id">bump_id</string>
|
<string name="bump_notification_channel_id">bump_id</string>
|
||||||
<string name="snooze">Snooze</string>
|
<string name="snooze">Snooze</string>
|
||||||
<string name="bump_notification_channel_name">Bump</string>
|
<string name="bump_notification_channel_name">Bump</string>
|
||||||
|
<string name="notification">This is a notification</string>
|
||||||
|
<string name="message_subscribed">Subscribed to Channel</string>
|
||||||
|
<string name="message_subscribe_failed">Could not subscribe</string>
|
||||||
</resources>
|
</resources>
|
@ -7,6 +7,8 @@ buildscript {
|
|||||||
dependencies {
|
dependencies {
|
||||||
classpath "com.android.tools.build:gradle:7.0.4"
|
classpath "com.android.tools.build:gradle:7.0.4"
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.6.0"
|
||||||
|
classpath 'com.google.gms:google-services:4.3.2' // Google Services plugin
|
||||||
|
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
Loading…
Reference in New Issue
Block a user