Skip to content

Commit ab3ed8b

Browse files
rom14514eri9000shubham7109
authored
Sample - Show mobile map package expiration date (#437)
Co-authored-by: Erick Lopez Solis <erick_solis@esri.com> Co-authored-by: Shubham Sharma <shubhamsharma@esri.com>
1 parent 33818b7 commit ab3ed8b

File tree

12 files changed

+441
-0
lines changed

12 files changed

+441
-0
lines changed

samples/add-elevation-source-from-tile-package/src/main/java/com/esri/arcgismaps/sample/addelevationsourcefromtilepackage/DownloadActivity.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/* Copyright 2025 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
117
package com.esri.arcgismaps.sample.addelevationsourcefromtilepackage
218

319
import android.content.Intent

samples/apply-dictionary-renderer-to-graphics-overlay/src/main/java/com/esri/arcgismaps/sample/applydictionaryrenderertographicsoverlay/DownloadActivity.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/* Copyright 2025 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
117
package com.esri.arcgismaps.sample.applydictionaryrenderertographicsoverlay
218

319
import android.content.Intent
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Show mobile map package expiration date
2+
3+
Access the expiration information of an expired mobile map package.
4+
5+
![Image of Show mobile map package expiration date](show-mobile-map-package-expiration-date.png)
6+
7+
## Use case
8+
9+
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.
10+
11+
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.
12+
13+
## How to use the sample
14+
15+
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.
16+
17+
## How it works
18+
19+
1. Create a `MobileMapPackage` object by providing a path to the local mobile map package file.
20+
2. Load the `MobileMapPackage`.
21+
3. Present the mobile map package's expiration information to the user:
22+
* Use `Expiration.message` to get the expiration message set by the author of the MMPK.
23+
* Use `Expiration.dateTime` to get the expiration date set by the author of the MMPK.
24+
* Use `Expiration.isExpired` to determine whether the MMPK has expired.
25+
26+
## Relevant API
27+
28+
* Expiration
29+
* MobileMapPackage
30+
31+
## Offline data
32+
33+
This sample uses the [LothianRiversAnno - Expired](https://www.arcgis.com/home/item.html?id=174150279af74a2ba6f8b87a567f480b) mobile map package. It is downloaded from ArcGIS Online automatically.
34+
35+
## Tags
36+
37+
expiration, mmpk
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"category": "Maps",
3+
"description": "Access the expiration information of an expired mobile map package.",
4+
"formal_name": "ShowMobileMapPackageExpirationDate",
5+
"ignore": false,
6+
"images": [
7+
"show-mobile-map-package-expiration-date.png"
8+
],
9+
"keywords": [
10+
"expiration",
11+
"mmpk",
12+
"Expiration",
13+
"MobileMapPackage"
14+
],
15+
"language": "kotlin",
16+
"provision_from": [
17+
"https://www.arcgis.com/home/item.html?id=174150279af74a2ba6f8b87a567f480b"
18+
],
19+
"provision_to": [],
20+
"redirect_from": "",
21+
"relevant_apis": [
22+
"Expiration",
23+
"MobileMapPackage"
24+
],
25+
"snippets": [
26+
"src/main/java/com/esri/arcgismaps/sample/showmobilemappackageexpirationdate/components/ShowMobileMapPackageExpirationDateViewModel.kt",
27+
"src/main/java/com/esri/arcgismaps/sample/showmobilemappackageexpirationdate/MainActivity.kt",
28+
"src/main/java/com/esri/arcgismaps/sample/showmobilemappackageexpirationdate/DownloadActivity.kt",
29+
"src/main/java/com/esri/arcgismaps/sample/showmobilemappackageexpirationdate/screens/ShowMobileMapPackageExpirationDateScreen.kt"
30+
],
31+
"title": "Show mobile map package expiration date"
32+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
plugins {
2+
alias(libs.plugins.arcgismaps.android.library)
3+
alias(libs.plugins.arcgismaps.android.library.compose)
4+
alias(libs.plugins.arcgismaps.kotlin.sample)
5+
alias(libs.plugins.gradle.secrets)
6+
}
7+
8+
secrets {
9+
// this file doesn't contain secrets, it just provides defaults which can be committed into git.
10+
defaultPropertiesFileName = "secrets.defaults.properties"
11+
}
12+
13+
android {
14+
namespace = "com.esri.arcgismaps.sample.showmobilemappackageexpirationdate"
15+
buildFeatures {
16+
buildConfig = true
17+
}
18+
}
19+
20+
dependencies {
21+
// Only module specific dependencies needed here
22+
}
75.6 KB
Loading
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
3+
4+
<uses-permission android:name="android.permission.INTERNET" />
5+
6+
<application><activity
7+
android:exported="true"
8+
android:name=".MainActivity"
9+
android:label="@string/show_mobile_map_package_expiration_date_app_name">
10+
11+
</activity>
12+
<activity
13+
android:name=".DownloadActivity"
14+
android:exported="true"
15+
android:label="@string/show_mobile_map_package_expiration_date_app_name" />
16+
</application>
17+
18+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/* Copyright 2025 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
17+
package com.esri.arcgismaps.sample.showmobilemappackageexpirationdate
18+
19+
import android.content.Intent
20+
import android.os.Bundle
21+
import com.esri.arcgismaps.sample.sampleslib.DownloaderActivity
22+
23+
class DownloadActivity : DownloaderActivity() {
24+
override fun onCreate(savedInstanceState: Bundle?) {
25+
super.onCreate(savedInstanceState)
26+
downloadAndStartSample(
27+
Intent(this, MainActivity::class.java),
28+
getString(R.string.show_mobile_map_package_expiration_date_app_name),
29+
listOf(
30+
"https://www.arcgis.com/home/item.html?id=174150279af74a2ba6f8b87a567f480b"
31+
)
32+
)
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/* Copyright 2025 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
17+
package com.esri.arcgismaps.sample.showmobilemappackageexpirationdate
18+
19+
import android.os.Bundle
20+
import androidx.activity.ComponentActivity
21+
import androidx.activity.compose.setContent
22+
import androidx.compose.material3.MaterialTheme
23+
import androidx.compose.material3.Surface
24+
import androidx.compose.runtime.Composable
25+
import com.arcgismaps.ApiKey
26+
import com.arcgismaps.ArcGISEnvironment
27+
import com.esri.arcgismaps.sample.sampleslib.theme.SampleAppTheme
28+
import com.esri.arcgismaps.sample.showmobilemappackageexpirationdate.screens.ShowMobileMapPackageExpirationDateScreen
29+
30+
class MainActivity : ComponentActivity() {
31+
32+
override fun onCreate(savedInstanceState: Bundle?) {
33+
super.onCreate(savedInstanceState)
34+
// authentication with an API key or named user is
35+
// required to access basemaps and other location services
36+
ArcGISEnvironment.apiKey = ApiKey.create(BuildConfig.ACCESS_TOKEN)
37+
38+
setContent {
39+
SampleAppTheme {
40+
ShowMobileMapPackageExpirationDateApp()
41+
}
42+
}
43+
}
44+
45+
@Composable
46+
private fun ShowMobileMapPackageExpirationDateApp() {
47+
Surface(color = MaterialTheme.colorScheme.background) {
48+
ShowMobileMapPackageExpirationDateScreen(
49+
sampleName = getString(R.string.show_mobile_map_package_expiration_date_app_name)
50+
)
51+
}
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/* Copyright 2025 Esri
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*
15+
*/
16+
17+
package com.esri.arcgismaps.sample.showmobilemappackageexpirationdate.components
18+
19+
import android.app.Application
20+
import androidx.compose.runtime.getValue
21+
import androidx.compose.runtime.mutableStateOf
22+
import androidx.compose.runtime.setValue
23+
import androidx.lifecycle.AndroidViewModel
24+
import androidx.lifecycle.viewModelScope
25+
import com.arcgismaps.mapping.ArcGISMap
26+
import com.arcgismaps.mapping.MobileMapPackage
27+
import com.esri.arcgismaps.sample.sampleslib.components.MessageDialogViewModel
28+
import com.esri.arcgismaps.sample.showmobilemappackageexpirationdate.R
29+
import java.io.File
30+
import java.time.ZoneId
31+
import java.time.format.DateTimeFormatter
32+
import java.time.format.FormatStyle
33+
import java.util.Locale
34+
import kotlinx.coroutines.launch
35+
36+
class ShowMobileMapPackageExpirationDateViewModel(val app: Application) : AndroidViewModel(app) {
37+
// The map displayed on the MapView. Updated after loading the mobile map package
38+
var arcGISMap: ArcGISMap by mutableStateOf(ArcGISMap())
39+
private set
40+
41+
// Message dialog view model for handling error messages
42+
val messageDialogVM = MessageDialogViewModel()
43+
44+
// Expiration UI states exposed to the screen
45+
var isExpired by mutableStateOf(false)
46+
private set
47+
48+
var expirationMessage by mutableStateOf("")
49+
private set
50+
51+
var expirationDateText by mutableStateOf("N/A")
52+
private set
53+
54+
// Build the provision path where offline resources are stored for the sample app
55+
private val provisionPath: String by lazy {
56+
val basePath = app.getExternalFilesDir(null)?.path.toString()
57+
val appFolderName = app.getString(R.string.show_mobile_map_package_expiration_date_app_name)
58+
basePath + File.separator + appFolderName
59+
}
60+
61+
init {
62+
// Load the mobile map package and update map/expiration info
63+
viewModelScope.launch {
64+
loadMobileMapPackageAndUpdateState()
65+
}
66+
}
67+
68+
// Loads the local mobile map package and updates the map and expiration states
69+
private suspend fun loadMobileMapPackageAndUpdateState() {
70+
// Locate the LothianRiversAnno.mmpk file in the provisioned path
71+
val mmpkFile = File(provisionPath, "LothianRiversAnno.mmpk")
72+
if (!mmpkFile.exists()) {
73+
messageDialogVM.showMessageDialog("Mobile map package file does not exist.")
74+
return
75+
}
76+
77+
// Create and load the mobile map package
78+
val mobileMapPackage = MobileMapPackage(mmpkFile.path)
79+
mobileMapPackage.load().onSuccess {
80+
// If the loaded mobile map package does not contain any maps
81+
val map = mobileMapPackage.maps.firstOrNull()
82+
if (map == null) {
83+
messageDialogVM.showMessageDialog("Mobile map package does not contain a map")
84+
return@onSuccess
85+
}
86+
87+
// Set the map to the first map in the mobile map package
88+
arcGISMap = map
89+
90+
// Read expiration information from the mobile map package
91+
mobileMapPackage.expiration?.let { expiration ->
92+
isExpired = expiration.isExpired
93+
expirationMessage = expiration.message
94+
95+
val formatter = DateTimeFormatter
96+
.ofLocalizedDateTime(FormatStyle.SHORT)
97+
.withLocale(Locale.getDefault())
98+
.withZone(ZoneId.systemDefault())
99+
100+
expirationDateText = expiration.dateTime?.let { formatter.format(it) } ?: "N/A"
101+
}
102+
}.onFailure { error ->
103+
messageDialogVM.showMessageDialog(
104+
title = "Failed to load the mobile map package",
105+
description = error.message.toString()
106+
)
107+
}
108+
}
109+
}

0 commit comments

Comments
 (0)