package com.mottainai.driver.service
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.media.RingtoneManager
import android.os.Build
import android.util.Log
import androidx.core.app.NotificationCompat
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.mottainai.driver.R
import com.mottainai.driver.activity.SplashScreenActivity
class MyFirebaseMessagingService : FirebaseMessagingService() {
/**
* Called when message is received.
*
* @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
// [START receive_message]
override fun onMessageReceived(remoteMessage: RemoteMessage) {
// [START_EXCLUDE]
// There are two types of messages data messages and notification messages. Data messages
// are handled
// here in onMessageReceived whether the app is in the foreground or background. Data
// messages are the type
// traditionally used with GCM. Notification messages are only received here in
// onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated
// notification is displayed.
// When the user taps on the notification they are returned to the app. Messages
// containing both notification
// and data payloads are treated as notification messages. The Firebase console always
// sends notification
// [END_EXCLUDE]
// TODO(developer): Handle FCM messages here.
Log.d(
TAG,
"From: " + remoteMessage.from
)
// Check if message contains a data payload.
if (remoteMessage.data.size > 0) {
//sendNotification(remoteMessage.getData().toString());
Log.d(
TAG,
"Message data payload: " + remoteMessage.data
)
if ( /* Check if data needs to be processed by long running job */true) {
// For long-running tasks (10 seconds or more) use WorkManager.
scheduleJob()
} else {
// Handle message within 10 seconds
handleNow()
}
}
// Check if message contains a notification payload.
if (remoteMessage.notification != null) {
Log.d(
TAG,
"Message Notification Body: " + remoteMessage.notification!!.body
)
sendNotification(
remoteMessage.notification!!.title,
remoteMessage.notification!!.body
)
}
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
// [END receive_message]
// [START on_new_token]
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the InstanceID token
* is initially generated so this is where you would retrieve the token.
*/
override fun onNewToken(token: String) {
Log.d(TAG, "Refreshed token: $token")
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(token)
}
// [END on_new_token]
/**
* Schedule async work using WorkManager.
*/
private fun scheduleJob() {
// [START dispatch_job]
// OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(MyWorker.class)
// .build();
// WorkManager.getInstance().beginWith(work).enqueue();
// [END dispatch_job]
}
/**
* Handle time allotted to BroadcastReceivers.
*/
private fun handleNow() {
Log.d(TAG, "Short lived task is done.")
}
/**
* Persist token to third-party servers.
*
*
* Modify this method to associate the user's FCM InstanceID token with any server-side account
* maintained by your application.
*
* @param token The new token.
*/
private fun sendRegistrationToServer(token: String) {
// TODO: Implement this method to send token to your app server.
}
/**
* Create and show a simple notification containing the received FCM message.
*
* @param body FCM message body received.
*/
private fun sendNotification(title: String?, body: String?) {
val intent = Intent(this, SplashScreenActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(
this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT
)
val channelId = getString(R.string.default_notification_channel_id)
val defaultSoundUri =
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val vibrate = longArrayOf(500, 1000)
val notificationBuilder =
NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setVibrate(vibrate)
.setContentIntent(pendingIntent)
val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_HIGH
)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
}
companion object {
private const val TAG = "MyFirebaseMsgService"
}
}
//This is my service class . Everything is working fine here. From notification I want to launch splash screen which is working fine every time except one scenario. While my app is minimized clicking on notification it is opening the minimized activity instead of Splash screen activity which is my launcher activity. Can anyone please provide a solution for this?
package com.mottainai.driver.activity
//import com.google.firebase.analytics.FirebaseAnalytics
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.graphics.Point
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.telephony.TelephonyManager
import android.util.Base64
import android.view.View
import android.view.Window
import android.view.WindowManager
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import butterknife.BindView
import butterknife.ButterKnife
import com.mottainai.driver.MainApplication
import com.mottainai.driver.R
import com.mottainai.driver.api.CustomFastNetworking
import com.mottainai.driver.api.EndPoints
import com.mottainai.driver.api.NetworkMonitor
import com.mottainai.driver.apimodels.StatusObject
import com.mottainai.driver.customviews.CustomProgressBar
import com.mottainai.driver.helper.NavigationHelper
import com.mottainai.driver.util.Constant
import com.mottainai.driver.util.JsonObjectCreator
import com.mottainai.driver.util.LocalPreference
import com.mottainai.driver.util.PreferenceKeys
import rx.Observer
import rx.android.schedulers.AndroidSchedulers
import rx.schedulers.Schedulers
import java.util.*
import javax.inject.Inject
class SplashScreenActivity : AppCompatActivity() {
@Inject
lateinit var localPreference: LocalPreference
@Inject
lateinit var navigationHelper: NavigationHelper
@Inject
lateinit var networkMonitor: NetworkMonitor
//
@BindView(R.id.show_snack_txt)
lateinit var show_snack_txt: TextView
@BindView(R.id.snack_container)
lateinit var snack_container: LinearLayout
internal var isSnackShowing = false
lateinit var customProgressBar: CustomProgressBar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
this.window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN
)
if (!isTaskRoot
&& intent.hasCategory(Intent.CATEGORY_LAUNCHER)
&& intent.action != null
&& intent.action.equals(Intent.ACTION_MAIN)) {
finish()
return
}
setContentView(R.layout.activity_splash_screen)
customProgressBar= CustomProgressBar()
ButterKnife.bind(this)
MainApplication.instance.mainComponent!!.inject(this)
// slideToTop(task_imageView);
val loc = Locale("", getUserCountry(this)!!)
Constant.countryName=loc.displayCountry
getScreenWidth()
onNewIntent(getIntent())
}
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
setIntent(intent)
val handler = Handler(Looper.getMainLooper())
handler.postDelayed(Runnable {
navigate()
}, 2000)
}
fun getUserCountry(context: Context): String? {
try {
val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
val simCountry = tm.simCountryIso
if (simCountry != null && simCountry.length == 2) { // SIM country code is available
return simCountry.toLowerCase(Locale.US)
} else if (tm.phoneType != TelephonyManager.PHONE_TYPE_CDMA) { // device is not 3G (would be unreliable)
val networkCountry = tm.networkCountryIso
if (networkCountry != null && networkCountry.length == 2) { // network country code is available
return networkCountry.toLowerCase(Locale.US)
}
}
} catch (e: Exception) {
}
return null
}
private fun navigate(){
if(localPreference.getBoolean(PreferenceKeys.isLoggedIn))
if(localPreference.getLong(PreferenceKeys.SessionExitTime)>0 && System.currentTimeMillis()>(localPreference.getLong(
PreferenceKeys.SessionExitTime
)+Constant.SessionDuration))
{
if(networkMonitor.isConnected)
doLogOut()
else{
showSnack(R.string.no_internet, true)
val handler = Handler()
handler.postDelayed({
navigationHelper.finish(this)
}, 2600)
}
}
else
navigateToDashBoard()
else
navigateToLogin()
}
private fun navigateToLogin() {
navigationHelper.navigate(this@SplashScreenActivity, LoginActivity::class.java)
}
fun showSnack(message: String, isError: Boolean) {
isSnackShowing=true
if (isError)
show_snack_txt.setBackgroundColor(resources.getColor(R.color.snack_red))
else
show_snack_txt.setBackgroundColor(resources.getColor(R.color.snack_green))
snack_container.visibility = View.VISIBLE
show_snack_txt.text = message
val slide_down = AnimationUtils.loadAnimation(
applicationContext,
R.anim.slide_down
)
snack_container.startAnimation(slide_down)
val handler = Handler()
handler.postDelayed({ hideSnack() }, 2500)
//viewHolder.snack_container.setVisibility(0);
}
fun showSnack(message: Int, isError: Boolean) {
isSnackShowing=true
if (isError)
show_snack_txt.setBackgroundColor(resources.getColor(R.color.snack_red))
else
show_snack_txt.setBackgroundColor(resources.getColor(R.color.snack_green))
snack_container.visibility = View.VISIBLE
show_snack_txt.setText(message)
val slide_down = AnimationUtils.loadAnimation(
applicationContext,
R.anim.slide_down
)
snack_container.startAnimation(slide_down)
val handler = Handler()
handler.postDelayed({ hideSnack() }, 2500)
//viewHolder.snack_container.setVisibility(0);
}
private fun hideSnack() {
snack_container.visibility = View.GONE
val slide_up = AnimationUtils.loadAnimation(
applicationContext,
R.anim.slide_up_snack
)
snack_container.startAnimation(slide_up)
slide_up.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {
}
override fun onAnimationEnd(animation: Animation) {
isSnackShowing = false
}
override fun onAnimationRepeat(animation: Animation) {
}
})
}
// private fun navigate(){
//
// if(localPreference.getBoolean(PreferenceKeys.isLoggedIn))
// navigateToDashBoard()
// else
// navigateToLogin()
// }
private fun doLogOut() {
customProgressBar.show(this, resources.getString(R.string.please_wait))
CustomFastNetworking.callPostApi(
Constant.Basic + (Constant.UserName + ":" + Constant.Password).encode(),
Constant.ContentTypeValue, EndPoints.LogOutPoint,
JsonObjectCreator.prepareLogOutJsonObject(localPreference.initiateUser()!!.id.toString())
)
.getObjectObservable(StatusObject::class.java)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<StatusObject> {
override fun onCompleted() {
// do anything onComplete
}
override fun onError(e: Throwable) {
// handle error
customProgressBar.dismiss()
}
override fun onNext(response: StatusObject) {
customProgressBar.dismiss()
if (response.status!!) {
localPreference.clearPreferences()
navigateToLogin()
// var mActivityManager:ActivityManager = applicationContext.getSystemService(ACTIVITY_SERVICE) as ActivityManager
// mActivityManager.killBackgroundProcesses("com.mottainai.driver");
}
}
})
}
fun String.encode(): String {
return Base64.encodeToString(this.toByteArray(charset("UTF-8")), Base64.DEFAULT).replace(
"\n",
""
)
}
private fun getScreenWidth() {
val display = windowManager.defaultDisplay
val size = Point()
display.getSize(size)
Constant.Width = size.x
Constant.Height=size.y
}
fun navigateToDashBoard() {
navigationHelper.navigate(this@SplashScreenActivity, DashBoardActivity::class.java)
}
override fun onResume() {
super.onResume()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
}
}
//Still onNewIntent() is not getting called while app is minimized...launch mode is single top declared in manifest.Flags also tested with one shot and update current.Please suggest me something.