Skip to content

Instantly share code, notes, and snippets.

@SurajBahadur
Created August 19, 2019 13:05
Show Gist options
  • Save SurajBahadur/90e4d74f3a8951a0911dc1de5d3600b2 to your computer and use it in GitHub Desktop.
Save SurajBahadur/90e4d74f3a8951a0911dc1de5d3600b2 to your computer and use it in GitHub Desktop.
Play around with mapbox, exoplayer,downloading video/audio in kotlin
package com.app.test.receiver
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.app.test.listeners.LocationCallBack
/**
* initializes receiver with callback
* @param iLocationCallBack Location callback
*/
class GpsReceiver(private val locationCallBack: LocationCallBack) : BroadcastReceiver() {
/**
* triggers on receiving external broadcast
* @param context Context
* @param intent Intent
*/
override fun onReceive(context: Context, intent: Intent) {
if (intent.action!!.matches("android.location.PROVIDERS_CHANGED".toRegex())) {
locationCallBack.onLocationTriggered()
}
}
}
interface locationListener {
fun onLocationChanged(lat: Double, lng: Double)
}
package com.app.test.ui.mapBox
import Preferences
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.Dialog
import android.app.ProgressDialog
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.IntentFilter
import android.graphics.*
import android.graphics.Typeface.DEFAULT
import android.graphics.Typeface.create
import android.location.LocationManager
import android.media.AudioManager
import android.net.ConnectivityManager
import android.net.Uri
import android.os.*
import android.provider.Settings
import android.support.design.widget.NavigationView
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.support.v4.graphics.drawable.DrawableCompat
import android.support.v4.view.GravityCompat
import android.support.v4.widget.DrawerLayout
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.DividerItemDecoration
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.text.TextUtils
import android.util.Log
import android.util.SparseArray
import android.view.*
import android.widget.*
import at.huber.youtubeExtractor.VideoMeta
import at.huber.youtubeExtractor.YouTubeExtractor
import at.huber.youtubeExtractor.YtFile
import com.app.test.R
import com.app.test.activity.MainActivity
import com.app.test.database.DatabaseClient
import com.app.test.database.entity.PackageSpots
import com.app.test.listeners.LocationCallBack
import com.app.test.listeners.locationListener
import com.app.test.listeners.onItemClickedListener
import com.app.test.receiver.GpsReceiver
import com.app.test.ui.mapBox.response.*
import com.app.test.utils.Constants
import com.app.test.utils.saveValue
import com.google.android.exoplayer2.*
import com.google.android.exoplayer2.source.*
import com.google.android.exoplayer2.source.hls.HlsMediaSource
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector
import com.google.android.exoplayer2.trackselection.TrackSelectionArray
import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory
import com.google.android.exoplayer2.util.MimeTypes
import com.google.android.exoplayer2.util.Util
import com.google.gson.Gson
import com.mapbox.android.core.location.*
import com.mapbox.android.core.permissions.PermissionsListener
import com.mapbox.android.core.permissions.PermissionsManager
import com.mapbox.directions.DirectionsCriteria
import com.mapbox.directions.MapboxDirections
import com.mapbox.directions.service.models.DirectionsResponse
import com.mapbox.directions.service.models.DirectionsRoute
import com.mapbox.directions.service.models.Waypoint
import com.mapbox.mapboxsdk.Mapbox
import com.mapbox.mapboxsdk.annotations.IconFactory
import com.mapbox.mapboxsdk.annotations.MarkerOptions
import com.mapbox.mapboxsdk.annotations.PolylineOptions
import com.mapbox.mapboxsdk.camera.CameraPosition
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
import com.mapbox.mapboxsdk.geometry.LatLng
import com.mapbox.mapboxsdk.geometry.LatLngBounds
import com.mapbox.mapboxsdk.maps.MapView
import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.maps.Style
import com.mapbox.mapboxsdk.offline.*
import com.mapbox.mapboxsdk.plugins.markerview.MarkerViewManager
import com.squareup.picasso.NetworkPolicy
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_map_box.*
import kotlinx.android.synthetic.main.content_play_audio.*
import kotlinx.android.synthetic.main.navigation_view.*
import kotlinx.android.synthetic.main.play_tour_video.*
import org.json.JSONObject
import retrofit.Callback
import retrofit.Response
import retrofit.Retrofit
import timber.log.Timber
import java.io.BufferedInputStream
import java.io.File
import java.io.FileOutputStream
import java.net.URL
import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import android.view.KeyEvent.KEYCODE_BACK as KEYCODE_BACK1
class MapBoxActivity : AppCompatActivity(), PermissionsListener, onItemClickedListener, locationListener {
// UI elements
private var mapView: MapView? = null
private var map: MapboxMap? = null
private var progressBar: ProgressBar? = null
private var downloadButton: Button? = null
private var listButton: Button? = null
private var isEndNotified: Boolean = false
private var regionSelected: Int = 0
// Offline objects
private var offlineManager: OfflineManager? = null
private var offlineRegion: OfflineRegion? = null
private var permissionsManager: PermissionsManager? = null
private var rvSpotList: RecyclerView? = null
private var spotListAdapter: SpotListAdapter? = null
private var mViewModel: MapBoxViewModel? = null
internal var LOG_TAG = "DIRECTIO"
private var currentRoute: DirectionsRoute? = null
private var mRegionToDownload: MapData? = null
private var mRegionRegionSpot: List<DataItem>? = null
private var mRegionRoute: Route? = null
private var mRegionManualRoute: ManualItem? = null
private val gson = Gson()
private var packageSpotsListStr: String = ""
private var dataSourceFac: DataSource.Factory? = null
private lateinit var mRegionPackageId: String
private lateinit var mPackageTokenId: String
private lateinit var mComingFrom: String
private var mDoubleTourStatus: Boolean = false
private var markerViewManager: MarkerViewManager? = null
private var MAP_NORMAL: String = "normal"
private var MAP_SATELLITE: String = "satellite"
private lateinit var locationEngine: LocationEngine
private val DEFAULT_INTERVAL_IN_MILLISECONDS = 10000L
//val DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS * 5
private val DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS * 5
private val callback = LocationListeningCallback(this)
private lateinit var mDrawerLayout: DrawerLayout
private lateinit var navigationView: NavigationView
private lateinit var fragment: Fragment
private lateinit var iv_toggle_menu: ImageView
private var downloadListPosition = 0
private lateinit var mTourTimeStatus: String
private lateinit var points: ArrayList<LatLng>
private lateinit var dialogMsg: String
/**
* mTourTokenStatus denotes tour active or inactive
* true token is active
* false toke inactive
*/
private var mTourTokenStatus: String = "active"
private lateinit var mTourDisTravelledByUser: String
private val mVideoWatchedList = mutableListOf<String>()
private var customExceptionHandlerAttached: Boolean = false
private var STATUS_ACTIVATION = false
private var STATUS_RETURN = false
private var STATUS_INACTIVATION = false
private var TYPE_ACTIVATION = "activation"
private var TYPE_RETURN = "return"
private var TYPE_INACTIVATION = "inactivation"
private var TYPE_EXPIRE = "expire"
private var mTourEndTime: Long = 0
@SuppressLint("MissingPermission")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Mapbox.getInstance(this, getString(R.string.mapbox_key))
setContentView(R.layout.activity_map_box)
mViewModel = ViewModelProviders.of(this).get(MapBoxViewModel::class.java)
mapView = findViewById(R.id.mapView)
rvSpotList = findViewById(R.id.rvSpotList)
callback.onLocationChangeListener(this)
attachObserver()
clickListeners()
getBundleArguments()
navigationDrawer()
attachLocationOnOffListener()
syncMap()
}
private fun syncMap() {
mapView!!.getMapAsync { mapboxMap ->
map = mapboxMap
mapboxMap.setStyle(Style.SATELLITE) { style ->
// Assign progressBar for later use
progressBar = findViewById(R.id.progress_bar)
// Set up the offlineManager
offlineManager = OfflineManager.getInstance(this@MapBoxActivity)
markerViewManager = MarkerViewManager(mapView, mapboxMap)
enableLocationComponent(style)
ivMapStyle.tag = MAP_SATELLITE
if (isLocationEnabled(this@MapBoxActivity)) {
if (isNetworkAvailable()) {
mViewModel?.getPackagesData(mRegionPackageId, deviceToken())
} else {
RetrievePackageSpots(baseContext, mRegionPackageId, false).execute()
}
} else {
showLocationDialog()
}
downloadButton = this.findViewById(R.id.download_button)
downloadButton!!.setOnClickListener { view -> downloadRegionDialog() }
// List offline regions
listButton = findViewById(R.id.list_button)
listButton!!.setOnClickListener { view -> downloadedRegionList() }
}
}
}
//function to start tour timer
//45 min=2700000
private fun startTripTimeTracker(tourTime: Int): CountDownTimer {
return object : CountDownTimer(tourTime.toLong(), 1000) {
override fun onTick(millisUntilFinished: Long) {
print("${TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)}")
//tvTourName.text = TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished).toString()
}
override fun onFinish() {
//trip limit end
mTourTokenStatus = "inactive"
}
}
}
//Function called whenever device location changed
override fun onLocationChanged(lat: Double, lng: Double) {
if (mRegionToDownload != null) {
if (mRegionToDownload?.boothLat != "" && mRegionToDownload?.boothLong != "") {
val distance = meterDistanceBtBoothAndUser(mRegionToDownload?.boothLat!!.toFloat(), mRegionToDownload?.boothLong!!.toFloat(), lat.toFloat(), lng.toFloat())
if (mDoubleTourStatus) {
//DOUBLE TOUR PREVENTION ON
if (mRegionToDownload?.maxDistance != "" && mRegionToDownload?.minDistance != "") {
//token activation: the tablet was more than 100m from the ticket booth
if (!STATUS_ACTIVATION && distance > mRegionToDownload?.maxDistance!!.toDouble()) {
mViewModel?.updateTourTokenTime(getUpdateTokenTimeParams(TYPE_ACTIVATION))
}
//token return : this is the time that the distance to the ticket booth is less then 50m
if (!STATUS_RETURN && STATUS_ACTIVATION && distance < mRegionToDownload?.minDistance!!.toDouble()) {
mViewModel?.updateTourTokenTime(getUpdateTokenTimeParams(TYPE_RETURN))
}
//token inactive if cross tour time limit and distance greater than max distance
if (mTourTokenStatus == "inactive" && (distance > mRegionToDownload?.maxDistance!!.toFloat() || distance > mRegionToDownload?.minDistance!!.toFloat())
&& !STATUS_INACTIVATION) {
mViewModel?.updateTourTokenTime(getUpdateTokenTimeParams(TYPE_INACTIVATION))
}
}
//token inactive if cross tour time limit and distance greater than max distance
/*if (mTourTokenStatus == "inactive" && distance > mRegionToDownload?.maxDistance!!.toFloat() && !STATUS_INACTIVATION) {
//takeUserToHomeScreen()
mViewModel?.updateTourTokenTime(getUpdateTokenTimeParams(TYPE_INACTIVATION))
}
if (mTourTokenStatus == "inactive" && distance > mRegionToDownload?.minDistance!!.toFloat() && !STATUS_INACTIVATION) {
//If the user tablet location becomes more then 50 meters away from the ticket booth with an inactivated token, then the tour
//will automatically finish and the app will return to the home screen. To see the tour again, a new token should be used.
//takeUserToHomeScreen()
mViewModel?.updateTourTokenTime(getUpdateTokenTimeParams(TYPE_INACTIVATION))
}*/
if (mTourTokenStatus == "inactive" && distance < mRegionToDownload?.minDistance!!.toFloat()) {
//If the user is still inside the 50m range from the ticket booth and the tour is still running inside the app,
// the user can still use the tour normally, including watching all videos.
}
}
//VIDEO WILL BE PLAY AUTOMATICALLY IF USER COMES INSIDE 20 METER RANGE OF SPOTS
mRegionRegionSpot!!.forEachIndexed { index, location ->
if (20 > meterDistanceBtBoothAndUser(location.latitude!!.toFloat(), location.longitude!!.toFloat(), lat.toFloat(), lng.toFloat())) {
if (mVideoWatchedList.size > 0) {
//if (mVideoWatchedList.binarySearch(location.id.toString()) == -1) {
if (!mVideoWatchedList.contains(location.id.toString())) {
//playVideo(getFileUri(index).toString())
mVideoWatchedList.add(location.id.toString())
playVideoBasedOnUserLocation(index)
} else {
showMessage(location.id.toString())
}
} else {
//playVideo(getFileUri(index).toString())
mVideoWatchedList.add(location.id.toString())
playVideoBasedOnUserLocation(index)
}
}
}
} else {
showMessage("minimum and maximum distance of tour not found")
}
} else {
//showMessage("Booth location not found")
}
}
private fun playVideoBasedOnUserLocation(index: Int) {
val uri: Uri? = getFileUri(index)
val name: String = uri?.lastPathSegment as String
val extension = name.substring(name.lastIndexOf(".") + 1)
val data = mRegionRegionSpot?.get(index)
if (data?.fileType.equals("audio")) {
playAudio(data, uri.toString())
} else if (data?.fileType.equals("youtube")) {
if (data?.youtubeId != "") {
if (data?.youtubeId!!.contains("youtube")) {
playYoutubeVideo(data.youtubeId)
} else {
playVideoWithoutSubtitle(data.youtubeId)
}
} else showMessage(getString(R.string.txt_videoid_missing))
} else if (extension == "mp4") {
//PLAY VIDEO WITH VTT FILE
if (data?.fileType.equals("vtt") && data?.spotVideoVtt != "") {
playVideoWithSubtitle(uri.toString(), data)
}
//PLAY VIDEO WITHOUT VTT
if (data?.fileType.equals("video") && data?.spotVideoVtt == "") {
playVideoWithoutSubtitle(uri.toString())
}
} else {
Toast.makeText(this@MapBoxActivity, "Server Error", Toast.LENGTH_SHORT).show()
}
}
private fun getUpdateTokenTimeParams(type: String): HashMap<String, String> {
val data = HashMap<String, String>()
data["id"] = mPackageTokenId
data["device_id"] = deviceToken()
data["package_id"] = mRegionPackageId
data["type"] = type
return data
}
//Function to return distance of user from booth
private fun meterDistanceBtBoothAndUser(lat_booth: Float, lng_booth: Float, lat_user: Float, lng_user: Float): Double {
val pk = (180f / Math.PI).toFloat()
val a1 = lat_booth / pk
val a2 = lng_booth / pk
val b1 = lat_user / pk
val b2 = lng_user / pk
val t1 = Math.cos(a1.toDouble()) * Math.cos(a2.toDouble()) * Math.cos(b1.toDouble()) * Math.cos(b2.toDouble())
val t2 = Math.cos(a1.toDouble()) * Math.sin(a2.toDouble()) * Math.cos(b1.toDouble()) * Math.sin(b2.toDouble())
val t3 = Math.sin(a1.toDouble()) * Math.sin(b1.toDouble())
val tt = Math.acos(t1 + t2 + t3)
return 6366000 * tt
}
private fun takeUserToHomeScreen() {
if (mDoubleTourStatus) {
val timerData = TourTimePojo(mRegionPackageId, mTourEndTime, mPackageTokenId, STATUS_ACTIVATION, STATUS_RETURN, STATUS_INACTIVATION, mDoubleTourStatus)
Preferences.prefs?.saveValue(Constants.END_TIME, gson.toJson(timerData))
} else {
val timerData = TourTimePojo(mRegionPackageId, mTourEndTime, mPackageTokenId, STATUS_ACTIVATION, STATUS_RETURN, STATUS_INACTIVATION, mDoubleTourStatus)
Preferences.prefs?.saveValue(Constants.END_TIME, gson.toJson(timerData))
}
startActivity(Intent(this@MapBoxActivity, MainActivity::class.java))
finish()
}
/**
*Function to attached location listener
*/
private fun attachLocationOnOffListener() {
try {
registerReceiver(GpsReceiver(object : LocationCallBack {
override fun onLocationTriggered() {
if (isLocationEnabled(this@MapBoxActivity)) {
//location enable
if (isNetworkAvailable()) {
mViewModel?.getPackagesData(mRegionPackageId, deviceToken())
} else {
RetrievePackageSpots(baseContext, mRegionPackageId, false).execute()
}
} else {
//location disable
takeUserToHomeScreen()
}
}
}), IntentFilter(LocationManager.PROVIDERS_CHANGED_ACTION))
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun showLocationDialog() {
val alertDialog: AlertDialog? = this.let {
val builder = AlertDialog.Builder(it)
builder.setCancelable(false)
builder.setMessage(getString(R.string.txt_enable_location))
builder.apply {
setPositiveButton("Ok"
) { dialog, id ->
if (!isLocationEnabled(this@MapBoxActivity)) {
showLocationDialog()
}
}
}
builder.create()
}
alertDialog!!.show()
}
fun isLocationEnabled(context: Context): Boolean {
var locationMode = 0
val locationProviders: String
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
locationMode = Settings.Secure.getInt(context.contentResolver, Settings.Secure.LOCATION_MODE)
} catch (e: Settings.SettingNotFoundException) {
e.printStackTrace()
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF
} else {
locationProviders = Settings.Secure.getString(context.contentResolver, Settings.Secure.LOCATION_MODE)
return !TextUtils.isEmpty(locationProviders)
}
}
/**
* Function to handle navigation drawer clicks
*/
private fun navigationDrawer() {
mDrawerLayout = findViewById(R.id.drawer_layout)
navigationView = findViewById(R.id.design_navigation_view2)
iv_toggle_menu = findViewById(R.id.iv_toggle_menu)
tv_language.setOnClickListener {
mDrawerLayout.closeDrawer(GravityCompat.START)
takeUserToHomeScreen()
}
tv_tour_list.setOnClickListener {
mDrawerLayout.closeDrawer(GravityCompat.START)
takeUserToHomeScreen()
}
tv_end_tour.setOnClickListener {
mDrawerLayout.closeDrawer(GravityCompat.START)
/*Preferences.prefs!!.saveValue(Constants.END_TIME, "")
startActivity(Intent(this@MapBoxActivity, MainActivity::class.java))
finish()*/
mViewModel?.updateTourTokenTime(getUpdateTokenTimeParams(TYPE_EXPIRE))
}
mDrawerLayout.addDrawerListener(object : DrawerLayout.DrawerListener {
override fun onDrawerStateChanged(p0: Int) {
}
override fun onDrawerSlide(p0: View, p1: Float) {
}
override fun onDrawerClosed(p0: View) {
iv_toggle_menu.visibility = View.VISIBLE
}
override fun onDrawerOpened(p0: View) {
DrawableCompat.setTint(iv_closedrawer.drawable, ContextCompat.getColor(this@MapBoxActivity, R.color.black))
iv_toggle_menu.visibility = View.INVISIBLE
}
})
iv_toggle_menu.setOnClickListener {
mDrawerLayout.bringToFront()
if (mDrawerLayout.isDrawerOpen(Gravity.START)) {
mDrawerLayout.closeDrawer(GravityCompat.START)
iv_toggle_menu.visibility = View.VISIBLE
} else {
DrawableCompat.setTint(iv_closedrawer.drawable, ContextCompat.getColor(this@MapBoxActivity, R.color.black))
iv_toggle_menu.visibility = View.INVISIBLE
mDrawerLayout.openDrawer(GravityCompat.START)
}
}
iv_closedrawer.setOnClickListener {
mDrawerLayout.closeDrawer(GravityCompat.START)
iv_toggle_menu.visibility = View.VISIBLE
}
iv_toggle_menu.visibility = View.VISIBLE
}
@SuppressLint("MissingPermission")
private fun doLocationRequest() {
locationEngine = LocationEngineProvider.getBestLocationEngine(this)
val request = LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS)
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
.setMaxWaitTime(DEFAULT_MAX_WAIT_TIME)
.setDisplacement(10F)
.build()
locationEngine.requestLocationUpdates(request, callback, mainLooper)
locationEngine.getLastLocation(callback)
}
private class LocationListeningCallback internal constructor(activity: MapBoxActivity) : LocationEngineCallback<LocationEngineResult> {
private lateinit var listener: locationListener
fun onLocationChangeListener(listener: locationListener) {
this.listener = listener
}
override fun onSuccess(result: LocationEngineResult?) {
// The LocationEngineCallback interface's method which fires when the device's location has changed.
try {
result?.lastLocation
this.listener.onLocationChanged(result?.lastLocation?.latitude!!, result.lastLocation?.longitude!!)
Log.d("Location=", "Location=${result?.lastLocation}")
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun onFailure(exception: Exception) {
// The LocationEngineCallback interface's method which fires when the device's location can not be captured
Log.d("Location=", "${exception.message}")
}
}
@SuppressLint("MissingPermission")
private fun clickListeners() {
ivMapStyle.setOnClickListener {
if (ivMapStyle.tag.equals(MAP_NORMAL)) {
map?.setStyle(Style.SATELLITE)
ivMapStyle.tag = MAP_SATELLITE
ivMapStyle.setBackgroundResource(R.drawable.ic_satellite)
} else if (ivMapStyle.tag.equals(MAP_SATELLITE)) {
map?.setStyle(Style.LIGHT)
ivMapStyle.tag = MAP_NORMAL
ivMapStyle.setBackgroundResource(R.drawable.ic_map)
}
}
ivNavigate.setOnClickListener {
if (map!!.locationComponent.lastKnownLocation != null)
map?.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLng(map!!.locationComponent.lastKnownLocation?.latitude!!, map!!.locationComponent.lastKnownLocation?.longitude!!), 13.0))
}
}
private fun getBundleArguments() {
mRegionPackageId = intent.getStringExtra("packageId")
mPackageTokenId = intent.getStringExtra("packageTokenId")
mComingFrom = intent.getStringExtra("comingFrom")
mDoubleTourStatus = intent.getBooleanExtra("doubleTourStatus", false)
}
private fun attachObserver() {
mViewModel?.response?.observe(this, Observer { it ->
it.let {
if (it!!.status == 1) {
mRegionRegionSpot = it.data as List<DataItem>
mRegionToDownload = it.mapData
mRegionRoute = it.route
mRegionManualRoute = it.manual!![0]
packageSpotsListStr = gson.toJson(it)
val now = System.currentTimeMillis()
mTourEndTime = now + TimeUnit.MINUTES.toMillis(mRegionToDownload?.tourTime!!.toLong())
downloadTourPackageRegion(it.mapData?.packageId, it.mapData?.regionName)
} else {
showMessage(it.message!!)
}
}
})
mViewModel?.tokenResponse?.observe(this, Observer { it ->
it.let {
if (it!!.status == 1) {
when (it.type) {
TYPE_ACTIVATION -> {
STATUS_ACTIVATION = true
if (mRegionToDownload?.tourTime!!.isNotEmpty()) {
Preferences.initPreferences(this)
val gson = Gson()
if (mComingFrom.equals("available_location_fragment", true)) {
val timerJsonData = Preferences.prefs!!.getString(Constants.END_TIME, "")
//retrieve tour timer data stored in the database
val timerPojo: TourTimePojo = gson.fromJson(timerJsonData, TourTimePojo::class.java)
STATUS_ACTIVATION = timerPojo.statusActivation
STATUS_RETURN = timerPojo.statusReturn
STATUS_INACTIVATION = timerPojo.statusInactivation
//resume the tour timer
startTripTimeTracker((intent.getLongExtra("tourTimeLeft", 0) * 60000).toInt()).start()
} else {
startTripTimeTracker(mRegionToDownload?.tourTime!!.toInt() * 60000).start()
}
} else showMessage("Total tour time not available")
}
TYPE_RETURN -> {
STATUS_RETURN = true
}
TYPE_INACTIVATION -> {
STATUS_INACTIVATION = true
takeUserToHomeScreen()
}
TYPE_EXPIRE -> {
Preferences.prefs!!.saveValue(Constants.END_TIME, "")
startActivity(Intent(this@MapBoxActivity, MainActivity::class.java))
finish()
}
}
}
}
})
mViewModel?.apiError?.observe(this, Observer {
it?.let {
showMessage(it)
//showSnackBar(it)
}
})
mViewModel?.isLoading?.observe(this, Observer {
it?.let {
//showMessage(it)
//showLoading(it)
}
})
mViewModel?.onFailure?.observe(this, Observer {
it?.let {
//showMessage(it)
//showSnackBar(ApiFailureTypes().getFailureMessage(it))
}
})
}
fun isNetworkAvailable(): Boolean {
val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val netInfo = cm.activeNetworkInfo
if (netInfo != null && netInfo.isConnectedOrConnecting) {
return true
}
return false
}
@SuppressLint("MissingPermission")
private fun enableLocationComponent(loadedMapStyle: Style) {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {
// Get an instance of the component
val locationComponent = map!!.locationComponent
// Activate with options
locationComponent.activateLocationComponent(this, loadedMapStyle)
// Enable to make component visible
locationComponent.isLocationComponentEnabled = true
// Set the component's camera mode
//locationComponent.cameraMode = CameraMode.TRACKING
// Set the component's render mode
//locationComponent.renderMode = RenderMode.COMPASS
} else {
permissionsManager = PermissionsManager(this)
permissionsManager!!.requestLocationPermissions(this)
}
}
// Override Activity lifecycle methods
public override fun onResume() {
super.onResume()
mapView!!.onResume()
doLocationRequest()
}
override fun onStart() {
super.onStart()
mapView!!.onStart()
}
override fun onStop() {
super.onStop()
locationEngine.removeLocationUpdates(callback)
mapView!!.onStop()
}
public override fun onPause() {
super.onPause()
mapView!!.onPause()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapView!!.onSaveInstanceState(outState)
}
override fun onDestroy() {
super.onDestroy()
if (markerViewManager != null) {
markerViewManager?.onDestroy()
}
mapView!!.onDestroy()
}
override fun onLowMemory() {
super.onLowMemory()
mapView!!.onLowMemory()
}
fun deviceToken(): String {
return Settings.Secure.getString(this?.contentResolver, Settings.Secure.ANDROID_ID)
}
private fun downloadRegionDialog() {
// Set up download interaction. Display a dialog
// when the user clicks download button and require
// a user-provided region name
val builder = AlertDialog.Builder(this@MapBoxActivity)
val regionNameEdit = EditText(this@MapBoxActivity)
regionNameEdit.hint = getString(R.string.set_region_name_hint)
// Build the dialog box
builder.setTitle(getString(R.string.dialog_title))
.setView(regionNameEdit)
.setMessage(getString(R.string.dialog_message))
.setPositiveButton(getString(R.string.dialog_positive_button)) { dialog, which ->
val regionName = regionNameEdit.text.toString()
// Require a region name to begin the download.
// If the user-provided string is empty, display
// a toast message and do not begin download.
if (regionName.length == 0) {
Toast.makeText(this@MapBoxActivity, getString(R.string.dialog_toast), Toast.LENGTH_SHORT).show()
} else {
// Begin download process
//downloadRegion(regionName)
}
}
.setNegativeButton(getString(R.string.dialog_negative_button)) { dialog, which -> dialog.cancel() }
//Display the dialog
builder.show()
}
private fun downloadRegion(packageId: String?, pckRegionName: String?) {
// Define offline region parameters, including bounds,
// min/max zoom, and metadata
// Start the progressBar
startProgress()
// Create offline definition using the current
// style and boundaries of visible map area
val styleUrl = map!!.style!!.url
//LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
val bounds = LatLngBounds.Builder()
.include(LatLng(mRegionToDownload?.minLatitude!!.toDouble(), mRegionToDownload?.minLongitude!!.toDouble())) // Northeast
.include(LatLng(mRegionToDownload?.maxLatitude!!.toDouble(), mRegionToDownload?.maxLongitude!!.toDouble())) // Southwest
/*.include(LatLng(30.7168, 76.7474)) // Northeast
.include(LatLng(30.7307, 76.7785)) // Southwest*/
.build()
val minZoom = mRegionToDownload?.minZoom!!.toDouble()
val maxZoom = mRegionToDownload?.maxZoom!!.toDouble()
/*val minZoom = map!!.getCameraPosition().zoom
val maxZoom = map!!.getMaxZoomLevel()*/
val pixelRatio = this.resources.displayMetrics.density
val definition = OfflineTilePyramidRegionDefinition(styleUrl, bounds, minZoom, maxZoom, pixelRatio)
// Build a JSONObject using the user-defined offline region title,
// convert it into string, and use it to create a metadata variable.
// The metadata variable will later be passed to createOfflineRegion()
var metadata: ByteArray?
try {
val jsonObject = JSONObject()
jsonObject.put(JSON_FIELD_REGION_NAME, pckRegionName)
jsonObject.put(JSON_FIELD_REGION_ID, packageId)
val json = jsonObject.toString()
metadata = json.toByteArray(charset(JSON_CHARSET))
} catch (exception: Exception) {
Timber.e("Failed to encode metadata: %s", exception.message)
metadata = null
}
// Create the offline region and launch the download
offlineManager!!.createOfflineRegion(definition, metadata!!, object : OfflineManager.CreateOfflineRegionCallback {
override fun onCreate(offlineRegion: OfflineRegion) {
Timber.d("Offline region created: %s", packageId)
this@MapBoxActivity.offlineRegion = offlineRegion
launchDownload()
}
override fun onError(error: String) {
Timber.e("Error: %s", error)
}
})
}
private fun launchDownload() {
// Set up an observer to handle download progress and
// notify the user when the region is finished downloading
offlineRegion!!.setObserver(object : OfflineRegion.OfflineRegionObserver {
override fun onStatusChanged(status: OfflineRegionStatus) {
// Compute a percentage
val percentage = if (status.requiredResourceCount >= 0)
100.0 * status.completedResourceCount / status.requiredResourceCount
else
0.0
if (status.isComplete) {
// Download complete
endProgress(getString(R.string.end_progress_success))
//recall the method to load the downloaded region on map
downloadTourPackageRegion(mRegionToDownload?.packageId, mRegionToDownload?.regionName)
//downloadTourPackageRegion(it.mapData?.packageId, it.mapData?.regionName)
return
} else if (status.isRequiredResourceCountPrecise) {
// Switch to determinate state
setPercentage(Math.round(percentage).toInt())
}
// Log what is being currently downloaded
Timber.d("%s/%s resources; %s bytes downloaded.",
status.completedResourceCount.toString(),
status.requiredResourceCount.toString(),
status.completedResourceSize.toString())
}
override fun onError(error: OfflineRegionError) {
Timber.e("onError reason: %s", error.reason)
Timber.e("onError message: %s", error.message)
}
override fun mapboxTileCountLimitExceeded(limit: Long) {
Timber.e("Mapbox tile count limit exceeded: %s", limit)
}
})
// Change the region state
offlineRegion!!.setDownloadState(OfflineRegion.STATE_ACTIVE)
}
private fun downloadTourPackageRegion(packageId: String?, pckRegionName: String?) {
// Reset the region selected int to 0
regionSelected = -1
var status = false
try {
// Query the DB asynchronously
offlineManager!!.listOfflineRegions(object : OfflineManager.ListOfflineRegionsCallback {
override fun onList(offlineRegions: Array<OfflineRegion>?) {
// Check result. If no regions have beenOfflineManager
// downloaded yet, notify user and return
if (offlineRegions == null || offlineRegions.size == 0) {
downloadRegion(packageId, pckRegionName)
return
}
for (offlineRegion in offlineRegions) {
regionSelected++
//offlineRegionsNames.add(getRegionName(offlineRegion))
if (packageId == getRegionName(offlineRegion)) {
status = true
break
}
}
if (status) {
//region already downloaded
//val items = offlineRegionsNames.toTypedArray<CharSequence>()
val bounds = offlineRegions[regionSelected].definition.bounds
val regionZoom = offlineRegions[regionSelected].definition.minZoom
val cameraPosition = CameraPosition.Builder()
.target(bounds.center)
.zoom(regionZoom)
.build()
// Move camera to new position
map!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
addTourSpotsOnMap()
if (isNetworkAvailable()) {
RetrievePackageSpots(baseContext, mRegionToDownload?.packageId!!, true).execute()
} else {
RetrievePackageSpots(baseContext, mRegionToDownload?.packageId!!, false).execute()
}
} else {
//download region
downloadRegion(packageId, pckRegionName)
}
}
override fun onError(error: String) {
Timber.e("Error: %s", error)
}
})
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun createTourRegionMarker(number: String): Bitmap {
val markerLayout = getLayoutInflater().inflate(R.layout.marker_layout, null)
val markerImage = markerLayout.findViewById(R.id.marker_image) as ImageView
val markerNumber = markerLayout.findViewById(R.id.marker_text) as TextView
markerImage.setImageResource(R.mipmap.icon)
markerNumber.setText(number)
markerLayout.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
markerLayout.layout(0, 0, markerLayout.getMeasuredWidth(), markerLayout.getMeasuredHeight())
val bitmap = Bitmap.createBitmap(markerLayout.getMeasuredWidth(), markerLayout.getMeasuredHeight(), Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
markerLayout.draw(canvas)
return bitmap
}
private fun loadDownloadedRegion(packageId: String?, pckRegionName: String?) {
// Reset the region selected int to 0
regionSelected = -1
var status = false
// Query the DB asynchronously
offlineManager!!.listOfflineRegions(object : OfflineManager.ListOfflineRegionsCallback {
override fun onList(offlineRegions: Array<OfflineRegion>?) {
// Check result. If no regions have beenOfflineManager
// downloaded yet, notify user and return
if (offlineRegions == null || offlineRegions.size == 0) {
downloadRegion(packageId, pckRegionName)
return
}
for (offlineRegion in offlineRegions) {
regionSelected++
//offlineRegionsNames.add(getRegionName(offlineRegion))
if (packageId == getRegionName(offlineRegion)) {
status = true
break
}
}
if (status) {
//region already downloaded
//val items = offlineRegionsNames.toTypedArray<CharSequence>()
val bounds = offlineRegions[regionSelected].definition.bounds
val regionZoom = offlineRegions[regionSelected].definition.minZoom
val cameraPosition = CameraPosition.Builder()
.target(bounds.center)
.zoom(regionZoom)
.build()
// Move camera to new position
map!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
addTourSpotsOnMap()
} else {
//download region
downloadRegion(packageId, pckRegionName)
}
}
override fun onError(error: String) {
Timber.e("Error: %s", error)
}
})
}
private fun downloadedRegionList() {
// Build a region list when the user clicks the list button
// Reset the region selected int to 0
regionSelected = 1
// Query the DB asynchronously
offlineManager!!.listOfflineRegions(object : OfflineManager.ListOfflineRegionsCallback {
override fun onList(offlineRegions: Array<OfflineRegion>?) {
// Check result. If no regions have been
// downloaded yet, notify user and return
if (offlineRegions == null || offlineRegions.size == 0) {
Toast.makeText(applicationContext, getString(R.string.toast_no_regions_yet), Toast.LENGTH_SHORT).show()
return
}
// Add all of the region names to a list
val offlineRegionsNames = ArrayList<String>()
for (offlineRegion in offlineRegions) {
offlineRegionsNames.add(getRegionName(offlineRegion))
}
val items = offlineRegionsNames.toTypedArray<CharSequence>()
val bounds = offlineRegions[regionSelected].definition.bounds
val regionZoom = offlineRegions[regionSelected].definition.minZoom
//getRoute(origin, destination);
// Create new camera position
val cameraPosition = CameraPosition.Builder()
.target(bounds.center)
.zoom(regionZoom)
.build()
// Move camera to new position
map!!.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
addTourSpotsOnMap()
}
override fun onError(error: String) {
Timber.e("Error: %s", error)
}
})
}
private fun getRoute(origin: Waypoint, destination: Waypoint) {
val md = MapboxDirections.Builder()
.setAccessToken(getString(R.string.mapbox_key))
.setOrigin(origin)
.setDestination(destination)
.setProfile(DirectionsCriteria.PROFILE_WALKING)
.build()
md.enqueue(object : Callback<DirectionsResponse> {
override fun onResponse(response: Response<DirectionsResponse>, retrofit: Retrofit) {
// You can get generic HTTP info about the response
Log.d(LOG_TAG, "Response code: " + response.code())
// Print some info about the route
currentRoute = response.body().routes[0]
showMessage(String.format("Route is %d meters long.", currentRoute!!.distance))
// Draw the route on the map
//drawRoute(currentRoute);
}
override fun onFailure(t: Throwable) {
showMessage("Error: " + t.message)
}
})
}
private fun drawRoute(route: DirectionsRoute) {
// Convert List<Waypoint> into LatLng[]
// List<Waypoint> waypoints = route.getGeometry().getWaypoints();
// LatLng[] point = new LatLng[waypoints.size()];
// for (int i = 0; i < waypoints.size(); i++) {
// point[i] = new LatLng(
// waypoints.get(i).getLatitude(),
// waypoints.get(i).getLongitude());
// }
//
// // Draw Points on MapView
// map.addPolyline(new PolylineOptions()
// .add(point)
// .color(Color.parseColor("#3887be"))
// .width(5));
}
private fun showMessage(message: String) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
private fun getRegionName(offlineRegion: OfflineRegion): String {
// Get the region name from the offline region metadata
var regionName: String
try {
val metadata = offlineRegion.metadata
val json = String(metadata, charset(JSON_CHARSET))
val jsonObject = JSONObject(json)
regionName = jsonObject.getString(JSON_FIELD_REGION_ID)
} catch (exception: Exception) {
Timber.e("Failed to decode metadata: %s", exception.message)
regionName = String.format(getString(R.string.region_name), offlineRegion.id)
}
return regionName
}
// Progress bar methods
private fun startProgress() {
//Disable buttons
downloadButton!!.isEnabled = false
listButton!!.isEnabled = false
// Start and show the progress bar
isEndNotified = false
progressBar!!.isIndeterminate = true
progressBar!!.visibility = View.VISIBLE
}
private fun setPercentage(percentage: Int) {
progressBar!!.isIndeterminate = false
progressBar!!.progress = percentage
}
private fun endProgress(message: String) {
// Don't notify more than once
if (isEndNotified) {
return
}
// Enable buttons
downloadButton!!.isEnabled = true
listButton!!.isEnabled = true
// Stop and hide the progress bar
isEndNotified = true
progressBar!!.isIndeterminate = false
progressBar!!.visibility = View.GONE
// Show a toast
//Toast.makeText(this@MapBoxActivity, message, Toast.LENGTH_LONG).show()
}
override fun onExplanationNeeded(permissionsToExplain: List<String>) {
Toast.makeText(this, "Need Permission to show your current location", Toast.LENGTH_LONG).show()
}
override fun onPermissionResult(granted: Boolean) {
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
permissionsManager!!.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
fun addTourSpotsOnMap() {
points = ArrayList()
tvTourName.text = mRegionToDownload?.tourNameLanguage
map!!.setMaxZoomPreference(mRegionToDownload!!.maxZoom!!.toDouble())
map!!.setMinZoomPreference(mRegionToDownload!!.minZoom!!.toDouble())
mRegionRegionSpot!!.forEachIndexed { index, dataItem ->
points.add(LatLng(dataItem.latitude!!.toDouble(), dataItem.longitude!!.toDouble()))
}
//ADD SPOT ON MAP
for (i in points.indices) {
val options = MarkerOptions()
val iconFactory = IconFactory.getInstance(this@MapBoxActivity)
val index = i
val icon = iconFactory.fromBitmap(drawTextToBitmap(this@MapBoxActivity, R.drawable.ic_circle, index.plus(1).toString()))
options.icon = icon
options.position = points[i]
map!!.addMarker(options)
}
//ATTACHED CLICKED LISTENER ON MARKER CLICK
map!!.setOnMarkerClickListener {
points.forEachIndexed { index, latLng ->
if (latLng == it.position) {
val uri: Uri? = getFileUri(index)
val name: String = uri?.lastPathSegment as String
val extension = name.substring(name.lastIndexOf(".") + 1)
val data = mRegionRegionSpot?.get(index)
if (data?.fileType.equals("audio")) {
playAudio(data, uri.toString())
} else if (data?.fileType.equals("youtube")) {
if (data?.youtubeId != "") {
if (data?.youtubeId!!.contains("youtube")) {
playYoutubeVideo(data.youtubeId)
} else {
playVideoWithoutSubtitle(data.youtubeId)
}
} else showMessage(getString(R.string.txt_videoid_missing))
} else if (extension == "mp4") {
//PLAY VIDEO WITH VTT FILE
if (data?.fileType.equals("vtt") && data?.spotVideoVtt != "") {
playVideoWithSubtitle(uri.toString(), data)
}
//PLAY VIDEO WITHOUT VTT
if (data?.fileType.equals("video") && data?.spotVideoVtt == "") {
playVideoWithoutSubtitle(uri.toString())
}
} else {
Toast.makeText(this@MapBoxActivity, "Server Error", Toast.LENGTH_SHORT).show()
}
}
}
false
}
if (mRegionToDownload?.tourTime!!.isNotEmpty()) {
//startTripTimeTracker(mRegionToDownload?.tourTime!!.toInt() * 60000).start()
} else showMessage("Total tour time not available")
if (mRegionToDownload?.manualPoint == "0") {
//automatic
drawRouteWithMapboxPoints()
} else {
//manual
drawRouteWithManualPoints()
}
showSpotDetails()
}
private fun drawRouteWithManualPoints() {
try {
val coordinates = mRegionManualRoute?.trips
val point = ArrayList<LatLng>()
coordinates!!.forEachIndexed { index, location ->
point.add(LatLng(location!![0]!!.toDouble(), location[1]!!.toDouble()))
}
map?.addPolyline(PolylineOptions()
.addAll(point)
.color(Color.parseColor("#2196F3"))
.width(3F)
)
} catch (e: Exception) {
e.printStackTrace()
Toast.makeText(this@MapBoxActivity, "No manual route found", Toast.LENGTH_LONG).show()
}
}
private fun drawRouteWithMapboxPoints() {
try {
val coordinates = mRegionRoute?.trips!![0]?.geometry?.coordinates
val point = ArrayList<LatLng>()
coordinates!!.forEachIndexed { _, location ->
point.add(LatLng(
location!![0]!!,
location[1]!!))
}
map?.addPolyline(PolylineOptions()
.addAll(point)
.color(Color.parseColor("#2196F3"))
.width(3F)
)
} catch (e: Exception) {
e.printStackTrace()
if (this.mRegionRegionSpot!!.size >= 2) {
val latLngBounds = LatLngBounds.Builder()
.include(LatLng(this.mRegionRegionSpot!![0].latitude!!.toDouble(), this.mRegionRegionSpot!![0].longitude!!.toDouble()))
.include(LatLng(this.mRegionRegionSpot!![1].latitude!!.toDouble(), this.mRegionRegionSpot!![1].longitude!!.toDouble()))
.build()
map!!.easeCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 500), 2000)
}
//Toast.makeText(this@MapBoxActivity, "No automatic route found", Toast.LENGTH_LONG).show()
}
}
fun drawTextToBitmap(gContext: Context,
gResId: Int,
gText: String): Bitmap {
val resources = gContext.resources
val scale = resources.displayMetrics.density
var bitmap = BitmapFactory.decodeResource(resources, gResId)
var bitmapConfig: Bitmap.Config? = bitmap.config
// set default bitmap config if none
if (bitmapConfig == null) {
bitmapConfig = Bitmap.Config.ARGB_8888
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true)
val canvas = Canvas(bitmap)
// new antialised Paint
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
// text color - #000000
paint.color = Color.rgb(255, 255, 255)
// text size in pixels
paint.textSize = (14 * scale).toInt().toFloat()
//text bold
paint.typeface = create(DEFAULT, Typeface.BOLD)
// text shadow
//paint.setShadowLayer(1f, 0f, 1f, Color.WHITE)
// draw text to the Canvas center
val bounds = Rect()
paint.getTextBounds(gText, 0, gText.length, bounds)
val x = (bitmap.width - bounds.width()) / 2
val y = (bitmap.height + bounds.height()) / 2
canvas.drawText(gText, x.toFloat(), y.toFloat(), paint)
return bitmap
}
/**
* file_type will have value either video or audio
* spot_video_vtt contain the vtt file otherwise it will be empty
*/
override fun onItemClickListener(pos: Int, uri: String) {
val data = mRegionRegionSpot?.get(pos)
//PLAY AUDIO
if (data?.fileType.equals("audio")) {
playAudio(data, uri)
return
}
//PLAY VIDEO WITH VTT FILE
if (data?.fileType.equals("vtt") && data?.spotVideoVtt != "") {
playVideoWithSubtitle(uri, data)
return
}
//PLAY VIDEO WITOUT VTT
if (data?.fileType.equals("video") && data?.spotVideoVtt == "") {
playVideoWithoutSubtitle(uri)
return
}
//PLAY YOUTUBE VIDEO
if (data?.fileType.equals("youtube") && data?.youtubeId != "") {
if (data?.youtubeId!!.contains("youtube")) {
playYoutubeVideo(data.youtubeId)
} else {
playVideoWithoutSubtitle(data.youtubeId)
}
} else {
Toast.makeText(this@MapBoxActivity, getString(R.string.txt_videoid_missing), Toast.LENGTH_SHORT).show()
}
}
private fun playAudio(data: DataItem?, uri: String) {
val audioManager: AudioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
val mPlayTourSpot = Dialog(this, android.R.style.Theme_Translucent)
mPlayTourSpot.window!!.requestFeature(Window.FEATURE_NO_TITLE)
mPlayTourSpot.setContentView(R.layout.content_play_audio)
mPlayTourSpot.setCancelable(true)
mPlayTourSpot.ivTourAudioCancel.setOnClickListener {
nPlayer!!.stop()
nPlayer!!.release()
mPlayTourSpot.dismiss()
}
mPlayTourSpot.setOnKeyListener { dialog, keyCode, event ->
when (keyCode) {
KeyEvent.KEYCODE_BACK -> {
nPlayer!!.stop()
nPlayer!!.release()
mPlayTourSpot.dismiss()
}
KeyEvent.KEYCODE_VOLUME_UP -> {
if (event.action == KeyEvent.ACTION_DOWN) {
audioManager.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_PLAY_SOUND)
}
}
KeyEvent.KEYCODE_VOLUME_DOWN -> {
if (event.action == KeyEvent.ACTION_DOWN) {
audioManager.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_PLAY_SOUND)
}
}
}
return@setOnKeyListener true
}
mPlayTourSpot.setOnDismissListener {
object : DialogInterface {
override fun dismiss() {
if (nPlayer != null) {
nPlayer!!.release()
nPlayer = null
}
}
override fun cancel() {
if (nPlayer != null) {
nPlayer!!.release()
nPlayer = null
}
}
}
}
mPlayTourSpot.tvSpotTitle.text = data?.spotName
mPlayTourSpot.tvSpotDesc.text = data?.spotDesc
Picasso.get()
.load(data!!.vThumbnail)
.networkPolicy(NetworkPolicy.OFFLINE)
.into(mPlayTourSpot.ivSpotImage, object : com.squareup.picasso.Callback {
override fun onSuccess() {
}
override fun onError(e: Exception?) {
Picasso.get()
.load(data!!.vThumbnail)
.into(mPlayTourSpot.ivSpotImage, object : com.squareup.picasso.Callback {
override fun onSuccess() {
}
override fun onError(e: Exception?) {
print("Couldn't fetch data")
}
})
}
})
mPlayTourSpot.window!!.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT)
val player: ExoPlayer
if (nPlayer != null) {
nPlayer!!.release()
nPlayer = null
}
val defaultBandwidthMeter = DefaultBandwidthMeter()
val dataSourceFactory = DefaultDataSourceFactory(this, Util.getUserAgent(this, this!!.getString(R.string.app_name)), defaultBandwidthMeter)
dataSourceFac = dataSourceFactory
val videoTrackSelectionFactory = AdaptiveTrackSelection.Factory(defaultBandwidthMeter)
val trackSelector = DefaultTrackSelector(videoTrackSelectionFactory)
val contentMediaSource = buildMediaSource(Uri.parse(uri))
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector)
player.setPlayWhenReady(true)
mPlayTourSpot.pvSpotAudio.player = player
player.prepare(contentMediaSource)
nPlayer = player
nPlayer?.addListener(object : Player.EventListener {
override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters?) {
Log.d(TAG, "" + playbackParameters)
}
override fun onSeekProcessed() {
Log.d(TAG, "")
}
override fun onTracksChanged(trackGroups: TrackGroupArray?, trackSelections: TrackSelectionArray?) {
Log.d(TAG, "" + trackGroups)
}
override fun onPlayerError(error: ExoPlaybackException?) {
Log.d(TAG, "" + error!!.message)
}
override fun onLoadingChanged(isLoading: Boolean) {
Log.d(TAG, "loading [$isLoading]")
}
override fun onPositionDiscontinuity(reason: Int) {
Log.d(TAG, "" + reason)
}
override fun onRepeatModeChanged(repeatMode: Int) {
Log.d(TAG, "" + repeatMode)
}
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
Log.d(TAG, "" + shuffleModeEnabled)
}
override fun onTimelineChanged(timeline: Timeline?, manifest: Any?, reason: Int) {
Log.d(TAG, "" + timeline)
}
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
if (playbackState == Player.STATE_ENDED) {
if (nPlayer != null) {
nPlayer!!.release()
nPlayer = null
mPlayTourSpot.dismiss()
}
}
}
})
mPlayTourSpot.show()
}
private fun playVideoWithSubtitle(video: String, data: DataItem?) {
val audioManager: AudioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
val mPlayTourVideo = Dialog(this, android.R.style.Theme_Translucent)
mPlayTourVideo.window!!.requestFeature(Window.FEATURE_NO_TITLE)
mPlayTourVideo.setContentView(R.layout.play_tour_video)
mPlayTourVideo.setCancelable(true)
mPlayTourVideo.window!!.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT)
mPlayTourVideo.ivTourVideoCancel.setOnClickListener {
nPlayer!!.stop()
nPlayer!!.release()
mPlayTourVideo.dismiss()
}
mPlayTourVideo.setOnKeyListener { dialog, keyCode, event ->
when (keyCode) {
KeyEvent.KEYCODE_BACK -> {
nPlayer!!.stop()
nPlayer!!.release()
mPlayTourVideo.dismiss()
}
KeyEvent.KEYCODE_VOLUME_UP -> {
if (event.action == KeyEvent.ACTION_DOWN) {
audioManager.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_PLAY_SOUND)
}
}
KeyEvent.KEYCODE_VOLUME_DOWN -> {
if (event.action == KeyEvent.ACTION_DOWN) {
audioManager.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_PLAY_SOUND)
}
}
}
return@setOnKeyListener true
}
val player: ExoPlayer
if (nPlayer != null) {
nPlayer!!.release()
nPlayer = null
}
val defaultBandwidthMeter = DefaultBandwidthMeter()
val dataSourceFactory = DefaultDataSourceFactory(this, Util.getUserAgent(this, this.getString(R.string.app_name)), defaultBandwidthMeter)
dataSourceFac = dataSourceFactory
val videoTrackSelectionFactory = AdaptiveTrackSelection.Factory(defaultBandwidthMeter)
val trackSelector = DefaultTrackSelector(videoTrackSelectionFactory)
val contentMediaSource = buildMediaSource(Uri.parse(video))
val mediaSources = arrayOfNulls<MediaSource>(2) //The Size must change depending on the Uris
mediaSources[0] = contentMediaSource //uri
val subtitleSource = SingleSampleMediaSource(Uri.parse(data?.spotVideoVtt),
dataSourceFactory, Format.createTextSampleFormat(null, MimeTypes.TEXT_VTT, Format.NO_VALUE, "en", null),
C.TIME_UNSET)
mediaSources[1] = subtitleSource
val mediaSource = MergingMediaSource(mediaSources[0], mediaSources[1])
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector)
player.setPlayWhenReady(true)
mPlayTourVideo.pvTourVideo.player = player
player.prepare(mediaSource)
nPlayer = player
nPlayer?.addListener(object : Player.EventListener {
override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters?) {
Log.d(TAG, "" + playbackParameters)
}
override fun onSeekProcessed() {
Log.d(TAG, "")
}
override fun onTracksChanged(trackGroups: TrackGroupArray?, trackSelections: TrackSelectionArray?) {
Log.d(TAG, "" + trackGroups)
}
override fun onPlayerError(error: ExoPlaybackException?) {
Log.d(TAG, "" + error!!.message)
}
override fun onLoadingChanged(isLoading: Boolean) {
Log.d(TAG, "loading [$isLoading]")
}
override fun onPositionDiscontinuity(reason: Int) {
Log.d(TAG, "" + reason)
}
override fun onRepeatModeChanged(repeatMode: Int) {
Log.d(TAG, "" + repeatMode)
}
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
Log.d(TAG, "" + shuffleModeEnabled)
}
override fun onTimelineChanged(timeline: Timeline?, manifest: Any?, reason: Int) {
Log.d(TAG, "" + timeline)
}
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
if (playbackState == Player.STATE_ENDED) {
if (nPlayer != null) {
nPlayer!!.release()
nPlayer = null
mPlayTourVideo.dismiss()
}
}
}
})
mPlayTourVideo.show()
}
override fun onBackPressed() {
if (nPlayer != null) {
nPlayer!!.stop()
nPlayer!!.release()
nPlayer = null
}
}
override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KEYCODE_BACK1) {
onBackPressed()
return true
}
return super.onKeyUp(keyCode, event)
}
private fun playYoutubeVideo(youtubeId: String?) {
@SuppressLint("StaticFieldLeak") val mExtractor = object : YouTubeExtractor(this) {
override fun onExtractionComplete(sparseArray: SparseArray<YtFile>?, videoMeta: VideoMeta) {
if (sparseArray != null) {
playVideoWithoutSubtitle(sparseArray.get(18).url)
} else {
showMessage("This video is no longer available on youtube")
}
}
}
mExtractor.extract(youtubeId, true, true)
}
private fun playVideoWithoutSubtitle(video: String) {
val audioManager: AudioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
val mPlayTourVideo = Dialog(this, android.R.style.Theme_Translucent)
mPlayTourVideo.window!!.requestFeature(Window.FEATURE_NO_TITLE)
mPlayTourVideo.setContentView(R.layout.play_tour_video)
mPlayTourVideo.setCancelable(true)
mPlayTourVideo.window!!.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT)
mPlayTourVideo.ivTourVideoCancel.setOnClickListener {
if (nPlayer != null) {
nPlayer!!.stop()
nPlayer!!.release()
}
mPlayTourVideo.dismiss()
}
mPlayTourVideo.setOnKeyListener { dialog, keyCode, event ->
when (keyCode) {
KeyEvent.KEYCODE_BACK -> {
nPlayer!!.stop()
nPlayer!!.release()
mPlayTourVideo.dismiss()
}
KeyEvent.KEYCODE_VOLUME_UP -> {
if (event.action == KeyEvent.ACTION_DOWN) {
audioManager.adjustVolume(AudioManager.ADJUST_RAISE, AudioManager.FLAG_PLAY_SOUND)
}
}
KeyEvent.KEYCODE_VOLUME_DOWN -> {
if (event.action == KeyEvent.ACTION_DOWN) {
audioManager.adjustVolume(AudioManager.ADJUST_LOWER, AudioManager.FLAG_PLAY_SOUND)
}
}
}
return@setOnKeyListener true
}
val player: ExoPlayer
if (nPlayer != null) {
nPlayer!!.release()
nPlayer = null
}
val defaultBandwidthMeter = DefaultBandwidthMeter()
val dataSourceFactory = DefaultDataSourceFactory(this, Util.getUserAgent(this, this!!.getString(R.string.app_name)), defaultBandwidthMeter)
dataSourceFac = dataSourceFactory
val videoTrackSelectionFactory = AdaptiveTrackSelection.Factory(defaultBandwidthMeter)
val trackSelector = DefaultTrackSelector(videoTrackSelectionFactory)
val contentMediaSource = buildMediaSource(Uri.parse(video))
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector)
player.setPlayWhenReady(true)
mPlayTourVideo.pvTourVideo.player = player
player.prepare(contentMediaSource)
nPlayer = player
nPlayer?.addListener(object : Player.EventListener {
override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters?) {
Log.d(TAG, "" + playbackParameters)
}
override fun onSeekProcessed() {
Log.d(TAG, "")
}
override fun onTracksChanged(trackGroups: TrackGroupArray?, trackSelections: TrackSelectionArray?) {
Log.d(TAG, "" + trackGroups)
}
override fun onPlayerError(error: ExoPlaybackException?) {
Log.d(TAG, "" + error!!.message)
}
override fun onLoadingChanged(isLoading: Boolean) {
Log.d(TAG, "loading [$isLoading]")
}
override fun onPositionDiscontinuity(reason: Int) {
Log.d(TAG, "" + reason)
}
override fun onRepeatModeChanged(repeatMode: Int) {
Log.d(TAG, "" + repeatMode)
}
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
Log.d(TAG, "" + shuffleModeEnabled)
}
override fun onTimelineChanged(timeline: Timeline?, manifest: Any?, reason: Int) {
Log.d(TAG, "" + timeline)
}
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
if (playbackState == Player.STATE_ENDED) {
if (nPlayer != null) {
nPlayer!!.release()
nPlayer = null
mPlayTourVideo.dismiss()
}
}
}
})
mPlayTourVideo.show()
}
val playVideo: (String) -> Unit = {
val mPlayTourVideo = Dialog(this, android.R.style.Theme_Translucent)
mPlayTourVideo.window!!.requestFeature(Window.FEATURE_NO_TITLE)
mPlayTourVideo.setContentView(R.layout.play_tour_video)
mPlayTourVideo.setCancelable(true)
mPlayTourVideo.window!!.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT)
val player: ExoPlayer
if (nPlayer != null) {
nPlayer!!.release()
nPlayer = null
}
val defaultBandwidthMeter = DefaultBandwidthMeter()
val dataSourceFactory = DefaultDataSourceFactory(this, Util.getUserAgent(this, this!!.getString(R.string.app_name)), defaultBandwidthMeter)
dataSourceFac = dataSourceFactory
val videoTrackSelectionFactory = AdaptiveTrackSelection.Factory(defaultBandwidthMeter)
val trackSelector = DefaultTrackSelector(videoTrackSelectionFactory)
val contentMediaSource = buildMediaSource(Uri.parse(it))
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector)
player.setPlayWhenReady(true)
mPlayTourVideo.pvTourVideo.player = player
player.prepare(contentMediaSource)
nPlayer = player
nPlayer?.addListener(object : Player.EventListener {
override fun onPlaybackParametersChanged(playbackParameters: PlaybackParameters?) {
Log.d(TAG, "" + playbackParameters)
}
override fun onSeekProcessed() {
Log.d(TAG, "")
}
override fun onTracksChanged(trackGroups: TrackGroupArray?, trackSelections: TrackSelectionArray?) {
Log.d(TAG, "" + trackGroups)
}
override fun onPlayerError(error: ExoPlaybackException?) {
Log.d(TAG, "" + error!!.message)
}
override fun onLoadingChanged(isLoading: Boolean) {
Log.d(TAG, "loading [$isLoading]")
}
override fun onPositionDiscontinuity(reason: Int) {
Log.d(TAG, "" + reason)
}
override fun onRepeatModeChanged(repeatMode: Int) {
Log.d(TAG, "" + repeatMode)
}
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
Log.d(TAG, "" + shuffleModeEnabled)
}
override fun onTimelineChanged(timeline: Timeline?, manifest: Any?, reason: Int) {
Log.d(TAG, "" + timeline)
}
override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
if (playbackState == Player.STATE_ENDED) {
if (nPlayer != null) {
nPlayer!!.release()
nPlayer = null
mPlayTourVideo.dismiss()
}
}
}
})
mPlayTourVideo.show()
}
private fun buildMediaSource(uri: Uri): MediaSource {
@C.ContentType val type = Util.inferContentType(uri)
when (type) {
/*C.TYPE_DASH:
return new DashMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
C.TYPE_SS:
return new SsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);*/
C.TYPE_HLS -> return HlsMediaSource.Factory(dataSourceFac).createMediaSource(uri)
C.TYPE_OTHER -> return ExtractorMediaSource.Factory(dataSourceFac).createMediaSource(uri)
else -> throw IllegalStateException("Unsupported type: $type") as Throwable
}
}
private fun showSpotDetails() {
val downloadList: ArrayList<String> = ArrayList()
mRegionRegionSpot!!.forEachIndexed { index, e ->
downloadList.add(mRegionRegionSpot!![index].sVideo!!)
}
// DataHeb.addRequestUrl(imgUrlList)
// enqueueDownloads()
rvSpotList!!.addItemDecoration(DividerItemDecoration(this@MapBoxActivity, LinearLayoutManager.HORIZONTAL))
spotListAdapter = SpotListAdapter(applicationContext, this.mRegionRegionSpot!!, playVideo)
spotListAdapter?.onItemClickedListener(this)
val horizontalLayoutManager = LinearLayoutManager(this@MapBoxActivity, LinearLayoutManager.HORIZONTAL, false)
rvSpotList!!.layoutManager = horizontalLayoutManager
rvSpotList!!.adapter = spotListAdapter
dialogMsg = mRegionRegionSpot!![downloadListPosition].spotName!!.toString()
initDownload(mRegionRegionSpot!![downloadListPosition].sVideo!!.toString())
}
companion object {
private val TAG = "OffManActivity"
// JSON encoding/decoding
val JSON_CHARSET = "UTF-8"
val JSON_FIELD_REGION_NAME = "FIELD_REGION_NAME"
val JSON_FIELD_REGION_ID = "FIELD_REGION_ID"
val UNKNOWN_REMAINING_TIME: Long = -1
val UNKNOWN_DOWNLOADED_BYTES_PER_SECOND: Long = 0
var nPlayer: ExoPlayer? = null
}
//HANDLING ROOM DATABASE
inner class InsertPackageSpots// only retain a weak reference to the activity
internal constructor(val packageId: String, val myDataset: String, val context: Context) : AsyncTask<Void, Void, Boolean>() {
// doInBackground methods runs on a worker thread
override fun doInBackground(vararg objs: Void): Boolean? {
var packageSpots = PackageSpots(packageId, myDataset)
//adding to database
DatabaseClient.getInstance(context)
.appDatabase
.tourPackageDao()
.insertPackageSpots(packageSpots)
return true
}
// onPostExecute runs on main thread
override fun onPostExecute(bool: Boolean?) {
}
}
inner class UpdatePackageSpots// only retain a weak reference to the activity
internal constructor(val packageId: String, val myDataset: String, val context: Context) : AsyncTask<Void, Void, Boolean>() {
// doInBackground methods runs on a worker thread
override fun doInBackground(vararg objs: Void): Boolean? {
val packageSpots = PackageSpots(packageId, myDataset)
/*var cat: CategoriesTable = CategoriesTable(myDataset.get(j).catName.toString(),
myDataset.get(j).catColor.toString()
, myDataset.get(j).catValue.toString(), myDataset.get(j).icon.toString(), false)*/
//adding to database
DatabaseClient.getInstance(context)
.appDatabase
.tourPackageDao()
.updatePackageSpots(packageId, packageSpotsListStr)
return true
}
// onPostExecute runs on main thread
override fun onPostExecute(bool: Boolean?) {
if (bool!!) {
}
}
}
inner class RetrievePackageSpots// only retain a weak reference to the activity
internal constructor(@SuppressLint("StaticFieldLeak") val context: Context, val packageSpotId: String, val internetStatus: Boolean) : AsyncTask<Void, Void, List<PackageSpots>>() {
override fun doInBackground(vararg voids: Void): List<PackageSpots> {
return DatabaseClient
.getInstance(context)
.appDatabase
.tourPackageDao()
.getPackageSpots(packageSpotId)
}
override fun onPostExecute(data: List<PackageSpots>) {
super.onPostExecute(data)
if (data.size > 0) {
if (internetStatus) {
//fresh data available, udate the database
UpdatePackageSpots(mRegionToDownload?.packageId!!, packageSpotsListStr, baseContext).execute()
} else {
//package exist in database
val gson = Gson()
val spots = gson.fromJson(data.get(0).packageSpots, PackageSpotsResponse::class.java)
mRegionRegionSpot = spots.data as List<DataItem>
mRegionToDownload = spots.mapData
mRegionRoute = spots.route
loadDownloadedRegion(spots.mapData?.packageId, spots.mapData?.regionName)
}
} else {
if (packageSpotsListStr != "") {
InsertPackageSpots(mRegionToDownload?.packageId!!, packageSpotsListStr, baseContext).execute()
} else {
showMessage(getString(R.string.txt_dwnld_tour_spots))
}
}
}
}
/**
*CODE FOR DOWNLOADING FILES AUDIO,VIDEO,VTT AND SO ON
*/
fun initDownload(url: String) {
val path = Environment.getExternalStorageDirectory().toString() + File.separator + "TourGuide/"
val directory = File(path)
val files = directory.listFiles()
val fileName = url.substring(url.lastIndexOf('/') + 1)
val mFileNameList = mutableListOf<String>()
//val mFileNameList.binarySearch(location.id.toString()) == -1
if (files != null) {
files.forEachIndexed { index, file ->
mFileNameList.add(file.name)
}
if (mFileNameList.contains(fileName)) {
print("FILE PRESENT INSIDE FOLDER")
if (downloadListPosition < mRegionRegionSpot!!.size - 1) {
downloadListPosition = downloadListPosition.plus(1)
dialogMsg = mRegionRegionSpot!![downloadListPosition].spotName!!.toString()
initDownload(mRegionRegionSpot!![downloadListPosition].sVideo.toString())
}
} else {
print("FILE NOT PRESENT INSIDE FOLDER")
dialogMsg = mRegionRegionSpot!![downloadListPosition].spotName!!.toString()
DownloadTask().execute(url)
}
} else {
DownloadTask().execute(url)
}
}
/**
* Async task to download file from uri
*/
@SuppressLint("StaticFieldLeak")
inner class DownloadTask : AsyncTask<String, String, String>() {
private var progressDialog: ProgressDialog? = null
private var fileName: String? = null
private var folder: String? = null
private val isDownloaded: Boolean = false
/**
* Before starting background thread
* Show Progress Bar Dialog
*/
override fun onPreExecute() {
super.onPreExecute()
this.progressDialog = ProgressDialog(this@MapBoxActivity)
this.progressDialog!!.setTitle(getString(R.string.txt_downloading))
this.progressDialog!!.setMessage(dialogMsg)
this.progressDialog!!.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
this.progressDialog!!.setCancelable(false)
this.progressDialog!!.show()
}
override fun doInBackground(vararg f_url: String?): String {
var count: Int = 0
try {
val url = URL(f_url[0])
val connection = url.openConnection()
connection.connect()
// getting file length
val lengthOfFile = connection.contentLength
// input stream to read file - with 8k buffer
val input = BufferedInputStream(url.openStream(), 8192)
val timestamp = SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(Date())
//Extract file name from URL
fileName = f_url[0]?.substring(f_url[0]!!.lastIndexOf('/') + 1, f_url[0]!!.length)
folder = Environment.getExternalStorageDirectory().toString() + File.separator + "TourGuide/"
//Create TourGuide folder if it does not exist
val directory = File(folder!!)
if (!directory.exists()) {
directory.mkdirs()
}
// Output stream to write file
val output = FileOutputStream(folder!! + fileName!!)
val data = ByteArray(1024)
var total: Long = 0
//while ((count = input.read(data)) != -1) {
while (count != -1) {
count = input.read(data)
total += count.toLong()
// publishing the progress....
// After this onProgressUpdate will be called
publishProgress("" + (total * 100 / lengthOfFile).toInt())
Log.d(TAG, "Progress: " + (total * 100 / lengthOfFile).toInt())
// writing data to file
output.write(data, 0, count)
}
// flushing output
output.flush()
// closing streams
output.close()
input.close()
return "Downloaded at: $folder$fileName"
} catch (e: Exception) {
Log.e("Error: ", e.message)
}
return "Something went wrong"
}
override fun onPostExecute(message: String?) {
// dismiss the dialog after the file was downloaded
this.progressDialog!!.dismiss()
if (downloadListPosition != mRegionRegionSpot!!.size - 1) {
downloadListPosition = downloadListPosition.plus(1)
initDownload(mRegionRegionSpot!![downloadListPosition].sVideo.toString())
}
// Display File path after downloading
//Toast.makeText(applicationContext, message, Toast.LENGTH_LONG).show()
}
override fun onProgressUpdate(vararg progress: String?) {
progressDialog!!.progress = Integer.parseInt(progress[0])
}
}
/**
* Method to return file uri
*/
private fun getFileUri(position: Int): Uri {
val fileName = mRegionRegionSpot?.get(position)?.sVideo!!.substring(mRegionRegionSpot!![position].sVideo!!.lastIndexOf('/') + 1)
val path = Environment.getExternalStorageDirectory().absolutePath + File.separator + "TourGuide/$fileName"
val file = File(path)
var uri: Uri?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
uri = Uri.parse(file.path)
} else {
uri = Uri.fromFile(file)
}
return uri
}
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black">
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/pvTourVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
app:auto_show="true"
app:resize_mode="fit"
app:surface_type="texture_view"
app:use_artwork="true"
app:use_controller="true" />
<ImageView
android:id="@+id/ivTourVideoCancel"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginTop="@dimen/_5sdp"
android:layout_marginEnd="@dimen/_5sdp"
android:src="@android:drawable/ic_menu_close_clear_cancel"
android:visibility="visible" />
</RelativeLayout>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment