Skip to content

Commit

Permalink
feat: push notification service and related updates (JunTingLin#31)
Browse files Browse the repository at this point in the history
* feat: push notification service

* update: notification layout

* update: app icon

* update: change push notification host platform
  • Loading branch information
bosh-wang authored Sep 3, 2023
1 parent e1406fd commit e0dd0da
Show file tree
Hide file tree
Showing 27 changed files with 272 additions and 11 deletions.
12 changes: 11 additions & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'com.google.gms.google-services' // Firebase cloud messaging
}

android {
Expand Down Expand Up @@ -74,4 +75,13 @@ dependencies {

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2"

}
//Firebase cloud messaging
implementation(platform("com.google.firebase:firebase-bom:32.2.2"))
implementation("com.google.firebase:firebase-analytics-ktx")
implementation 'com.google.firebase:firebase-messaging-ktx:23.2.1'

}

//Firebase cloud messaging
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
39 changes: 39 additions & 0 deletions app/google-services.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"project_info": {
"project_number": "492668968463",
"project_id": "fcm-push-notification-e4aec",
"storage_bucket": "fcm-push-notification-e4aec.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:492668968463:android:0678bdeeba840fcb938d7a",
"android_client_info": {
"package_name": "com.junting.drug_android_frontend"
}
},
"oauth_client": [
{
"client_id": "492668968463-vp40cg6ueq2vu2l58cjqn3uckn07dvnn.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDifL__af4zqstAbbX2j4u2RCZ-kVra6IQ"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "492668968463-vp40cg6ueq2vu2l58cjqn3uckn07dvnn.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
19 changes: 19 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />

<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

<!-- permission of bluetooth connection-->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
Expand Down Expand Up @@ -34,6 +36,14 @@
android:usesCleartextTraffic="true"
tools:targetApi="31">

<!-- Firebase cloud messaging -->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/app_image" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/black" />

<activity
android:name=".IntroductoryActivity"
android:exported="false" />
Expand Down Expand Up @@ -88,6 +98,15 @@
android:exported="false"
android:label="@string/photo_confirmation_page" />

<!--Firebase cloud messaging-->
<service
android:name=".MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>

</application>

</manifest>
Binary file added app/src/main/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
package com.junting.drug_android_frontend

import android.Manifest
import android.content.BroadcastReceiver
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.MenuItem
import android.widget.ImageView
import android.widget.SeekBar
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.view.GravityCompat
import androidx.navigation.NavController
import androidx.navigation.NavDestination
Expand All @@ -19,6 +26,7 @@ import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.navigation.NavigationView
import com.google.firebase.messaging.FirebaseMessaging
import com.junting.drug_android_frontend.databinding.ActivityMainBinding
import com.junting.drug_android_frontend.databinding.FontSizeDialogLayoutBinding
import com.junting.drug_android_frontend.libs.FontSizeManager
Expand All @@ -27,6 +35,12 @@ import com.junting.drug_android_frontend.libs.SharedPreferencesManager
import com.junting.drug_android_frontend.ui.libs.updater.UpdateUIHelper
import com.squareup.picasso.Picasso
import java.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.net.HttpURLConnection
import java.net.URL
import java.util.Locale


class MainActivity : AppCompatActivity() {
Expand Down Expand Up @@ -170,6 +184,20 @@ class MainActivity : AppCompatActivity() {
navController.navigate(R.id.navigation_pillBoxManagement)
}
setupUpdateUIListener()

// sending FCM token
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
if (task.isSuccessful) {
val token = task.result
Log.d("FCM Token", "Token: $token")
sendTokenToServer(token)
} else {
Log.e("FCM Token", "Error getting token: ${task.exception}")
}
}

//check push notification permission
askNotificationPermission()
}

// out of onCreate
Expand Down Expand Up @@ -301,4 +329,48 @@ class MainActivity : AppCompatActivity() {
super.onDestroy()
UpdateUIHelper.unListen(baseContext, setTodayReminderBadgeReceiver)
}

fun sendTokenToServer(token: String) {
GlobalScope.launch(Dispatchers.IO) {
val url = URL("https://bosh.pythonanywhere.com/addToken/${token}")

try {
val connection = url.openConnection() as HttpURLConnection
connection.requestMethod = "GET"

val responseCode = connection.responseCode
Log.d("FCM token", "Response Code: $responseCode")
} catch (e: Exception) {
e.printStackTrace()
}
}
}

private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
if (isGranted) {
// FCM SDK (and your app) can post notifications.
} else {
Toast.makeText(this, "你不能收到吃藥通知", Toast.LENGTH_SHORT).show()
}
}
private fun askNotificationPermission() {
// This is only necessary for API level >= 33 (TIRAMISU)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
PackageManager.PERMISSION_GRANTED
) {
// FCM SDK (and your app) can post notifications.
} else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
// TODO: display an educational UI explaining to the user the features that will be enabled
// by them granting the POST_NOTIFICATION permission. This UI should provide the user
// "OK" and "No thanks" buttons. If the user selects "OK," directly request the permission.
// If the user selects "No thanks," allow the user to continue without notifications.
} else {
// Directly ask for the permission
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.junting.drug_android_frontend

import android.annotation.SuppressLint
import com.google.firebase.messaging.FirebaseMessagingService

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import com.google.firebase.messaging.RemoteMessage

const val channelId = "notification_channel"
const val channelName = "com.junting.drug_android_frontend"
class MyFirebaseMessagingService : FirebaseMessagingService(){

override fun onNewToken(token: String) {
Log.d("New token", "$token")
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {

// if (remoteMessage.data.isNotEmpty()) {
Log.d("Message", remoteMessage.notification!!.title!!)
generateNotification(remoteMessage.notification!!.title!!, remoteMessage.notification!!.body!!)
// }
}

// @SuppressLint("RemoteViewLayout")
// fun getRemoteView(notificationTitle: String, notificationDescription: String) : RemoteViews{
//
// val remoteViews = RemoteViews("com.junting.drug_android_frontend", R.layout.notification)
//
// remoteViews.setTextViewText(R.id.notification_title, notificationTitle)
// remoteViews.setTextViewText(R.id.notification_description, notificationDescription)
// remoteViews.setImageViewResource(R.id.notification_logo, R.drawable.app_image)
//
// return remoteViews
// }
fun generateNotification(notificationTitle: String, notificationDescription: String){

val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

val pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE)

var builder: NotificationCompat.Builder = NotificationCompat.Builder(applicationContext, channelId)
.setSmallIcon(R.drawable.app_image)
.setContentTitle(notificationTitle)
.setContentText(notificationDescription)
.setAutoCancel(true)
.setVibrate(longArrayOf(1000, 1000, 1000, 1000))
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent)


// builder = builder.setContent(getRemoteView(notificationTitle, notificationDescription))

val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
val notificationChannel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(notificationChannel)
}

notificationManager.notify(0, builder.build())
}
}
46 changes: 46 additions & 0 deletions app/src/main/res/layout/notification.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
tools:ignore="UselessParent">

