Monday, 6 November 2017

RecyclerView Android Example


PaymentsHistoryActivity

package com.demo
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import android.view.MenuItem
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.demo.R
import com.demo.global.Constant
import com.demo.global.Utils
import com.demo.models.CommonModel
import com.demo.models.PaymentsModel
import com.demo.patient.adapters.PaymentsHistoryAdapter
import com.demo.restapi.ApiInterface
import com.demo.restapi.ParseController
import kotlinx.android.synthetic.main.pd_activity_common.*
import kotlinx.android.synthetic.main.toolbar.*
import retrofit2.Response

class PaymentsHistoryActivity : AppCompatActivity() {

    private var intTotal: Int = 0
    private var intPage: Int = 1
    private var type: String = Constant.pay
    private var isLoadMore: Boolean = false
    private val arrayList = ArrayList<PaymentsModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.pd_activity_common)

        //Toolbar
        setSupportActionBar(toolbar)
        supportActionBar!!.setDisplayShowTitleEnabled(false)
        supportActionBar!!.setDisplayHomeAsUpEnabled(true)
        toolbar.title = ""
        tvToolbarTitle.text = getString(R.string.payments_history)

        val bundle = intent.extras
        if (bundle != null && Utils.isNotEmptyString(bundle.getString(Constant.type))) {
            type = Utils.chkStr(bundle.getString(Constant.type))
        }

        initUI()
    }

    private fun initUI() {
        val layoutManager = LinearLayoutManager(this)
        recyclerView.layoutManager = layoutManager
        tvNoDataFound.setOnClickListener { refreshData(true) }

        //Pull down to refresh data
        swpRefLayout.setColorSchemeResources(R.color.colorPrimary)
        swpRefLayout.setOnRefreshListener {
            refreshData(false)
        }

        //Pull up to load more data
        recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                val position = layoutManager.findLastCompletelyVisibleItemPosition()
                if (isLoadMore && intTotal != arrayList.size && position == arrayList.size - Constant.loadMore) {
                    isLoadMore = false
                    progressBar.visibility = View.VISIBLE
                    getPaymentHistory(false)
                }
            }
        })

        getPaymentHistory(true)
    }

    private fun getPaymentHistory(showShimmer: Boolean) {
        if (showShimmer) {
            shimmerLayout.visibility = View.VISIBLE
            shimmerLayout.startShimmer()
        }

        val hashMap = HashMap<String, String>()
        hashMap[Constant.type] = type
        hashMap[Constant.page] = intPage.toString()

        val call = ApiInterface.create(this).postMethod(Constant.getPaymentHistory, hashMap)
        ParseController(this, call, false,
            resources.getString(R.string.loading), object : ParseController.ApiCompleteListener {
                override fun <T> onSuccessResponse(jsonResponse: Response<T>) {
                    try {
                        val response = jsonResponse.body() as CommonModel?
                        if (response != null) {
                            val code = Utils.chkStr(response.code)
                            val message = Utils.chkStr(response.message)
                            when (code) {
                                Constant._200 -> {
                                    if (response.data != null && response.data!!.payments != null) {
                                        intTotal = Utils.chkInt(response.data!!.total)
                                        if (response.data!!.payments!!.isNotEmpty()) {
                                            arrayList.addAll(response.data!!.payments!!)
                                            isLoadMore = true
                                            intPage++
                                        }
                                    }
                                }
                                Constant._401 -> Utils.logout(this@PaymentsHistoryActivity, message)
                                else -> Utils.showSnackBar(crLayout, message)
                            }
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                    setData()
                }

                override fun onFailedResponse(statusCode: Int, message: String) {
                    Utils.showSnackBar(crLayout, message)
                    setData()
                }
            })
    }

    private fun setData() {
        //Here all loader hidden and closed
        swpRefLayout.isRefreshing = false
        shimmerLayout.stopShimmer()
        shimmerLayout.visibility = View.GONE
        progressBar.visibility = View.GONE

        //Here shown all payment history
        if (arrayList.isNotEmpty()) {
            recyclerView.visibility = View.VISIBLE
            tvNoDataFound.visibility = View.GONE
            if (recyclerView.adapter == null) {
                recyclerView.adapter = PaymentsHistoryAdapter(this, type, arrayList)
            } else {
                recyclerView.adapter!!.notifyDataSetChanged()
            }
        } else {
            recyclerView.visibility = View.GONE
            tvNoDataFound.visibility = View.VISIBLE
        }
    }

    private fun refreshData(showShimmer: Boolean) {
        intPage = 1
        intTotal = 0
        arrayList.clear()
        if (recyclerView.adapter != null) {
            recyclerView.adapter!!.notifyDataSetChanged()
        }
        getPaymentHistory(showShimmer)
    }

    // Back button
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when (item.itemId) {
            android.R.id.home -> {
                Utils.hideKeyboard(this)
                this.finish()
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }
}



PaymentsHistoryAdapter

package com.demo.patient.adapters
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.PopupMenu
import androidx.recyclerview.widget.RecyclerView
import com.demo.R
import com.demo.global.Constant
import com.demo.global.Utils
import com.demo.models.PaymentsModel
import kotlinx.android.synthetic.main.p_item_payments_history.view.*
import java.util.*

class PaymentsHistoryAdapter(
    private val context: Context,
    private val type: String,
    private val arrayList: ArrayList<PaymentsModel>
) : RecyclerView.Adapter<PaymentsHistoryAdapter.ViewHolder>() {

    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.p_item_payments_history, parent, false)
        return ViewHolder(view)
    }

    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val model = arrayList[position]

        if (model.appointment != null) {
            if (type == Constant.pay) {
                var name = ""
                name = if (model.appointment!!.doctor != null) {
                    Utils.chkStr(model.appointment!!.doctor!!.name)
                } else {
                    Utils.chkStr(model.appointment!!.diagnostics!!.name)
                }
                holder.itemView.tvPaidTo.text = name
            } else {
                //received
                holder.itemView.tvPaidToTitle.text =
                    context.resources.getString(R.string.received_from)
                holder.itemView.tvPaidTo.text = Utils.chkStr(model.appointment!!.patient_name)
            }
        }
        // Amount
        val symbol = Utils.chkStr(model.symbol)
        holder.itemView.tvAmount.text = symbol + Utils.chkStrAndReturnInt(model.amount) + "/-"

        if (Utils.isNotEmptyString(Utils.chkStr(model.refund_amount))) {
            holder.itemView.tvRefunded.visibility = View.GONE
        }

        val txnDate = Utils.chkStr(model.txn_date)
        holder.itemView.tvDateAndTime.text =
            Utils.dateFormat(txnDate, Constant.yyyy_mm_dd_hh_mm_ss, Constant.dd_mm_yyyy_hh_mm_a)

        holder.itemView.imgMoreMenu.setOnClickListener {
            val popup = PopupMenu(context, it)
            popup.menuInflater.inflate(R.menu.poupup_menu, popup.menu)
            popup.menu.findItem(R.id.invoice).isVisible = true

            popup.setOnMenuItemClickListener { item ->
                when (item.title) {
                    context.resources.getString(R.string.invoice) -> {
                        val intent = Intent()
                        intent.setDataAndType(Uri.parse(Utils.chkStr(model.invoice)), "application/pdf")
                        context.startActivity(intent)
                    }
                }
                true
            }
            popup.show()
        }
    }

    override fun getItemCount(): Int {
        return arrayList.size
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getItemViewType(position: Int): Int {
        return position
    }
}



 


