Social Event Voting
In this guide you will learn how to render an interactive map, and log touch gestures input by the user, such as pinch rotate, swipe or move(pan).
The map is fully 3D, supporting pan, pinch-zoom, pinch-rotate, tilt, single pointer long touch, single pointer double touch, two-pointer touch.
Setup
- Get your Magic Lane API key token: if you do not have a token, see the Getting Started guide.
- Download the Maps & Navigation SDK for Android archive file.
- Download the SocialEventVoting project archive file or clone the project with git.
- See the Configure Android Example guide.
Run the example
In Android Studio, from the File
menu, select Sync Project with Gradle Files
.


An android device should be connected via USB cable. Press SHIFT+F10 to compile, install and run the example on the android device.
How it works
You can open the MainActivity.kt file to see how to access and display the number of votes for a social event while displaying an interactive map.
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
progressBar = findViewById(R.id.progress_bar)
gemSurfaceView = findViewById(R.id.gem_surface_view)
eventVotingContainer = findViewById(R.id.event_voting_container)
icon = findViewById(R.id.icon)
text = findViewById(R.id.text)
time = findViewById(R.id.time)
score = findViewById(R.id.score)
thumbUpButton = findViewById(R.id.thumb_up_button)
pleaseSelectText = findViewById(R.id.please_select_text)
SdkSettings.onMapDataReady = onMapDataReady@{ isReady ->
if (!isReady) return@onMapDataReady
// Defines an action that should be done when the world map is ready (Updated/loaded).
gemSurfaceView.mapView?.onTouch = { xy ->
SdkCall.execute {
gemSurfaceView.mapView?.cursorScreenPosition = xy
val overlays = gemSurfaceView.mapView?.cursorSelectionOverlayItems
if (!overlays.isNullOrEmpty())
{
val overlay = overlays[0]
if (overlay.overlayInfo?.uid == ECommonOverlayId.SocialReports.value)
{
Util.postOnMain { showVotingPanel(overlay) }
return@execute
}
}
Util.postOnMain { hideVotingPanel() }
}
}
}
SdkSettings.onApiTokenRejected = {
showDialog("TOKEN REJECTED")
}
if (!Util.isInternetConnected(this))
{
showDialog("You must be connected to the internet!")
}
}
The onCreate()
function is overridden in the MainActivity: AppCompatActivity()
class, and checks if internet access is available, showing a dialog message if not.
findViewById()
is used to obtain pointers to the various graphical user interface elements where text or graphical data is to be displayed.
When the map is loaded, SdkSettings.onMapDataReady =
a touch handler is defined to get the screen position where a user tap occurred: gemSurfaceView.mapView?.onTouch = { xy ->
then the xy screen position is set so the mapView can use it to search for map elements near that position: gemSurfaceView.mapView?.cursorScreenPosition = xy



When the user taps on the map, the overlay items, if any, near the tap position are obtained:
val overlays = gemSurfaceView.mapView?.cursorSelectionOverlayItems
and if the array is not empty, then the first item, at index 0, is selected:
val overlay = overlays[0]
and if it is a social reports item,
if (overlay.overlayInfo?.uid == ECommonOverlayId.SocialReports.value)
then the voting panel is displayed:
Util.postOnMain { showVotingPanel(overlay) }
private fun showVotingPanel(overlay: OverlayItem)
{
if (!eventVotingContainer.isVisible)
{
eventVotingContainer.visibility = View.VISIBLE
pleaseSelectText.visibility = View.GONE
}
var bitmap: Bitmap? = null
var textStr = ""
var timeStr = ""
var scoreStr = ""
var thumbUpBitmap: Bitmap? = null
val eventImageSize = resources.getDimension(R.dimen.event_image_size).toInt()
val imageSize = resources.getDimension(R.dimen.image_size).toInt()
SdkCall.execute {
bitmap = overlay.image?.asBitmap(eventImageSize, eventImageSize)
textStr = overlay.name.toString()
scoreStr = overlay.getPreviewData()?.find { it.key == "score" }?.valueString.toString()
val stamp = overlay.getPreviewData()?.find { it.key == "create_stamp_utc" }?.valueLong ?: 0
val eventTime = Calendar.getInstance(Locale.getDefault()).also { it.timeInMillis = stamp * 1000 }
val now = Calendar.getInstance(Locale.getDefault()).also { it.timeInMillis = System.currentTimeMillis() }
val dateFormat = if (eventTime.get(Calendar.YEAR) == now.get(Calendar.YEAR) &&
eventTime.get(Calendar.MONTH) == now.get(Calendar.MONTH) &&
eventTime.get(Calendar.DAY_OF_MONTH) == now.get(Calendar.DAY_OF_MONTH))
{
"HH:mm"
}
else { "dd/MM/yyyy" }
timeStr = SimpleDateFormat(dateFormat, Locale.getDefault()).format(Date(eventTime.timeInMillis))
if (overlay.getPreviewData()?.find { it.key == "allow_thumb" }?.valueBoolean == true)
{
thumbUpBitmap =
GemUtilImages.asBitmap(ImageDatabase().getImageById(SdkImages.SocialReports.Social_Thumbs_Up.value),
imageSize, imageSize)
}
}
icon.setImageBitmap(bitmap)
text.text = textStr
time.text = timeStr
score.text = scoreStr
if (thumbUpBitmap != null)
{
thumbUpButton.apply {
visibility = View.VISIBLE
setImageBitmap(thumbUpBitmap)
setOnClickListener {
val errorCode = SdkCall.execute
{ SocialOverlay.confirmReport(overlay, ProgressListener()) } ?: -1
if (errorCode < 0)
{
showDialog("Confirm report failed with error: ${GemError.getMessage(errorCode)}")
}
eventVotingContainer.visibility = View.GONE
}
}
}
else { thumbUpButton.visibility = View.GONE }
}
The showVotingPanel()
function first makes the voting container panel visible, if it is not.
eventVotingContainer.visibility = View.VISIBLE
Next, the time of the event is converted to hours and minutes, if it occurred today, or in day, month and year format otherwise.
The icon image associated with the event is icon.setImageBitmap(bitmap)
; the number of votes displayed in the upper right corner of the panel is the score.text = scoreStr
whereas the name of the event is text.text = textStr
and the date/time is time.text = timeStr
.
A click listener is set for the panel, setOnClickListener {
and the panel is made to disappear when the user clicks on it: eventVotingContainer.visibility = View.GONE
Android Examples
Maps SDK for Android Examples can be downloaded or cloned with Git.