WIP notificaciones push
This commit is contained in:
parent
896912d514
commit
c87e12caab
@ -61,6 +61,7 @@ dependencies {
|
|||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
|
implementation "androidx.datastore:datastore-preferences:1.0.0"
|
||||||
|
|
||||||
// Hilt
|
// Hilt
|
||||||
implementation "com.google.dagger:hilt-android:2.47"
|
implementation "com.google.dagger:hilt-android:2.47"
|
||||||
@ -131,5 +132,5 @@ dependencies {
|
|||||||
implementation(platform("com.google.firebase:firebase-bom:32.7.1"))
|
implementation(platform("com.google.firebase:firebase-bom:32.7.1"))
|
||||||
implementation("com.google.firebase:firebase-crashlytics")
|
implementation("com.google.firebase:firebase-crashlytics")
|
||||||
implementation("com.google.firebase:firebase-analytics")
|
implementation("com.google.firebase:firebase-analytics")
|
||||||
|
implementation("com.google.firebase:firebase-messaging-ktx")
|
||||||
}
|
}
|
||||||
@ -1,9 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
<application
|
<application
|
||||||
android:name=".MyApplication"
|
android:name=".MyApplication"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@ -50,6 +51,15 @@
|
|||||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
android:resource="@xml/provider_paths"/>
|
android:resource="@xml/provider_paths"/>
|
||||||
</provider>
|
</provider>
|
||||||
|
<service android:name=".push_notifications.FcmService"
|
||||||
|
android:exported="false">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.google.firebase.MESSAGING_EVENT" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</service>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
<uses-permission android:name="android.permission.INTERNET"/>
|
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
@ -1,10 +1,16 @@
|
|||||||
package com.isolaatti
|
package com.isolaatti
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
|
import androidx.datastore.core.DataStore
|
||||||
|
import androidx.datastore.preferences.core.Preferences
|
||||||
|
import androidx.datastore.preferences.preferencesDataStore
|
||||||
import com.isolaatti.connectivity.ConnectivityCallbackImpl
|
import com.isolaatti.connectivity.ConnectivityCallbackImpl
|
||||||
import dagger.hilt.android.HiltAndroidApp
|
import dagger.hilt.android.HiltAndroidApp
|
||||||
|
|
||||||
|
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
|
||||||
|
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
class MyApplication : Application() {
|
class MyApplication : Application() {
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,21 @@
|
|||||||
package com.isolaatti.home
|
package com.isolaatti.home
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.Observer
|
import androidx.datastore.preferences.core.edit
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.isolaatti.R
|
import com.isolaatti.R
|
||||||
import com.isolaatti.common.IsolaattiBaseActivity
|
import com.isolaatti.common.IsolaattiBaseActivity
|
||||||
|
import com.isolaatti.dataStore
|
||||||
import com.isolaatti.databinding.ActivityHomeBinding
|
import com.isolaatti.databinding.ActivityHomeBinding
|
||||||
import com.isolaatti.home.presentation.FeedViewModel
|
import com.isolaatti.home.presentation.FeedViewModel
|
||||||
|
|
||||||
@ -16,6 +23,18 @@ class HomeActivity : IsolaattiBaseActivity() {
|
|||||||
private lateinit var viewBinding: ActivityHomeBinding
|
private lateinit var viewBinding: ActivityHomeBinding
|
||||||
private val feedViewModel: FeedViewModel by viewModels()
|
private val feedViewModel: FeedViewModel by viewModels()
|
||||||
|
|
||||||
|
private val requestPermissionLauncher = registerForActivityResult(
|
||||||
|
ActivityResultContracts.RequestPermission(),
|
||||||
|
) { isGranted: Boolean ->
|
||||||
|
if (!isGranted) {
|
||||||
|
MaterialAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.push_notifications_dialog_title)
|
||||||
|
.setMessage(R.string.push_notifications_dialog_rejected_message)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
viewBinding = ActivityHomeBinding.inflate(layoutInflater)
|
viewBinding = ActivityHomeBinding.inflate(layoutInflater)
|
||||||
@ -24,6 +43,8 @@ class HomeActivity : IsolaattiBaseActivity() {
|
|||||||
viewBinding.bottomNavigation?.setupWithNavController(navHostFragment.navController)
|
viewBinding.bottomNavigation?.setupWithNavController(navHostFragment.navController)
|
||||||
viewBinding.navigationRail?.setupWithNavController(navHostFragment.navController)
|
viewBinding.navigationRail?.setupWithNavController(navHostFragment.navController)
|
||||||
|
|
||||||
|
askNotificationPermission()
|
||||||
|
|
||||||
if(savedInstanceState == null) {
|
if(savedInstanceState == null) {
|
||||||
feedViewModel.getFeed(false)
|
feedViewModel.getFeed(false)
|
||||||
}
|
}
|
||||||
@ -34,7 +55,28 @@ class HomeActivity : IsolaattiBaseActivity() {
|
|||||||
return super.onCreateOptionsMenu(menu)
|
return super.onCreateOptionsMenu(menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
private fun askNotificationPermission() {
|
||||||
super.onDestroy()
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) ==
|
||||||
|
PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
|
||||||
|
} else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
|
||||||
|
MaterialAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.push_notifications_dialog_title)
|
||||||
|
.setMessage(R.string.push_notifications_dialog_message)
|
||||||
|
.setPositiveButton(R.string.accept) { _, _ ->
|
||||||
|
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.no, null)
|
||||||
|
.show()
|
||||||
|
} else {
|
||||||
|
// Directly ask for the permission
|
||||||
|
requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.isolaatti.home.notifications.data
|
||||||
|
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Query
|
||||||
|
|
||||||
|
interface NotificationsApi {
|
||||||
|
@GET("/api/Notifications/list")
|
||||||
|
fun getNotifications(@Query("after") after: Long?): Call<NotificationsDto>
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package com.isolaatti.home.notifications.data
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime
|
||||||
|
|
||||||
|
data class NotificationsDto(
|
||||||
|
val result: List<NotificationDto>
|
||||||
|
)
|
||||||
|
|
||||||
|
data class NotificationDto(
|
||||||
|
val id: Long,
|
||||||
|
val date: ZonedDateTime,
|
||||||
|
val userId: Int,
|
||||||
|
val read: Boolean,
|
||||||
|
val payload: NotificationPayload
|
||||||
|
)
|
||||||
|
|
||||||
|
data class NotificationPayload(
|
||||||
|
val type: String,
|
||||||
|
val authorId: Int,
|
||||||
|
val authorName: String?,
|
||||||
|
val intentData: String?
|
||||||
|
)
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package com.isolaatti.push_notifications
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.google.firebase.messaging.FirebaseMessagingService
|
||||||
|
import dagger.hilt.EntryPoint
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class FcmService : FirebaseMessagingService() {
|
||||||
|
companion object {
|
||||||
|
const val LOG_TAG = "FcmService"
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var pushNotificationsApi: PushNotificationsApi
|
||||||
|
|
||||||
|
override fun onNewToken(token: String) {
|
||||||
|
|
||||||
|
pushNotificationsApi.registerDevice(token)
|
||||||
|
Log.d(LOG_TAG, token)
|
||||||
|
}
|
||||||
|
}
|
||||||
16
app/src/main/java/com/isolaatti/push_notifications/Module.kt
Normal file
16
app/src/main/java/com/isolaatti/push_notifications/Module.kt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package com.isolaatti.push_notifications
|
||||||
|
|
||||||
|
import com.isolaatti.connectivity.RetrofitClient
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
class Module {
|
||||||
|
@Provides
|
||||||
|
fun providePushNotificationsApi(retrofitClient: RetrofitClient): PushNotificationsApi {
|
||||||
|
return retrofitClient.client.create(PushNotificationsApi::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.isolaatti.push_notifications
|
||||||
|
|
||||||
|
import retrofit2.Call
|
||||||
|
import retrofit2.http.Multipart
|
||||||
|
import retrofit2.http.PUT
|
||||||
|
import retrofit2.http.Part
|
||||||
|
|
||||||
|
interface PushNotificationsApi {
|
||||||
|
|
||||||
|
@PUT("/api/push_notifications/register_device")
|
||||||
|
@Multipart
|
||||||
|
fun registerDevice(@Part("token") token: String): Call<Any>
|
||||||
|
|
||||||
|
}
|
||||||
6
app/src/main/res/layout/dialog_push_notifications.xml
Normal file
6
app/src/main/res/layout/dialog_push_notifications.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@ -186,4 +186,7 @@
|
|||||||
<string name="select_audio">Select audio</string>
|
<string name="select_audio">Select audio</string>
|
||||||
<string name="delete_audio_message">Do you really want to remove this audio? Discussions with this audio linked will still be pointing to it.</string>
|
<string name="delete_audio_message">Do you really want to remove this audio? Discussions with this audio linked will still be pointing to it.</string>
|
||||||
<string name="delete_audio_title">Remove audio?</string>
|
<string name="delete_audio_title">Remove audio?</string>
|
||||||
|
<string name="push_notifications_dialog_title">Push notifications</string>
|
||||||
|
<string name="push_notifications_dialog_message">Receive notifications to stay informed about your profile activity</string>
|
||||||
|
<string name="push_notifications_dialog_rejected_message">You won\'t receive notifications. You can change this on your device settings.</string>
|
||||||
</resources>
|
</resources>
|
||||||
Loading…
x
Reference in New Issue
Block a user