PaymentsModel

package com.demo.models

import com.google.gson.annotations.SerializedName
import com.demo.global.Constant

class PaymentsModel {

    @SerializedName(Constant.id)
    var id: String? = null

    @SerializedName(Constant.invoice)
    var invoice: String? = null

    @SerializedName(Constant.symbol)
    var symbol: String? = null

    @SerializedName(Constant.refund_amount)
    var refund_amount: String? = null

    //appointment object
    @SerializedName(Constant.appointment)
    var appointment: Appointment? = null

    class Appointment {
        @SerializedName(Constant.id)
        var id: String? = null

        @SerializedName(Constant.patient_name)
        var patient_name: String? = null

        //doctor object
        @SerializedName(Constant.doctor)
        var doctor: Doctor? = null

        class Doctor {
            @SerializedName(Constant.name)
            var name: String? = null
        }

        //doctor object
        @SerializedName(Constant.diagnostics)
        var diagnostics: Diagnostics? = null

        class Diagnostics {
            @SerializedName(Constant.name)
            var name: String? = null
        }
    }

    //files object
    @SerializedName(Constant.prescriptions)
    var prescriptions: ArrayList<AppointmentModel.PrescriptionModel>? = null

    class Practice {
        @SerializedName(Constant.id)
        var id: String? = null

        @SerializedName(Constant.name)
        var name: String? = null
    }
}

Utils

package com.demo.interfaces

import android.annotation.SuppressLint
import android.app.*
import android.content.*
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Color
import android.location.LocationManager
import android.net.ConnectivityManager
import android.net.Uri
import android.os.Build
import android.os.Handler
import android.provider.Settings
import android.text.Html
import android.text.Spanned
import android.text.TextUtils
import android.text.format.DateFormat
import android.util.Base64
import android.util.Base64.encodeToString
import android.util.Log
import android.util.Patterns
import android.view.Gravity
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.appcompat.widget.LinearLayoutCompat
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.Priority
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.google.android.gms.tasks.OnCompleteListener
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.textfield.TextInputEditText
import com.google.firebase.messaging.FirebaseMessaging
import com.hbb20.CountryCodePicker
import com.demo.R
import com.demo.activities.GetOtpActivity
import com.demo.activities.MainActivity
import com.demo.activities.PreviewImageActivity
import com.demo.doctor.adapters.SingleSelectionAdapter
import com.demo.models.UserModel
import com.demo.models.SpinnerModel
import com.demo.videocall.FBData
import com.demo.videocall.FloatingService
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.UnsupportedEncodingException
import java.text.DecimalFormat
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit

object Utils {
    var isDebugging = true

    // Get current time and date
    @SuppressLint("SimpleDateFormat")
    fun getCurrentTimeAndDate(inputFormat: String): String {
        if (isNotEmptyString(inputFormat)) {
            val sdf = SimpleDateFormat(inputFormat, Locale.getDefault())
            return sdf.format(Date())
        }
        return ""
    }


    // Date format
    @SuppressLint("SimpleDateFormat")
    fun dateFormat(inputDate: String, inputFormat: String, outputFormat: String): String {
        if (isNotEmptyString(inputDate) && isNotEmptyString(inputFormat) && isNotEmptyString(
                        outputFormat
                )
        ) {
            try {
                var sdf = SimpleDateFormat(inputFormat)
                val newDate = sdf.parse(inputDate)
                sdf = SimpleDateFormat(outputFormat)
                return sdf.format(newDate!!)
            } catch (e: Exception) {
                Log.e("Exception", e.message.toString())
            }
        }
        return ""
    }

    // Format date and time
    @SuppressLint("SimpleDateFormat")
    fun localizedDateFormat(inputDate: String, inputFormat: String): String {
        if (isNotEmptyString(inputDate) && isNotEmptyString(inputFormat)) {
            val sdf = SimpleDateFormat(inputFormat, Locale.ENGLISH)
            sdf.timeZone = TimeZone.getTimeZone("UTC")
            val date = sdf.parse(inputDate)
            sdf.timeZone = TimeZone.getDefault()
            return sdf.format(date!!)
        }
        return ""
    }

    fun simpleDateFormat(date: Date, outputFormat: String): String? {
        val format = SimpleDateFormat(outputFormat, Locale.getDefault())
        return format.format(date)
    }

    // Time stamp to date format
    fun timeStampToDateFormat(inputTimeStamp: String, outputFormat: String): String {
        if (isNotEmptyString(inputTimeStamp) && isNotEmptyString(outputFormat)) {
            val time = inputTimeStamp.toLong()
            val cal = Calendar.getInstance()
            cal.timeInMillis = time * 1000
            return DateFormat.format(outputFormat, cal).toString()
        }
        return ""
    }

    // Get current time stamp
    fun getCurrentTimeStamp(): String {
        //val timeStamp = System.currentTimeMillis() / 1000
        val c = Calendar.getInstance()
        val sdf = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ", Locale.ENGLISH)
        //Log.e("TIME", "formatted string: " + sdf.format(c.time))
        return sdf.format(c.time).toString()
    }