<ImageView
android:id="@+id/notification_logo"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:src="@drawable/app_image"/>

<TextView
android:id="@+id/notification_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:textSize="20sp"
android:textStyle="bold"
android:layout_toRightOf="@id/notification_logo"
android:layout_marginLeft="10dp"
android:layout_marginTop="15dp"/>

<TextView
android:id="@+id/notification_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is description"
android:textSize="20sp"
android:textStyle="normal"
android:layout_toRightOf="@id/notification_logo"
android:layout_below="@+id/notification_title"
android:layout_marginLeft="10dp" />

</RelativeLayout>


</RelativeLayout>
4 changes: 2 additions & 2 deletions app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
4 changes: 2 additions & 2 deletions app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
6 changes: 0 additions & 6 deletions app/src/main/res/mipmap-anydpi-v33/ic_launcher.xml

This file was deleted.

Binary file modified app/src/main/res/mipmap-hdpi/ic_launcher.webp
Binary file not shown.
Binary file not shown.
Binary file modified app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
Binary file not shown.
Binary file modified app/src/main/res/mipmap-mdpi/ic_launcher.webp
Binary file not shown.
Binary file not shown.
Binary file modified app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
Binary file not shown.
Binary file modified app/src/main/res/mipmap-xhdpi/ic_launcher.webp
Binary file not shown.
Binary file not shown.
Binary file modified app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
Binary file not shown.
Binary file modified app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
Binary file not shown.
Binary file not shown.
Binary file modified app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
Binary file not shown.
Binary file modified app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
Binary file not shown.
Binary file not shown.
Binary file modified app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
Binary file not shown.
4 changes: 4 additions & 0 deletions app/src/main/res/values/ic_launcher_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#A7D7B8</color>
</resources>
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
dependencies {
classpath 'com.google.gms:google-services:4.3.15'
}
}
plugins {
id 'com.android.application' version '7.4.1' apply false
id 'com.android.library' version '7.4.1' apply false
id 'org.jetbrains.kotlin.android' version '1.7.21' apply false
id 'com.google.gms.google-services' version '4.3.15' apply false // Firebase cloud messaging
}

0 comments on commit e0dd0da

Please sign in to comment.