package com.error404.skins.services import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent import android.content.Intent import android.graphics.Bitmap import android.net.Uri import android.os.Build import androidx.core.app.NotificationCompat import com.error404.skins.MainActivity import com.error404.skins.R import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import java.net.URL class MyFirebaseMessagingService : FirebaseMessagingService() { override fun onNewToken(token: String) { super.onNewToken(token) // এই token সার্ভারে সেভ করে রাখতে পারেন (নির্দিষ্ট ইউজারকে নোটিফিকেশন পাঠানোর জন্য) } /** * ওয়েবসাইট থেকে পাঠানো মেসেজ এখন "data-only" (top-level notification নেই), * তাই এই মেথডটা সবসময় কল হবে — অ্যাপ চালু থাকুক, ব্যাকগ্রাউন্ডে থাকুক বা বন্ধ থাকুক * (ব্যাকগ্রাউন্ড রেস্ট্রিকশন থাকা কিছু ফোনে কম রেসপন্সিভ হতে পারে, এটা Android এর * স্বাভাবিক সীমাবদ্ধতা)। */ override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) val data = remoteMessage.data val title = data["title"] ?: "Update" val body = data["body"] ?: "" val imageUrl = data["image_url"] val clickType = data["click_type"] ?: "app" // "app" অথবা "link" val clickUrl = data["click_url"] val forceUpdate = data["force_update"] == "true" val updateUrl = data["update_url"] if (!imageUrl.isNullOrBlank()) { // ছবি ডাউনলোড করে BigPictureStyle নোটিফিকেশন দেখানো হয় (নেটওয়ার্ক কল, // তাই ব্যাকগ্রাউন্ড থ্রেডে করা হচ্ছে) CoroutineScope(Dispatchers.IO).launch { val bitmap = try { val connection = URL(imageUrl).openConnection() connection.doInput = true connection.connect() android.graphics.BitmapFactory.decodeStream(connection.getInputStream()) } catch (e: Exception) { null } showNotification(title, body, bitmap, clickType, clickUrl, forceUpdate, updateUrl) } } else { showNotification(title, body, null, clickType, clickUrl, forceUpdate, updateUrl) } } private fun showNotification( title: String, message: String, image: Bitmap?, clickType: String, clickUrl: String?, forceUpdate: Boolean, updateUrl: String? ) { val channelId = "update_channel" val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channel = NotificationChannel( channelId, "App Updates", NotificationManager.IMPORTANCE_HIGH ).apply { description = "নতুন ভার্সন ও গুরুত্বপূর্ণ আপডেট সংক্রান্ত নোটিফিকেশন" enableLights(true) enableVibration(true) } notificationManager.createNotificationChannel(channel) } // ট্যাপ করলে কোথায় যাবে — অ্যাপ, নাকি একটা ওয়েব লিংক val pendingIntent: PendingIntent = if (clickType == "link" && !clickUrl.isNullOrBlank()) { val linkIntent = Intent(Intent.ACTION_VIEW, Uri.parse(clickUrl)).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK } PendingIntent.getActivity( this, 0, linkIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) } else { val appIntent = Intent(this, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK putExtra("force_update", forceUpdate) putExtra("update_url", updateUrl) } PendingIntent.getActivity( this, 0, appIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) } val builder = NotificationCompat.Builder(this, channelId) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(title) .setContentText(message) .setAutoCancel(true) .setContentIntent(pendingIntent) .setPriority(NotificationCompat.PRIORITY_HIGH) .setCategory(NotificationCompat.CATEGORY_RECOMMENDATION) if (image != null) { // ছবি থাকলে বড় প্রিভিউ দেখানো হয় (BigPictureStyle) builder.setStyle( NotificationCompat.BigPictureStyle() .bigPicture(image) .bigLargeIcon(null as Bitmap?) .setSummaryText(message) ) builder.setLargeIcon(image) } else { // ছবি না থাকলে আগের মতোই বড় টেক্সট স্টাইল builder.setStyle(NotificationCompat.BigTextStyle().bigText(message)) } notificationManager.notify(1001, builder.build()) } }