    // Get current time stamp
    fun getCarbonToDateTime(carbonString: String): String {
        //val timeStamp = System.currentTimeMillis() / 1000
        val c = Calendar.getInstance()
        val sdf = SimpleDateFormat("yy-MM-dd HH:mm", Locale.ENGLISH)
        Log.e("TIME", "formatted string: " + sdf.format(carbonString))
        return sdf.format(c.time).toString()
    }

    // Compare tow date
    fun compareTowDate(startDate: String, endDate: String, inputFormat: String): Boolean {
        if (isNotEmptyString(startDate) && isNotEmptyString(endDate) && isNotEmptyString(inputFormat)) {
            try {
                @SuppressLint("SimpleDateFormat")
                val formatter = SimpleDateFormat(inputFormat)
                val date1 = formatter.parse(startDate)
                val date2 = formatter.parse(endDate)
                if (date1!! < date2) {
                    return true
                }
            } catch (e1: ParseException) {
                e1.printStackTrace()
            }
        }
        return false
    }

    // Format UTC time zone
    @SuppressLint("SimpleDateFormat")
    fun formatUtcTimeZone(inputDate: String, inputFormat: String): String? {
        if (isNotEmptyString(inputDate) && isNotEmptyString(inputFormat)) {
            var convertTime = ""
            try {
                val dateFormat = SimpleDateFormat(inputFormat)
                dateFormat.timeZone = TimeZone.getTimeZone("UTC")
                val pastTime = dateFormat.parse(inputDate)
                val currentTime = Date()
                val dateDiff = currentTime.time - pastTime!!.time
                val second = TimeUnit.MILLISECONDS.toSeconds(dateDiff)
                val minute = TimeUnit.MILLISECONDS.toMinutes(dateDiff)
                val hour = TimeUnit.MILLISECONDS.toHours(dateDiff)
                val day = TimeUnit.MILLISECONDS.toDays(dateDiff)
                when {
                    second < 60 -> //convertTime = second.toString() + "s " + suffix
                        convertTime = "just now"
                    minute < 60 -> convertTime = minute.toString() + "m"
                    hour < 24 -> convertTime = hour.toString() + "hr"
                    day >= 7 -> convertTime = when {
                        day > 30 -> (day / 30).toString() + "mo"
                        day > 360 -> (day / 360).toString() + "y"
                        else -> (day / 7).toString() + "w"
                    }
                    day < 7 -> convertTime = day.toString() + "d"
                }
                return convertTime
            } catch (e: ParseException) {
                e.printStackTrace()
            }
        }
        return ""
    }

    // Format number
    fun formatNumber(value: Long?): String {
        if (value != null) {
            val suffixes = TreeMap<Long, String>()
            suffixes[1_000L] = "K"
            suffixes[1_000_000L] = "M"
            suffixes[1_000_000_000L] = "G"
            suffixes[1_000_000_000_000L] = "T"
            suffixes[1_000_000_000_000_000L] = "P"
            suffixes[1_000_000_000_000_000_000L] = "E"
            //Long.MIN_VALUE == -Long.MIN_VALUE so we need an adjustment here
            if (value == java.lang.Long.MIN_VALUE) return formatNumber(java.lang.Long.MIN_VALUE + 1)
            if (value < 0) return "-" + formatNumber(-value)
            if (value < 1000) return value.toString() //deal with easy case

            val e = suffixes.floorEntry(value)
            val divideBy = e!!.key
            val suffix = e.value

            val truncated = value / (divideBy!! / 10) //the number part of the output times 10
            val hasDecimal = truncated < 100 && truncated / 10.0 != (truncated / 10).toDouble()
            return if (hasDecimal) (truncated / 10.0).toString() + suffix else (truncated / 10).toString() + suffix
        }
        return ""
    }

    // Save preferences data
    fun saveData(context: Context?, key: String, value: String) {
        if (context != null && isNotEmptyString(key) && isNotEmptyString(value)) {
            val preferences =
                    context.getSharedPreferences(Constant.preference, Context.MODE_PRIVATE)
            preferences.edit().putString(key, value).apply()
        }
    }

    // Get preferences data
    fun getData(context: Context?, strKey: String): String {
        if (context != null && isNotEmptyString(strKey)) {
            val preferences =
                    context.getSharedPreferences(Constant.preference, Context.MODE_PRIVATE)
            return preferences.getString(strKey, "")!!
        }
        return ""
    }

    // Remove single preferences data
    fun removeData(context: Context?, key: String) {
        if (context != null && isNotEmptyString(key)) {
            val preferences =
                    context.getSharedPreferences(Constant.preference, Context.MODE_PRIVATE)
            preferences.edit().remove(key).apply()
        }
    }

    // Remove all preferences data
    private fun removeAllData(context: Context?) {
        if (context != null) {
            FBData.setOfflineUser()
            context.stopService(Intent(context, FloatingService::class.java))
            val preferences =
                    context.getSharedPreferences(Constant.preference, Context.MODE_PRIVATE)
            preferences.edit().clear().apply()

        }
    }

    // Check internet connection
    fun isNetworkAvailable(context: Context?): Boolean {
        if (context != null) {
            val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            val activeNetwork = cm.activeNetworkInfo
            return if (activeNetwork != null) {
                when (activeNetwork.type) {
                    ConnectivityManager.TYPE_WIFI -> true
                    ConnectivityManager.TYPE_MOBILE -> true
                    else -> false
                }
            } else {
                false
            }
        }
        return false
    }

    // Check GPS status
    fun isGPSOn(context: Context?): Boolean {
        if (context != null) {
            val manager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
            return manager.isProviderEnabled(LocationManager.GPS_PROVIDER)
        }
        return false
    }

    // Check email validation
    fun isValidEmail(email: String): Boolean {
        if (isNotEmptyString(email)) {
            return (Patterns.EMAIL_ADDRESS.matcher(email).matches())
        }
        return false
    }

    // Check password validation
    fun isValidPassword(password: String?): Boolean {
        if (isNotEmptyString(password)) {
            password?.let {
                val passwordPattern = "^(?=.*[0-9])(?=.*[a-z])(?=.*[@#$%^&+=])(?=\\S+$).{4,}$"
                val passwordMatcher = Regex(passwordPattern)
                return passwordMatcher.find(password) != null
            }
            return false
        }
        return false
    }

