1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-07 21:37:02 +09:00

DROID-3413 fixes

This commit is contained in:
Evgenii Kozlov 2025-03-12 12:11:37 +01:00
parent 400aa4c5c7
commit f0e85c80c9
5 changed files with 121 additions and 0 deletions

View file

@ -245,6 +245,9 @@ dependencies {
implementation libs.wireRuntime
implementation(platform("com.google.firebase:firebase-bom:33.10.0"))
implementation "com.google.firebase:firebase-messaging"
//Unit/Integration tests dependencies
testImplementation libs.androidXTestCore
testImplementation libs.junit

View file

@ -160,6 +160,15 @@
</intent-filter>
<meta-data android:name="photopicker_activity:0:required" android:value="" />
</service>
<service
android:name="com.anytypeio.anytype.other.AnytypeFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
</manifest>

View file

@ -19,6 +19,8 @@ import com.anytypeio.anytype.di.main.DaggerMainComponent
import com.anytypeio.anytype.di.main.MainComponent
import com.anytypeio.anytype.middleware.discovery.MDNSProvider
import com.anytypeio.anytype.middleware.discovery.adresshandler.LocalNetworkAddressProvider
import com.google.android.gms.tasks.OnCompleteListener
import com.google.firebase.messaging.FirebaseMessaging
import javax.inject.Inject
import timber.log.Timber
@ -63,6 +65,18 @@ class AndroidApplication : Application(), HasComponentDependencies {
setupCrashReporter()
setupLocalNetworkAddressHandler()
setupNotificationChannel()
FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
if (!task.isSuccessful) {
Timber.e(task.exception, "Fetching FCM registration token failed")
return@OnCompleteListener
}
// Get new FCM registration token
val token = task.result
Timber.d("FCM registration token: $token")
})
}
private fun enableStrictMode() {

View file

@ -0,0 +1,62 @@
package com.anytypeio.anytype.other
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
import android.os.Build
import com.anytypeio.anytype.R
import androidx.core.app.NotificationCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import service.Service
import timber.log.Timber
class AnytypeFirebaseMessagingService : FirebaseMessagingService() {
override fun onNewToken(token: String) {
super.onNewToken(token)
// This callback is fired whenever a new token is generated for the device.
// Send this token to your app server for registration.
}
override fun onMessageReceived(remoteMessage: RemoteMessage) {
super.onMessageReceived(remoteMessage)
Timber.d("onMessageReceived")
// Check if message contains a data payload.
remoteMessage.data.let { data ->
Timber.d("onMessageReceivedData: $data")
}
// Check if message contains a notification payload.
remoteMessage.notification?.let { notification ->
val title = notification.title
val body = notification.body
// Display the notification
sendNotification(title, body)
}
}
private fun sendNotification(title: String?, body: String?) {
// Build and show a notification via NotificationManager
val channelId = "fcm_default_channel"
val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_anytype_qr_code_logo)
.setContentTitle(title)
.setContentText(body)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Create channel for Android Oreo and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel =
NotificationChannel(channelId, "FCM Channel", NotificationManager.IMPORTANCE_HIGH)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(System.currentTimeMillis().toInt(), notificationBuilder.build())
}
}

View file

@ -8,8 +8,10 @@ import android.graphics.Color
import android.os.Build
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.FragmentContainerView
import androidx.lifecycle.Lifecycle
@ -105,6 +107,7 @@ class MainActivity : AppCompatActivity(R.layout.activity_main), AppNavigation.Pr
setupWindowInsets()
inject()
setupTheme()
askNotificationPermission()
startAppUpdater()
@ -675,6 +678,36 @@ class MainActivity : AppCompatActivity(R.layout.activity_main), AppNavigation.Pr
componentManager().mainEntryComponent.release()
}
// Declare the launcher at the top of your Activity/Fragment:
private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
if (isGranted) {
// FCM SDK (and your app) can post notifications.
} else {
// TODO: Inform user that that your app will not show notifications.
}
}
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)
}
}
}
companion object {
const val AUTO_UPDATE_URL = "https://fra1.digitaloceanspaces.com/anytype-release/latest-android.json"
const val SHARE_DIALOG_LABEL = "anytype.dialog.share.label"