adds stub for notifications
This commit is contained in:
parent
734b64ce3b
commit
6e3f3c44af
@ -1,8 +1,9 @@
|
|||||||
package com.example.bump
|
package com.example.bump
|
||||||
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.internal.runner.InstrumentationConnection
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import com.example.bump.util.LocalData
|
||||||
|
import com.example.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
|
||||||
@ -15,8 +16,9 @@ class MessageProcessorTest {
|
|||||||
val code = "dydoes-unknowledgeable-indiscretion-househusbands-pot-walloper-indiscretion-discophorous-transcriptions-dydoes-poodle-faker-transcriptions-budlike"
|
val code = "dydoes-unknowledgeable-indiscretion-househusbands-pot-walloper-indiscretion-discophorous-transcriptions-dydoes-poodle-faker-transcriptions-budlike"
|
||||||
// val messageRaw = "M1dEAxKZ5HUHCJoRkgGOvAABhqCAAAAAAGG2eKTSlKXWLDQx5B_wssZsNwsanzQID2UyUm4KKuKYKgfwH5MG2N-qzt6K4mg3pfZmWPaiDB9PiqlX236k6zo9Yvvq"
|
// val messageRaw = "M1dEAxKZ5HUHCJoRkgGOvAABhqCAAAAAAGG2eKTSlKXWLDQx5B_wssZsNwsanzQID2UyUm4KKuKYKgfwH5MG2N-qzt6K4mg3pfZmWPaiDB9PiqlX236k6zo9Yvvq"
|
||||||
val messageRaw = "M1dEAxKZ5HUHCJoRkgGOvAABhqCAAAAAAGG8afPPk380EzwcbGzNoTr_I4y6YT8hnUYcToinlgsVkaUx5K-JicdS5epZenOX4u8vVhhMvR0ebeWm_mgp6LZvTw8S"
|
val messageRaw = "M1dEAxKZ5HUHCJoRkgGOvAABhqCAAAAAAGG8afPPk380EzwcbGzNoTr_I4y6YT8hnUYcToinlgsVkaUx5K-JicdS5epZenOX4u8vVhhMvR0ebeWm_mgp6LZvTw8S"
|
||||||
val data = decryptMessage(code, messageRaw)
|
val processor = MessageProcessor(code)
|
||||||
Assert.assertEquals(data, "hello")
|
val decrypted = processor.decrypt(messageRaw)
|
||||||
|
Assert.assertEquals(decrypted, "hello")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -26,7 +28,9 @@ class MessageProcessorTest {
|
|||||||
|
|
||||||
val test = getRandomString(32)
|
val test = getRandomString(32)
|
||||||
val encrypted = message.encrypt(test)
|
val encrypted = message.encrypt(test)
|
||||||
val decrypted = decryptMessage(code, encrypted)
|
|
||||||
|
val processor = MessageProcessor(code)
|
||||||
|
val decrypted = processor.decrypt(encrypted)
|
||||||
Assert.assertEquals(test, decrypted)
|
Assert.assertEquals(test, decrypted)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,9 @@ package com.example.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.example.bump.util.MessageProcessor
|
||||||
|
import com.example.bump.util.RestSingleton
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
@ -27,6 +30,13 @@ class ExampleInstrumentedTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class NotificationTest {
|
||||||
|
@Test
|
||||||
|
fun showNotification() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class RestCryptTest{
|
class RestCryptTest{
|
||||||
@Test
|
@Test
|
||||||
@ -46,6 +56,8 @@ class RestCryptTest{
|
|||||||
assertEquals(messageData, encrypted)
|
assertEquals(messageData, encrypted)
|
||||||
val data = message.decrypt(messageData)
|
val data = message.decrypt(messageData)
|
||||||
assertEquals(data, testMessage)
|
assertEquals(data, testMessage)
|
||||||
|
|
||||||
|
val m = Message(code, data, messageEncrypted.get("timestamp").toString())
|
||||||
lock.countDown()
|
lock.countDown()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="com.example.bump.MainApplication"
|
android:name="com.example.bump.ui.MainApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
@ -17,7 +17,7 @@
|
|||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.BumpForAndroid">
|
android:theme="@style/Theme.BumpForAndroid">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name="com.example.bump.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,5 +0,0 @@
|
|||||||
package com.example.bump
|
|
||||||
|
|
||||||
class Message {
|
|
||||||
|
|
||||||
}
|
|
28
app/src/main/java/com/example/bump/receiver/AlarmReceiver.kt
Normal file
28
app/src/main/java/com/example/bump/receiver/AlarmReceiver.kt
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
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
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.maenle.bump
|
package com.example.bump.ui
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
@ -31,7 +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.BumpProcessor
|
import com.example.bump.util.BumpProcessor
|
||||||
|
import com.example.bump.util.CameraXViewModel
|
||||||
|
|
||||||
|
|
||||||
class CameraFragment: Fragment() {
|
class CameraFragment: Fragment() {
|
||||||
@ -181,7 +182,7 @@ class CameraFragment: Fragment() {
|
|||||||
barcodes.forEach {
|
barcodes.forEach {
|
||||||
Log.d(TAG, it.rawValue!!)
|
Log.d(TAG, it.rawValue!!)
|
||||||
val bump = BumpProcessor.getInstance(requireContext())
|
val bump = BumpProcessor.getInstance(requireContext())
|
||||||
bump.addSecret(requireContext(), it.rawValue!!)
|
bump.addSecret(requireContext(), it.rawValue!!)
|
||||||
fragmentManager?.popBackStack()
|
fragmentManager?.popBackStack()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,18 +1,20 @@
|
|||||||
package com.maenle.bump
|
package com.example.bump.ui
|
||||||
|
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager
|
||||||
|
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 androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import com.example.bump.BumpProcessor
|
import com.example.bump.util.BumpProcessor
|
||||||
import com.example.bump.MessageProcessor
|
import com.example.bump.util.RestSingleton
|
||||||
import com.example.bump.RestSingleton
|
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
|
||||||
import org.json.JSONObject
|
|
||||||
import java.io.File
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple [Fragment] subclass as the default destination in the navigation.
|
* A simple [Fragment] subclass as the default destination in the navigation.
|
||||||
@ -36,6 +38,13 @@ class FirstFragment : Fragment() {
|
|||||||
): View? {
|
): View? {
|
||||||
|
|
||||||
_binding = FragmentFirstBinding.inflate(inflater, container, false)
|
_binding = FragmentFirstBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
|
// TODO: Step 1.7 call create channel
|
||||||
|
createChannel(
|
||||||
|
getString(R.string.bump_notification_channel_id),
|
||||||
|
getString(R.string.bump_notification_channel_name)
|
||||||
|
)
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,6 +60,35 @@ class FirstFragment : Fragment() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createChannel(channelId: String, channelName: String) {
|
||||||
|
// TODO: Step 1.6 START create a channel
|
||||||
|
val notificationChannel = NotificationChannel(
|
||||||
|
channelId,
|
||||||
|
channelName,
|
||||||
|
// TODO: Step 2.4 change importance
|
||||||
|
NotificationManager.IMPORTANCE_HIGH
|
||||||
|
)// TODO: Step 2.6 disable badges for this channel
|
||||||
|
.apply {
|
||||||
|
setShowBadge(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
notificationChannel.enableLights(true)
|
||||||
|
notificationChannel.lightColor = Color.RED
|
||||||
|
notificationChannel.enableVibration(true)
|
||||||
|
notificationChannel.description = getString(R.string.bump_notification_channel_id)
|
||||||
|
|
||||||
|
val notificationManager = requireActivity().getSystemService(
|
||||||
|
NotificationManager::class.java
|
||||||
|
)
|
||||||
|
notificationManager.createNotificationChannel(notificationChannel)
|
||||||
|
|
||||||
|
// TODO: Step 1.6 END create a channel
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance() = FirstFragment()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
@ -1,4 +1,4 @@
|
|||||||
package com.maenle.bump
|
package com.example.bump.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
@ -9,6 +9,7 @@ import androidx.navigation.ui.navigateUp
|
|||||||
import androidx.navigation.ui.setupActionBarWithNavController
|
import androidx.navigation.ui.setupActionBarWithNavController
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import com.maenle.bump.R
|
||||||
import com.maenle.bump.databinding.ActivityMainBinding
|
import com.maenle.bump.databinding.ActivityMainBinding
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
@ -1,7 +1,9 @@
|
|||||||
package com.example.bump
|
package com.example.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.example.bump.util.RestSingleton
|
||||||
|
|
||||||
// Not object class. AndroidManifest.xml error happen.
|
// Not object class. AndroidManifest.xml error happen.
|
||||||
class MainApplication : Application() {
|
class MainApplication : Application() {
|
@ -1,4 +1,4 @@
|
|||||||
package com.maenle.bump
|
package com.example.bump.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
@ -1,15 +1,11 @@
|
|||||||
package com.example.bump
|
package com.example.bump.util
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import com.android.volley.toolbox.JsonObjectRequest
|
|
||||||
import com.maenle.bump.MainActivity
|
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
class BumpProcessor constructor(context: Context) {
|
class BumpProcessor constructor(context: Context) {
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.maenle.bump
|
package com.example.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
|
package com.example.bump.util
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Context.MODE_PRIVATE
|
import android.content.Context.MODE_PRIVATE
|
10
app/src/main/java/com/example/bump/util/Message.kt
Normal file
10
app/src/main/java/com/example/bump/util/Message.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package com.example.bump.util
|
||||||
|
|
||||||
|
import java.time.LocalDate
|
||||||
|
import java.time.format.DateTimeFormatter
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
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"))
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.example.bump
|
package com.example.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.maenle.bump.MainActivity
|
import com.example.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
|
||||||
@ -80,7 +80,7 @@ class MessageProcessor(code: String, private val salt: ByteArray? = null) {
|
|||||||
val decodedMessage : ByteArray = Base64.getUrlDecoder().decode(message)
|
val decodedMessage : ByteArray = Base64.getUrlDecoder().decode(message)
|
||||||
|
|
||||||
salt = decodedMessage.copyOfRange(0, SALT_LENGTH)
|
salt = decodedMessage.copyOfRange(0, SALT_LENGTH)
|
||||||
val iterationsDecoded = decodedMessage.copyOfRange(SALT_LENGTH, SALT_LENGTH+ ITERATIONS_LENGTH)
|
val iterationsDecoded = decodedMessage.copyOfRange(SALT_LENGTH, SALT_LENGTH + ITERATIONS_LENGTH)
|
||||||
val tokenString = String(Base64.getUrlEncoder().encode(decodedMessage.copyOfRange(20, decodedMessage.size)))
|
val tokenString = String(Base64.getUrlEncoder().encode(decodedMessage.copyOfRange(20, decodedMessage.size)))
|
||||||
|
|
||||||
iterations = BigInteger(iterationsDecoded).toInt()
|
iterations = BigInteger(iterationsDecoded).toInt()
|
91
app/src/main/java/com/example/bump/util/NotificationUtil.kt
Normal file
91
app/src/main/java/com/example/bump/util/NotificationUtil.kt
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package com.example.bump.util
|
||||||
|
|
||||||
|
import android.app.NotificationManager
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import com.example.bump.receiver.SnoozeReceiver
|
||||||
|
import com.example.bump.ui.MainActivity
|
||||||
|
import com.maenle.bump.R
|
||||||
|
|
||||||
|
// Notification ID.
|
||||||
|
private val NOTIFICATION_ID = 0
|
||||||
|
private val REQUEST_CODE = 0
|
||||||
|
private val FLAGS = 0
|
||||||
|
|
||||||
|
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
|
||||||
|
// Create the content intent for the notification, which launches
|
||||||
|
// this activity
|
||||||
|
// TODO: Step 1.11 create intent
|
||||||
|
val contentIntent = Intent(applicationContext, MainActivity::class.java)
|
||||||
|
// TODO: Step 1.12 create PendingIntent
|
||||||
|
val contentPendingIntent = PendingIntent.getActivity(
|
||||||
|
applicationContext,
|
||||||
|
NOTIFICATION_ID,
|
||||||
|
contentIntent,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO: Step 2.0 add style
|
||||||
|
val eggImage = BitmapFactory.decodeResource(
|
||||||
|
applicationContext.resources,
|
||||||
|
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
|
||||||
|
// Build the notification
|
||||||
|
val builder = NotificationCompat.Builder(
|
||||||
|
applicationContext,
|
||||||
|
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
|
||||||
|
.setSmallIcon(R.drawable.ic_launcher_foreground)
|
||||||
|
.setContentTitle(applicationContext
|
||||||
|
.getString(R.string.notification_title))
|
||||||
|
.setContentText(messageBody)
|
||||||
|
|
||||||
|
// TODO: Step 1.13 set content intent
|
||||||
|
.setContentIntent(contentPendingIntent)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
|
||||||
|
// TODO: Step 2.1 add style to builder
|
||||||
|
.setStyle(bigPicStyle)
|
||||||
|
.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
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
|
// TODO: Step 1.4 call notify
|
||||||
|
notify(NOTIFICATION_ID, builder.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Step 1.14 Cancel all notifications
|
||||||
|
/**
|
||||||
|
* Cancels all notifications.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
fun NotificationManager.cancelNotifications() {
|
||||||
|
cancelAll()
|
||||||
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package com.example.bump
|
package com.example.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.maenle.bump.MainActivity
|
import com.example.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=".MainActivity">
|
tools:context="com.example.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=".SecondFragment">
|
tools:context="com.example.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=".FirstFragment">
|
tools:context="com.example.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=".SecondFragment">
|
tools:context="com.example.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.MainActivity">
|
tools:context="com.maenle.bump.com.example.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.maenle.bump.FirstFragment"
|
android:name="com.example.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.maenle.bump.SecondFragment"
|
android:name="com.example.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.maenle.bump.CameraFragment"
|
android:name="com.example.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">
|
||||||
|
|
||||||
|
@ -14,4 +14,8 @@
|
|||||||
<string name="camera_fragment_label">Camera Fragment</string>
|
<string name="camera_fragment_label">Camera Fragment</string>
|
||||||
<string name="preference_file_key">code_file_key</string>
|
<string name="preference_file_key">code_file_key</string>
|
||||||
<string name="code_key">code_key</string>
|
<string name="code_key">code_key</string>
|
||||||
|
<string name="notification_title">Bump</string>
|
||||||
|
<string name="bump_notification_channel_id">bump_id</string>
|
||||||
|
<string name="snooze">Snooze</string>
|
||||||
|
<string name="bump_notification_channel_name">Bump</string>
|
||||||
</resources>
|
</resources>
|
Loading…
Reference in New Issue
Block a user