    // Check phone number validation
    fun isValidPhone(str: String): Boolean {
        return (!TextUtils.isEmpty(str) && Patterns.PHONE.matcher(str).matches())
    }

    // Get device unique id
    @SuppressLint("HardwareIds")
    fun getDeviceUniqueId(context: Context?): String {
        if (context != null) {
            return Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
        }
        return ""
    }

    // Get device name, os, sdk version
    fun getDeviceOs(): String {
        val builder = StringBuilder()
        builder.append("Android : ").append(Build.VERSION.RELEASE)
        val fields = Build.VERSION_CODES::class.java.fields
        for (field in fields) {
            val fieldName = field.name
            var fieldValue = -1
            try {
                fieldValue = field.getInt(Any())
            } catch (e: IllegalArgumentException) {
                e.printStackTrace()
            } catch (e: IllegalAccessException) {
                e.printStackTrace()
            } catch (e: NullPointerException) {
                e.printStackTrace()
            }
            if (fieldValue == Build.VERSION.SDK_INT) {
                builder.append(" : ").append(fieldName).append(" : ")
                builder.append("sdk=").append(fieldValue)
            }
        }
        return builder.toString()
    }


    // Check string empty or not
    fun isNotEmptyString(str: String?): Boolean {
        return str != null && str.trim().isNotEmpty() && !str.equals("null", ignoreCase = true)
    }

    // Check string empty or not
    fun isEmptyString(str: String?): Boolean {
        if (str == null || str.trim().isEmpty() || str.equals("null", ignoreCase = true)) {
            return true
        }
        return false
    }

    // Check string empty or not and return String
    fun chkStr(str: String?): String {
        if (str != null && str.isNotEmpty() && !str.equals("null", ignoreCase = true)) {
            return str
        }
        return ""
    }

    // Check string empty or not and return dash String
    fun chkStrAndReturnDash(str: String?): String {
        if (str != null && str.isNotEmpty() && !str.equals("null", ignoreCase = true)) {
            return str
        }
        return "-"
    }

    // Check string empty or not and return Int
    fun chkStrAndReturnInt(str: String?): Int {
        if (str != null && str.isNotEmpty() && !str.equals("null", ignoreCase = true)) {
            return str.toInt()
        }
        return 0
    }

    // Check string empty or not and return float value
    fun chkStrAndReturnFloat(str: String?): Float {
        if (str != null && str.isNotEmpty() && !str.equals("null", ignoreCase = true)) {
            return str.toFloat()
        }
        return 0.0f
    }

    // Check string empty or not and return Double value
    fun chkStrAndReturnDouble(str: String?): Double {
        if (str != null && str.isNotEmpty() && !str.equals("null", ignoreCase = true) && str.trim()
                        .isNotEmpty()
        ) {
            return str.toDouble()
        }
        return 0.0
    }

    // Check string empty or not and return Long value
    fun chkStrAndReturnLong(str: String?): Long {
        if (str != null && str.isNotEmpty() && !str.equals("null", ignoreCase = true) && str.trim()
                        .isNotEmpty()
        ) {
            return str.toLong()
        }
        return 0L
    }

    // Check parameter null or not and return
    fun chkInt(int: Int?): Int {
        if (int != null && int != 0) {
            return int
        }
        return 0
    }

    fun startActivity(context: Context?, activity: Class<*>) {
        context!!.startActivity(Intent(context, activity))
    }

    // Show SnackBar
    fun showSnackBar(coordinatorLayout: CoordinatorLayout?, strMsg: String) {
        if (coordinatorLayout != null && isNotEmptyString(strMsg)) {
            val snackbar = Snackbar.make(coordinatorLayout, strMsg, Snackbar.LENGTH_LONG)
            val sbView = snackbar.view
            val textView = sbView.findViewById<TextView>(R.id.snackbar_text)
            textView.setTextColor(Color.WHITE)
            snackbar.show()
        }
    }

    // Show toast
    fun showToast(context: Context?, strMsg: String) {
        if (context != null && isNotEmptyString(strMsg)) {
            val toast = Toast.makeText(context, strMsg, Toast.LENGTH_SHORT)
            toast.setGravity(Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0)
            toast.show()
        }
    }

    // Show long toast
    fun showToastLong(context: Context?, strMsg: String, timeInSecond: Int) {
        if (context != null && isNotEmptyString(strMsg) && timeInSecond > 0) {
            val toast = Toast.makeText(context, strMsg, Toast.LENGTH_SHORT)
            toast.setGravity(Gravity.CENTER_HORIZONTAL, 0, 0)
            toast.show()
            val handler = Handler()
            handler.postDelayed({ toast.cancel() }, timeInSecond.toLong())
        }
    }

    // Show alert dialog with click listener
    fun showAlertDialog(
            context: Context?,
            title: String,
            message: String,
            onClickListener: DialogInterface.OnClickListener
    ) {
        if (context != null && isNotEmptyString(message)) {
            val builder = AlertDialog.Builder(context)
            if (isNotEmptyString(title)) {
                builder.setTitle(title)
            }
            builder.setMessage(message)
            // builder.setIcon(android.R.drawable.ic_dialog_alert)
            builder.setCancelable(false)
            builder.setPositiveButton(R.string.ok, onClickListener)
            builder.create().show()
        }
    }

    // Show alert dialog
    fun showAlertDialog(context: Context?, title: String, message: String) {
        if (context != null && isNotEmptyString(message)) {
            val builder = AlertDialog.Builder(context)
            if (isNotEmptyString(title)) {
                builder.setTitle(title)
            }
            builder.setMessage(message)
            builder.setCancelable(false)
            builder.create().show()
        }
    }

    // Hide keyboard
    fun hideKeyboard(context: Context?) {
        if (context != null) {
            val view = (context as Activity).currentFocus
            if (view != null) {
                val inputManager =
                        context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                inputManager.hideSoftInputFromWindow(
                        view.windowToken,
                        InputMethodManager.HIDE_NOT_ALWAYS
                )
            }
        }
    }

    // Html format
    fun htmlFormat(str: String): Spanned {
        if (isNotEmptyString(str)) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                return Html.fromHtml(str, Html.FROM_HTML_MODE_LEGACY)
            } else {
                @Suppress("DEPRECATION")
                return Html.fromHtml(str)
            }
        }
        @Suppress("DEPRECATION")
        return Html.fromHtml("")
    }

    // Set text color
    fun setTextColor(str: String, color: Int): String {
        return "<font color=$color>$str</font>"
    }

    // Base 64 encode
    fun base64Encode(str: String): String {
        if (isNotEmptyString(str)) {
            try {
                val data = str.toByteArray(charset("UTF-8"))
                return encodeToString(data, Base64.DEFAULT)
            } catch (e: UnsupportedEncodingException) {
                e.printStackTrace()
            }
        }
        return ""
    }

    // Open url in browser
    fun openUrl(context: Context?, str: String) {
        if (context != null && isNotEmptyString(str)) {
            var url = str
            if (!url.startsWith("http://") && !url.startsWith("https://"))
                url = "http://$url"
            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
            context.startActivity(intent)
        }
    }

    // Open play store as per package name
    fun openPlayStore(context: Context?, appPackageName: String) {
        if (context != null && isNotEmptyString(appPackageName)) {
            try {
                context.startActivity(
                        Intent(
                                Intent.ACTION_VIEW,
                                Uri.parse("market://details?id=$appPackageName")
                        )
                )
            } catch (a: ActivityNotFoundException) {
                context.startActivity(
                        Intent(
                                Intent.ACTION_VIEW,
                                Uri.parse("https://play.google.com/store/apps/details?id=$appPackageName")
                        )
                )
            }
        }
    }

    // Convert bitmap to string
    fun bitmapToString(bmp: Bitmap?): String {
        if (bmp != null) {
            val baos = ByteArrayOutputStream()
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos)
            val imageBytes = baos.toByteArray()
            return encodeToString(imageBytes, Base64.DEFAULT)
        }
        return ""
    }

    // Bold and not text single line
    fun boldNormalText(str1: String, str2: String): String {
        return if (isNotEmptyString(str1) && isNotEmptyString(str2)) "<b>$str1</b>$str2" else ""
    }

    // Hide status bar
    fun hideStatusBar(activity: Activity?) {
        activity?.window?.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)
    }

    // Status bar color
    fun statusBarColor(activity: Activity?, color: Int) {
        if (activity != null && color != 0) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                activity.window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
                activity.window.statusBarColor = ContextCompat.getColor(activity, color)
            }
        }
    }

    // Status bar color
    fun transparentBottomMenu(activity: Activity?) {
        activity!!.window.setFlags(
                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
        )
    }

    // Create body
    fun createBody(str: String): RequestBody {
        return RequestBody.create(MediaType.parse("text/plain"), str)
    }

    // Create multipart
    fun createMultiPart(filePath: File?, key: String): MultipartBody.Part {
        if (filePath!!.exists()) {
            val body = RequestBody.create(MediaType.parse("multipart/form-data"), filePath)
            return MultipartBody.Part.createFormData(key, "file", body)
        }
        val body = RequestBody.create(MediaType.parse("text/plain"), "")
        return MultipartBody.Part.createFormData(key, "", body)
    }

    // Blank image pass in retrofit api
    fun blankImage(parameter: String): MultipartBody.Part {
        val requestFile = RequestBody.create(MediaType.parse("text/plain"), "")
        return MultipartBody.Part.createFormData(parameter, "", requestFile)
    }

    // Copy text
    fun copyText(context: Context?, str: String) {
        if (context != null && isNotEmptyString(str)) {
            val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?
            val clip = ClipData.newPlainText("Copy", str)
            clipboard?.setPrimaryClip(clip)
        }
    }

    // Show image in ImageView
    fun displayImage(
            context: Context?,
            path: String,
            imageView: AppCompatImageView?,
            defaultImage: Int
    ) {
        if (context != null && imageView != null) {
            val options = RequestOptions().centerCrop().placeholder(defaultImage)
                    .error(defaultImage).diskCacheStrategy(DiskCacheStrategy.ALL)
                    .priority(Priority.HIGH)
            Glide.with(context).load(path).apply(options).into(imageView)

        }
    }

    // preview Image
    fun previewImage(context: Context?, imageUrl: String) {
        if (context != null && isNotEmptyString(imageUrl)) {
            val intent = Intent(context, PreviewImageActivity::class.java)
            intent.putExtra(Constant.profile_picture, imageUrl)
            context.startActivity(intent)
        }
    }

    // Convert string to decimal
    fun stringToDecimal(str: String, pattern: String): String {
        if (isNotEmptyString(str) && isNotEmptyString(pattern)) {
            val precision = DecimalFormat(pattern)
            return precision.format(str.toDouble())
        }
        return ""
    }

    // All letter capital
    fun upperCaseLtr(str: String): String {
        if (isNotEmptyString(str)) {
            return str.toUpperCase(Locale.ROOT)
        }
        return ""
    }

    // All letter small
    fun lowerCaseLtr(str: String): String {
        if (isNotEmptyString(str)) {
            return str.toLowerCase(Locale.ROOT)
        }
        return ""
    }

    // Camel case letter
    fun camelCaseLtr(str: String): String {
        if (isNotEmptyString(str)) {
            return str.substring(0, 1).toUpperCase(Locale.ROOT) + str.substring(1)
        }
        return ""
    }

    fun removeLastChar(str: String, count: Int): String {
        if (isNotEmptyString(str)) {
            return str.substring(0, str.length - count)
        }
        return ""
    }

    // Check google play service available
    fun isGooglePlayServicesAvailable(context: Context?): Boolean {
        if (context != null) {
            val googleApiAvailability = GoogleApiAvailability.getInstance()
            val status = googleApiAvailability.isGooglePlayServicesAvailable(context)
            if (status != ConnectionResult.SUCCESS) {
                if (googleApiAvailability.isUserResolvableError(status)) {
                    googleApiAvailability.getErrorDialog(context as Activity?, status, 2404).show()
                }
                return false
            }
            return true
        }
        return false
    }

    // Check app install or not by package name
    fun isAppInstalled(context: Context?, packageName: String): Boolean {
        if (context != null && isNotEmptyString(packageName)) {
            return try {
                context.packageManager.getApplicationInfo(packageName, 0)
                true
            } catch (e: PackageManager.NameNotFoundException) {
                false
            }
        }
        return false
    }

    // Check abusive words
    fun checkAbusiveWords(text: String): Boolean {
        /*if (isNotEmptyString(text)) {
            val regex = Regex("[^A-Za-z ]")
            val result = regex.replace(text, "")
            val split = result.split(" ")
            for (word in split) {
                if (word.trim().toLowerCase()
                        .matches(Constant.abusiveWords.trim().toLowerCase().toRegex())
                ) {
                    return true
                }
            }
            return false
        }*/
        return false
    }

    // Encrypt String
    fun encryptString(message: String): String {
        return ""
    }

    // Decrypt String
    fun decryptString(message: String): String {
        return ""
    }

    fun compareTime(startTime: String, endtime: String): Boolean {
        val pattern = "HH:mm"
        val sdf = SimpleDateFormat(pattern)
        try {
            val date1 = sdf.parse(startTime)
            val date2 = sdf.parse(endtime)
            return date1.before(date2)
        } catch (e: ParseException) {
            e.printStackTrace()
        }
        return false
    }

    fun showSingleSelectionDialog(
            context: Context,
            editText: EditText,
            arrayList: ArrayList<SpinnerModel>?
    ): Dialog {
        hideKeyboard(context)
        val dialog = Dialog(context)
        dialog.setCancelable(true)
        //dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog.window!!.setContentView(R.layout.dialog_single_selection)

        val tvTitle = dialog.findViewById(R.id.tvTitle) as AppCompatTextView
        val llSearch = dialog.findViewById(R.id.llSearch) as LinearLayoutCompat
        val etSearch = dialog.findViewById(R.id.etSearch) as EditText
        val imgClear = dialog.findViewById(R.id.imgClear) as AppCompatImageView
        val recyclerView = dialog.findViewById(R.id.recyclerView) as RecyclerView
        val tvNoDataFound = dialog.findViewById(R.id.tvNoDataFound) as AppCompatTextView
        val tvCancel = dialog.findViewById(R.id.tvCancel) as AppCompatTextView

        val selectedCountry = SpinnerModel()

        val adapter = SingleSelectionAdapter(
                context,
                editText,
                arrayList!!,
                llSearch,
                etSearch,
                tvNoDataFound,
                dialog,
                imgClear
        )

        recyclerView.layoutManager = LinearLayoutManager(context)
        recyclerView.adapter = adapter

        tvCancel.setOnClickListener {
            hideKeyboard(context)
            dialog.cancel()
        }

        dialog.setOnDismissListener {
            hideKeyboard(context)
            dialog.cancel()
        }

        dialog.setOnCancelListener {
            hideKeyboard(context)
            dialog.cancel()
        }

        editText.isFocusableInTouchMode = false
        editText.isCursorVisible = false
        editText.setOnClickListener {
            if (arrayList!!.isNotEmpty()) {
                dialog.show()
            }
        }
        return dialog
    }

    fun showSettingsDialog(activity: Activity?) {
        if (activity != null) {
            val builder = android.app.AlertDialog.Builder(activity)
            builder.setTitle(activity.getString(R.string.need_permissions))
            builder.setMessage(activity.getString(R.string.this_app_needs_permission))
            builder.setPositiveButton(activity.getString(R.string.goto_settings)) { dialog, _ ->
                dialog.cancel()
                val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                val uri = Uri.fromParts("package", activity.packageName, null)
                intent.data = uri
                activity.startActivityForResult(intent, Constant.RC_PERMISSION)
            }
            builder.setNegativeButton(activity.getString(R.string.cancel)) { dialog, _ -> dialog.cancel() }
            builder.show()
        }
    }

    fun savePushToken(context: Context?) {
        FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
            if (!task.isSuccessful) {
                return@OnCompleteListener
            }
            // Get new FCM registration token
            val token = task.result
            if (isNotEmptyString(token)) {
                saveData(context, Constant.push_token, token.toString().trim())
            }
        })
    }
    
    /* fun specialityWithComma(model: ProfileModel.Detail?): String {
         if (model?.specialties != null && model.specialties!!.isNotEmpty()) {
             val strBuilder = StringBuilder()
             var comma = ""
             for (speciality in model.specialties!!) {
                 strBuilder.append(comma)
                 strBuilder.append(chkStr(speciality.title))
                 comma = ", "
             }
             return strBuilder.toString()
         }
         return ""
     }*/

    fun totalExperience(context: Context?, experience: Int): String {
        if (context != null) {
            return context.resources.getQuantityString(
                    R.plurals.yearCount,
                    experience,
                    experience
            ) + " " +
                    context.resources.getString(R.string.experience)
        }
        return ""
    }

    fun totalDoctor(context: Context?, doctor: Int): String {
        if (context != null) {
            return context.resources.getQuantityString(
                    R.plurals.doctorCount,
                    doctor,
                    doctor
            )
        }
        return ""
    }

    fun totalReview(context: Context?, review: Int): String {
        if (context != null) {
            return context.resources.getQuantityString(R.plurals.reviewCount, review, review)
        }
        return ""
    }

    fun getUserCountry(context: Context?): String {
        val ccp = CountryCodePicker(context)
        ccp.setCountryForPhoneCode(getData(context, Constant.dialcode).toInt())
        return ccp.selectedCountryName
    }

    fun callDial(context: Context?, number: String) {
        if (context != null && isNotEmptyString(number)) {
            val intent = Intent(Intent.ACTION_DIAL)
            intent.data = Uri.parse("tel:$number")
            context.startActivity(intent)
        }
    }

    fun sendEmail(context: Context?, emailId: String, subject: String) {
        if (context != null && isNotEmptyString(emailId)) {
            val uri = Uri.fromParts("mailto", emailId, null)
            val intent = Intent(Intent.ACTION_SENDTO, uri)
            intent.putExtra(Intent.EXTRA_SUBJECT, subject)
            intent.putExtra(Intent.EXTRA_TEXT, "Body")
            context.startActivity(Intent.createChooser(intent, "Send email..."))
        }
    }

    @SuppressLint("SimpleDateFormat")
    fun getTimes(start: String, end: String, interval: Int): ArrayList<String> {
        val sdf1: java.text.DateFormat = SimpleDateFormat("HH:mm")
        try {
            val date: Date = sdf1.parse(start)
            //println("Date and Time: $date")
            val date1: Date = sdf1.parse(end)
            //println("Date and Time1: $date1")
            val times = ArrayList<String>()
            val sdf = SimpleDateFormat("HH:mm")
            val calendar = GregorianCalendar.getInstance()
            calendar.time = date
            if (calendar.time.before(date1)) {
                times.add(sdf.format(calendar.time))
                while (calendar.time.before(date1)) {
                    calendar.add(Calendar.MINUTE, interval)
                    times.add(sdf.format(calendar.time))
                }
            }
            if (times.size > 0) {
                times.removeAt((times.size - 1))
            }
            Log.e("TIMES ", times.toString())
            return times
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return ArrayList<String>()
    }
}


