Access the expiration information of an expired mobile map package.
Use case
The data contained within a mobile map package (MMPK) may only be relevant for a fixed period of time. Using ArcGIS Pro, the author of an MMPK can set an expiration date to ensure the user is aware the data is out of date.
As long as the author of an MMPK has set an expiration date, the expiration date can be read even if the MMPK has not yet expired. For example, developers could also use this API to warn app users that an MMPK may be expiring soon.
How to use the sample
Launch the app. The author of the MMPK used in this sample chose to set the MMPK's map as still readable, even if it's expired. The app presents expiration information to the user.
How it works
- Create a
MobileMapPackageobject by providing a path to the local mobile map package file. - Load the
MobileMapPackage. - Present the mobile map package's expiration information to the user:
- Use
Expiration.messageto get the expiration message set by the author of the MMPK. - Use
Expiration.dateTimeto get the expiration date set by the author of the MMPK. - Use
Expiration.isExpiredto determine whether the MMPK has expired.
- Use
Relevant API
- Expiration
- MobileMapPackage
Offline data
This sample uses the LothianRiversAnno - Expired mobile map package. It is downloaded from ArcGIS Online automatically.
Tags
expiration, mmpk
Sample Code
/* Copyright 2025 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.esri.arcgismaps.sample.showmobilemappackageexpirationdate.components
import android.app.Application
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import com.arcgismaps.mapping.ArcGISMap
import com.arcgismaps.mapping.MobileMapPackage
import com.esri.arcgismaps.sample.sampleslib.components.MessageDialogViewModel
import com.esri.arcgismaps.sample.showmobilemappackageexpirationdate.R
import java.io.File
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import java.util.Locale
import kotlinx.coroutines.launch
class ShowMobileMapPackageExpirationDateViewModel(val app: Application) : AndroidViewModel(app) {
// The map displayed on the MapView. Updated after loading the mobile map package
var arcGISMap: ArcGISMap by mutableStateOf(ArcGISMap())
private set
// Message dialog view model for handling error messages
val messageDialogVM = MessageDialogViewModel()
// Expiration UI states exposed to the screen
var isExpired by mutableStateOf(false)
private set
var expirationMessage by mutableStateOf("")
private set
var expirationDateText by mutableStateOf("N/A")
private set
// Build the provision path where offline resources are stored for the sample app
private val provisionPath: String by lazy {
val basePath = app.getExternalFilesDir(null)?.path.toString()
val appFolderName = app.getString(R.string.show_mobile_map_package_expiration_date_app_name)
basePath + File.separator + appFolderName
}
init {
// Load the mobile map package and update map/expiration info
viewModelScope.launch {
loadMobileMapPackageAndUpdateState()
}
}
// Loads the local mobile map package and updates the map and expiration states
private suspend fun loadMobileMapPackageAndUpdateState() {
// Locate the LothianRiversAnno.mmpk file in the provisioned path
val mmpkFile = File(provisionPath, "LothianRiversAnno.mmpk")
if (!mmpkFile.exists()) {
messageDialogVM.showMessageDialog("Mobile map package file does not exist.")
return
}
// Create and load the mobile map package
val mobileMapPackage = MobileMapPackage(mmpkFile.path)
mobileMapPackage.load().onSuccess {
// If the loaded mobile map package does not contain any maps
val map = mobileMapPackage.maps.firstOrNull()
if (map == null) {
messageDialogVM.showMessageDialog("Mobile map package does not contain a map")
return@onSuccess
}
// Set the map to the first map in the mobile map package
arcGISMap = map
// Read expiration information from the mobile map package
mobileMapPackage.expiration?.let { expiration ->
isExpired = expiration.isExpired
expirationMessage = expiration.message
val formatter = DateTimeFormatter
.ofLocalizedDateTime(FormatStyle.SHORT)
.withLocale(Locale.getDefault())
.withZone(ZoneId.systemDefault())
expirationDateText = expiration.dateTime?.let { formatter.format(it) } ?: "N/A"
}
}.onFailure { error ->
messageDialogVM.showMessageDialog(
title = "Failed to load the mobile map package",
description = error.message.toString()
)
}
}
}