diff --git a/samples/add-raster-from-file/README.md b/samples/add-raster-from-file/README.md
new file mode 100644
index 000000000..bfc05ca5f
--- /dev/null
+++ b/samples/add-raster-from-file/README.md
@@ -0,0 +1,34 @@
+# Add raster from file
+
+Create and use a raster layer made from a local raster file.
+
+![Image of add raster from file](add-raster-from-file.png)
+
+## Use case
+
+Rasters can be digital aerial photographs, imagery from satellites, digital pictures, or even scanned maps. An end-user will frequently need to import raster files acquired through various data-collection methods into their map to view and analyze the data.
+
+## How to use the sample
+
+When the sample starts, a raster will be loaded from a file and displayed in the map view.
+
+## How it works
+
+1. Create a `Raster` from a raster file.
+2. Create a `RasterLayer` from the raster.
+3. Add it as an operational layer with `map.getOperationalLayers().add(rasterLayer)`.
+
+## Relevant API
+
+* Raster
+* RasterLayer
+
+## Additional information
+
+See the topic [What is raster data?](http://desktop.arcgis.com/en/arcmap/10.3/manage-data/raster-and-images/what-is-raster-data.htm) in the *ArcMap* documentation for more information about raster images.
+
+This sample uses the GeoViewCompose Toolkit module to be able to implement a Composable MapView.
+
+## Tags
+
+data, geoviewcompose, image, import, layer, raster, toolkit, visualization
diff --git a/samples/add-raster-from-file/README.metadata.json b/samples/add-raster-from-file/README.metadata.json
new file mode 100644
index 000000000..4c2bbb961
--- /dev/null
+++ b/samples/add-raster-from-file/README.metadata.json
@@ -0,0 +1,34 @@
+{
+ "category": "Layers",
+ "description": "Create and use a raster layer made from a local raster file.",
+ "formal_name": "AddRasterFromFile",
+ "ignore": false,
+ "images": [
+ "add-raster-from-file.png"
+ ],
+ "keywords": [
+ "data",
+ "geoviewcompose",
+ "image",
+ "import",
+ "layer",
+ "raster",
+ "toolkit",
+ "visualization",
+ "Raster",
+ "RasterLayer"
+ ],
+ "language": "kotlin",
+ "redirect_from": "",
+ "relevant_apis": [
+ "Raster",
+ "RasterLayer"
+ ],
+ "snippets": [
+ "src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/components/AddRasterFromFileViewModel.kt",
+ "src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/DownloadActivity.kt",
+ "src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/MainActivity.kt",
+ "src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/screens/AddRasterFromFileScreen.kt"
+ ],
+ "title": "Add raster from file"
+}
diff --git a/samples/add-raster-from-file/add-raster-from-file.png b/samples/add-raster-from-file/add-raster-from-file.png
new file mode 100644
index 000000000..b35b0524a
Binary files /dev/null and b/samples/add-raster-from-file/add-raster-from-file.png differ
diff --git a/samples/add-raster-from-file/build.gradle.kts b/samples/add-raster-from-file/build.gradle.kts
new file mode 100644
index 000000000..42ce040e5
--- /dev/null
+++ b/samples/add-raster-from-file/build.gradle.kts
@@ -0,0 +1,22 @@
+plugins {
+ alias(libs.plugins.arcgismaps.android.library)
+ alias(libs.plugins.arcgismaps.android.library.compose)
+ alias(libs.plugins.arcgismaps.kotlin.sample)
+ alias(libs.plugins.gradle.secrets)
+}
+
+secrets {
+ // this file doesn't contain secrets, it just provides defaults which can be committed into git.
+ defaultPropertiesFileName = "secrets.defaults.properties"
+}
+
+android {
+ namespace = "com.esri.arcgismaps.sample.addrasterfromfile"
+ buildFeatures {
+ buildConfig = true
+ }
+}
+
+dependencies {
+ // Only module specific dependencies needed here
+}
diff --git a/samples/add-raster-from-file/src/main/AndroidManifest.xml b/samples/add-raster-from-file/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..5fea7af33
--- /dev/null
+++ b/samples/add-raster-from-file/src/main/AndroidManifest.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/DownloadActivity.kt b/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/DownloadActivity.kt
new file mode 100644
index 000000000..912985b91
--- /dev/null
+++ b/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/DownloadActivity.kt
@@ -0,0 +1,37 @@
+/* Copyright 2024 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.addrasterfromfile
+
+import android.content.Intent
+import android.os.Bundle
+import com.esri.arcgismaps.sample.sampleslib.DownloaderActivity
+import kotlin.collections.listOf
+import kotlin.jvm.java
+
+class DownloadActivity : DownloaderActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ downloadAndStartSample(
+ Intent(this, MainActivity::class.java),
+ // get the app name of the sample
+ getString(R.string.add_raster_from_file_app_name),
+ listOf(
+ "https://arcgisruntime.maps.arcgis.com/home/item.html?id=7c4c679ab06a4df19dc497f577f111bd"
+ )
+ )
+ }
+}
diff --git a/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/MainActivity.kt b/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/MainActivity.kt
new file mode 100644
index 000000000..1fb1f261d
--- /dev/null
+++ b/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/MainActivity.kt
@@ -0,0 +1,53 @@
+/* Copyright 2024 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.addrasterfromfile
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Surface
+import androidx.compose.runtime.Composable
+import com.arcgismaps.ApiKey
+import com.arcgismaps.ArcGISEnvironment
+import com.esri.arcgismaps.sample.sampleslib.theme.SampleAppTheme
+import com.esri.arcgismaps.sample.addrasterfromfile.screens.AddRasterFromFileScreen
+
+class MainActivity : ComponentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ // authentication with an API key or named user is
+ // required to access basemaps and other location services
+ ArcGISEnvironment.apiKey = ApiKey.create(BuildConfig.ACCESS_TOKEN)
+
+ setContent {
+ SampleAppTheme {
+ AddRasterFromFileApp()
+ }
+ }
+ }
+
+ @Composable
+ private fun AddRasterFromFileApp() {
+ Surface(color = MaterialTheme.colorScheme.background) {
+ AddRasterFromFileScreen(
+ sampleName = getString(R.string.add_raster_from_file_app_name)
+ )
+ }
+ }
+}
diff --git a/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/components/AddRasterFromFileViewModel.kt b/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/components/AddRasterFromFileViewModel.kt
new file mode 100644
index 000000000..df0a64a32
--- /dev/null
+++ b/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/components/AddRasterFromFileViewModel.kt
@@ -0,0 +1,77 @@
+/* Copyright 2024 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.addrasterfromfile.components
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.viewModelScope
+import com.arcgismaps.mapping.ArcGISMap
+import com.arcgismaps.mapping.BasemapStyle
+import com.arcgismaps.mapping.layers.RasterLayer
+import com.arcgismaps.raster.Raster
+import com.arcgismaps.toolkit.geoviewcompose.MapViewProxy
+import com.esri.arcgismaps.sample.addrasterfromfile.R
+import com.esri.arcgismaps.sample.sampleslib.components.MessageDialogViewModel
+import kotlinx.coroutines.launch
+import java.io.File
+
+class AddRasterFromFileViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val provisionPath: String by lazy { application.getExternalFilesDir(null)?.path.toString() +
+ File.separator +
+ application.getString(R.string.add_raster_from_file_app_name)
+ }
+
+ val mapViewProxy = MapViewProxy()
+
+ // create a raster
+ val raster = Raster.createWithPath(provisionPath +
+ File.separator + "raster-file" + File.separator + "Shasta.tif")
+
+ // create a raster layer
+ val rasterLayer = RasterLayer(raster)
+
+ val arcGISMap = ArcGISMap(BasemapStyle.ArcGISImagery).apply {
+ operationalLayers.add(rasterLayer)
+ }
+
+ // Create a message dialog view model for handling error messages
+ val messageDialogVM = MessageDialogViewModel()
+
+ init {
+ viewModelScope.launch {
+ arcGISMap.load().onFailure { error ->
+ messageDialogVM.showMessageDialog(
+ "Failed to load map",
+ error.message.toString()
+ )
+ }
+ rasterLayer.load().onSuccess {
+ // Set the viewpoint to the raster layer's extent
+ val extent = rasterLayer.fullExtent
+ if (extent != null) {
+ mapViewProxy.setViewpointGeometry(extent, paddingInDips = 20.0)
+ }
+ }.onFailure { error ->
+ messageDialogVM.showMessageDialog(
+ "Failed to load raster layer",
+ error.message.toString()
+ )
+ }
+ }
+ }
+}
diff --git a/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/screens/AddRasterFromFileScreen.kt b/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/screens/AddRasterFromFileScreen.kt
new file mode 100644
index 000000000..35a36e120
--- /dev/null
+++ b/samples/add-raster-from-file/src/main/java/com/esri/arcgismaps/sample/addrasterfromfile/screens/AddRasterFromFileScreen.kt
@@ -0,0 +1,65 @@
+/* Copyright 2024 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.addrasterfromfile.screens
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Scaffold
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.lifecycle.viewmodel.compose.viewModel
+import com.arcgismaps.toolkit.geoviewcompose.MapView
+import com.esri.arcgismaps.sample.addrasterfromfile.components.AddRasterFromFileViewModel
+import com.esri.arcgismaps.sample.sampleslib.components.MessageDialog
+import com.esri.arcgismaps.sample.sampleslib.components.SampleTopAppBar
+
+/**
+ * Main screen layout for the sample app
+ */
+@Composable
+fun AddRasterFromFileScreen(sampleName: String) {
+ val mapViewModel: AddRasterFromFileViewModel = viewModel()
+ Scaffold(
+ topBar = { SampleTopAppBar(title = sampleName) },
+ content = {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(it),
+ ) {
+ MapView(
+ modifier = Modifier
+ .fillMaxSize()
+ .weight(1f),
+ arcGISMap = mapViewModel.arcGISMap,
+ mapViewProxy = mapViewModel.mapViewProxy
+ )
+ }
+
+ mapViewModel.messageDialogVM.apply {
+ if (dialogStatus) {
+ MessageDialog(
+ title = messageTitle,
+ description = messageDescription,
+ onDismissRequest = ::dismissDialog
+ )
+ }
+ }
+ }
+ )
+}
diff --git a/samples/add-raster-from-file/src/main/res/values/strings.xml b/samples/add-raster-from-file/src/main/res/values/strings.xml
new file mode 100644
index 000000000..c2c289ac0
--- /dev/null
+++ b/samples/add-raster-from-file/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Add raster from file
+