ApiInterface

package com.demo.restapi
import android.content.Context
import android.util.Log
import com.demo.global.Constant
import com.demo.global.Utils
import com.demo.models.CommonModel
import com.readystatesoftware.chuck.ChuckInterceptor
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.RequestBody
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.*
import java.security.SecureRandom
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

interface ApiInterface {

    @GET
    fun getMethod(@Url url: String): Call<CommonModel>

    @FormUrlEncoded
    @POST
    fun postMethod(@Url url: String, @FieldMap params: HashMap<String, String>): Call<CommonModel>

    @Multipart
    @POST
    fun uploadFileData(
        @Url url: String,
        @PartMap params: HashMap<String, RequestBody>,
        @Part files: ArrayList<MultipartBody.Part>
    ): Call<CommonModel>

    companion object {
        fun create(context: Context): ApiInterface {
            val retrofit = Retrofit.Builder()
                .client(okHttpClient(context))
                //.client(getUnsafeOkHttpClient(context)!!.build())
                .baseUrl(Constant.baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
            return retrofit.create(ApiInterface::class.java)
        }

        //WITH SSL (HTTPS Secure)
        private fun okHttpClient(context: Context): OkHttpClient {
            return OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .addInterceptor(ChuckInterceptor(context))
                .addInterceptor { chain ->
                    val newRequest = chain.request().newBuilder()
                        .addHeader("Accept", "application/json")
                        .addHeader("Content-Type", "application/json")
                        .addHeader("Authorization", Utils.getData(context, Constant.token))
                        .build()
                    Log.e("Token", Utils.getData(context, Constant.token))
                    chain.proceed(newRequest)
                }.build()
        }

        //Without SSL (HTTP UnSecure)
        private fun getUnsafeOkHttpClient(context: Context): OkHttpClient.Builder? {
            return try {
                // Create a trust manager that does not validate certificate chains
                val trustAllCerts = arrayOf<TrustManager>(
                    object : X509TrustManager {
                        @Throws(CertificateException::class)
                        override fun checkClientTrusted(
                            chain: Array<X509Certificate>,
                            authType: String
                        ) {
                        }

                        @Throws(CertificateException::class)
                        override fun checkServerTrusted(
                            chain: Array<X509Certificate>,
                            authType: String
                        ) {
                        }

                        override fun getAcceptedIssuers(): Array<X509Certificate> {
                            return arrayOf()
                        }
                    }
                )

                // Install the all-trusting trust manager
                val sslContext = SSLContext.getInstance("SSL")
                sslContext.init(null, trustAllCerts, SecureRandom())
                // Create an ssl socket factory with our all-trusting manager
                val sslSocketFactory = sslContext.socketFactory
                val builder = OkHttpClient.Builder()
                    .connectTimeout(60, TimeUnit.SECONDS)
                    .readTimeout(60, TimeUnit.SECONDS)
                    .writeTimeout(60, TimeUnit.SECONDS)
                    .addInterceptor(ChuckInterceptor(context))
                builder.addInterceptor { chain ->
                    val newRequest = chain.request().newBuilder()
                        .addHeader("Accept", "application/json")
                        .addHeader("Content-Type", "application/json")
                        .addHeader("Authorization", Utils.getData(context, Constant.token))
                        .build()
                    Log.e("Token", Utils.getData(context, Constant.token))
                    chain.proceed(newRequest)
                }.build()
                builder.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
                builder.hostnameVerifier { hostname, session -> true }
                builder
            } catch (e: Exception) {
                throw RuntimeException(e)
            }
        }
    }
}


ParseController

package com.demo.restapi

import android.content.Context
import android.os.Build
import android.util.Log
import androidx.multidex.BuildConfig
import com.nchealthhub.R
import com.google.gson.Gson
import com.demo.global.Constant
import com.demo.global.Utils
import okio.Buffer
import org.json.JSONException
import org.json.JSONObject
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.IOException
import java.net.URLDecoder

class ParseController(
    private val mContext: Context?, call: Call<*>,
    private val isShowLoading: Boolean,
    private val loadingMsg: String,
    private val listener: ApiCompleteListener
) {
    init {
        if (Utils.isDebugging) {
            Log.e("URL", URLDecoder.decode(call.request().url().toString(), "UTF-8"))
            Log.e("METHOD", URLDecoder.decode(call.request().method().toString(), "UTF-8"))
            if (call.request().body() != null) {
                val buffer = Buffer()
                call.request().body()!!.writeTo(buffer)
                val items = buffer.readUtf8().split("&")
                for (item in items) {
                    Log.e("PARAMETER", item.trim())
                }
            }
        }
        //Api call
        if (loadingMsg != mContext!!.getString(R.string.search)) {
            Utils.hideKeyboard(mContext)
        }
        if (Utils.isNetworkAvailable(mContext)) {
            callRetrofitApi(call)
        } else {
            listener.onFailedResponse(0, mContext!!.getString(R.string.internet_error))
        }
    }

    private fun <T> callRetrofitApi(call: Call<T>) {
        val dialog = CustomDialog(mContext)
        if (isShowLoading) {
            dialog.setCancelable(false)
            dialog.show()
        }
        call.enqueue(object : Callback<T> {
            override fun onResponse(call: Call<T>, response: Response<T>) {
                if (dialog.isShowing) {
                    dialog.dismiss()
                }

                if (response.isSuccessful && response.body() != null && response.body()!!.toString()
                        .trim().isNotEmpty()
                ) {
                    if (Utils.isDebugging) {
                        Log.e("SUCCESSFUL RESPONSE", "" + Gson().toJson(response.body()))
                    }
                    listener.onSuccessResponse(response)
                } else {
                    if (Utils.isDebugging) {
                        Log.e("ERROR RESPONSE", "" + Gson().toJson(response.body()))
                    }
                    try {
                        val jsonObject = JSONObject(response.errorBody()!!.string())
                        val message = jsonObject.getString(Constant.message)
                        when (jsonObject.getString(Constant.code)) {
                            Constant._400 -> {
                                listener.onFailedResponse(1, message)
                            }
                            Constant._401 -> {
                                Utils.logout(mContext, message)
                            }
                            else -> {
                                listener.onFailedResponse(
                                    2,
                                    mContext!!.getString(R.string.response_error)
                                )
                            }
                        }
                    } catch (e: JSONException) {
                        listener.onFailedResponse(3, mContext!!.getString(R.string.response_error))
                    } catch (e: IOException) {
                        listener.onFailedResponse(4, mContext!!.getString(R.string.response_error))
                    }
                }
            }

            override fun onFailure(call: Call<T>, t: Throwable) {
                if (Utils.isDebugging) {
                    Log.e("RESPONSE", "" + t.localizedMessage)
                }
                if (dialog.isShowing) {
                    dialog.dismiss()
                }
                //listener.onFailedResponse(0, t.localizedMessage!!)
                if (!call.isCanceled) {
                    listener.onFailedResponse(5, mContext!!.getString(R.string.response_error))
                }
            }
        })
    }

    interface ApiCompleteListener {
        fun <T> onSuccessResponse(jsonResponse: Response<T>)
        fun onFailedResponse(statusCode: Int, message: String)
    }
}


CustomDialog

package com.demo.restapi;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.Window;
import android.widget.ImageView;
import com.demo.R;
import com.bumptech.glide.Glide;

public class CustomDialog extends Dialog {

    private Context mContext;

    public CustomDialog(Context context) {
        super(context);
        mContext = context;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.dialog_loader);

        ImageView imgLoader = findViewById(R.id.img_loader);
        Glide.with(mContext).asGif().load(R.drawable.ripple_gif).into(imgLoader);
    }
}


package com.demo.pushnotification

import android.app.*
import android.content.Context
import android.content.Intent
import android.media.Ringtone
import android.media.RingtoneManager
import android.net.Uri
import android.os.Build
import android.util.Log
import androidx.core.app.NotificationCompat
import com.demo.R
import com.demo.global.Constant
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import com.demo.BuildConfig
import com.demo.activities.NotificationLogActivity
import com.demo.agent.AgentDashboardActivity
import com.demo.agent.AgentProfileActivity
import com.demo.doctor.*
import com.demo.global.Utils
import com.demo.patient.ChatActivity


class MyFirebaseMessagingService : FirebaseMessagingService() {

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        //Log.e("onMessageReceived", "" + remoteMessage)

        val isAuthentication = Utils.getData(this, Constant.is_authentication)
        /*if (isAuthentication == Constant.Y && remoteMessage.notification != null) {
             Log.e("notification", "" + remoteMessage.notification)
               val title = Utils.chkStr(remoteMessage.notification!!.title)
               val body = Utils.chkStr(remoteMessage.notification!!.body)
               val sound = Utils.chkStr(remoteMessage.notification!!.sound)
               val clickAction = Utils.chkStr(remoteMessage.notification!!.clickAction)
               val tag = Utils.chkStr(remoteMessage.notification!!.tag)
               //sendNotification(title, body, tag)
        }*/

        if (isAuthentication == Constant.Y && remoteMessage.data.isNotEmpty()) {
            //Log.e("data", "" + remoteMessage.data)
            val title = Utils.chkStr(remoteMessage.data[Constant.title])
            val text = Utils.chkStr(remoteMessage.data[Constant.text])
            val type = Utils.chkStr(remoteMessage.data[Constant.type])
            val id = Utils.chkStr(remoteMessage.data[Constant.id])
            sendNotification(title, text, type, id)
        }
    }

    private fun sendNotification(title: String, text: String, type: String, id: String) {
        val intent: Intent
        when (type) {
      
            "abc" -> {
                intent = Intent(this, ABCActivity::class.java)
                intent.putExtra(Constant.id, Utils.chkStr(id))
                intent.putExtra(Constant.appointment_status, Constant.create)
            }
            "xyz" -> {
                intent = Intent(this, XyzActivity::class.java)
                intent.putExtra(Constant.appointment_status, Constant.cancelled)
            } else -> {
                intent = Intent(this, NotificationLogActivity::class.java)
            }
        }
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        val pendingIntent =
            PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

        val notificationBuilder = NotificationCompat.Builder(this, BuildConfig.APPLICATION_ID)
            .setSmallIcon(R.drawable.ic_logo)
            .setContentTitle(Utils.htmlFormat(title))
            .setContentText(Utils.htmlFormat(text))
            .setStyle(NotificationCompat.BigTextStyle().bigText(Utils.htmlFormat(text)))
            .setDefaults(Notification.DEFAULT_ALL)
            .setContentIntent(pendingIntent)
            .setWhen(System.currentTimeMillis())
            .setAutoCancel(true)

        val notificationManager =
            getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        // Configure Notification Channel
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(
                BuildConfig.APPLICATION_ID,
                resources.getString(R.string.app_name),
                NotificationManager.IMPORTANCE_DEFAULT
            )
            channel.enableLights(true)
            channel.enableVibration(true)
            channel.setSound(null, null)
            notificationManager.createNotificationChannel(channel)
            try {
                //val notification = Uri.parse("android.resource://" + packageName + "/" + R.raw.tone)
                val notification = Uri.parse("android.resource://$packageName/")
                val r: Ringtone = RingtoneManager.getRingtone(this, notification)
                r.play()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        notificationManager.notify(1, notificationBuilder.build())
    }


    override fun onNewToken(token: String) {
        if (Utils.isNotEmptyString(token)) {
            Utils.saveData(this, Constant.push_token, token.trim())
        }
    }
}

No comments:

Post a Comment

Marvel Api Integration In Android

                              Full Source Code Download Here: https://github.com/sanjaymangaroliya/MarvelApiIntegration.git MainA...