Open Mobile Map Package

Screenshot of Open Mobile Map Package App

Description

This sample demonstrates how to open and display a map from a Mobile Map Package.

Features

  • MapView
  • MobileMapPackage

Developer Pattern

This sample takes a Mobile Map Package that was created in ArcGIS Pro, and displays a ArcGISMap from within the package in a MapView. This is accomplished by calling MobileMapPackage.loadAsyc() and waiting for its load status to be completed. Once the package is loaded, you can access its maps, and assign one of the maps to be viewed in the MapView. This sample uses the Android [Constraint Layout](https://developer.android.com/training/constraint-layout/index.html). In order to use you must ensure you have the latest Android Support Repository. Details for installing can be found [here](https://developer.android.com/training/constraint-layout/index.html#add-constraintlayout-to-your-project).

Provision your device

  1. Download the data from ArcGIS Online.
  2. Extract the contents of the downloaded zip file to disk.
  3. Create an ArcGIS/samples/MapPackage folder on your device. You can use the Android Debug Bridge (adb) tool found in <sdk-dir>/platform-tools.
  4. Open up a command prompt and execute the adb shell command to start a remote shell on your target device.
  5. Navigate to your sdcard directory, e.g. cd /sdcard/.
  6. Create the ArcGIS/samples/MapPackage directory, mkdir ArcGIS/samples/MapPackage.
  7. You should now have the following directory on your target device, /sdcard/ArcGIS/samples/MapPackage. We will copy the contents of the downloaded data into this directory. Note: Directory may be slightly different on your device.
  8. Exit the shell with the, exit command.
  9. While still in your command prompt, navigate to the folder where you extracted the contents of the data from step 1 and execute the following command:
adb push Yellowstone.mmpk /sdcard/ArcGIS/samples/MapPackage

LinkLocal Location

Yellowstone Mobile Map Package

<sdcard>/ArcGIS/samples/MapPackage/Yellowstone.mmpk

Code

/* Copyright 2016 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.arcgisruntime.sample.openmobilemappackage;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;

import com.esri.arcgisruntime.loadable.LoadStatus;
import com.esri.arcgisruntime.mapping.MobileMapPackage;
import com.esri.arcgisruntime.mapping.view.MapView;

import java.io.File;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MMPK";
    private static final String FILE_EXTENSION = ".mmpk";
    private static File extStorDir;
    private static String extSDCardDirName;
    private static String filename;
    private static String mmpkFilePath;
    private MapView mMapView;
    private MobileMapPackage mapPackage;

    // define permission to request
    String[] reqPermission = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
    private int requestCode = 2;

    /**
     * Create the mobile map package file location and name structure
     */
    private static String createMobileMapPackageFilePath(){
        return extStorDir.getAbsolutePath() + File.separator + extSDCardDirName + File.separator + filename + FILE_EXTENSION;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // get sdcard resource name
        extStorDir = Environment.getExternalStorageDirectory();
        // get the directory
        extSDCardDirName = this.getResources().getString(R.string.config_data_sdcard_offline_dir);
        // get mobile map package filename
        filename = this.getResources().getString(R.string.config_mmpk_name);
        // create the full path to the mobile map package file
        mmpkFilePath = createMobileMapPackageFilePath();

        // retrieve the MapView from layout
        mMapView = (MapView) findViewById(R.id.mapView);

        // For API level 23+ request permission at runtime
        if(ContextCompat.checkSelfPermission(MainActivity.this, reqPermission[0]) == PackageManager.PERMISSION_GRANTED){
            loadMobileMapPackage(mmpkFilePath);
        }else{
            // request permission
            ActivityCompat.requestPermissions(MainActivity.this, reqPermission, requestCode);
        }

    }

    /**
     * Handle the permissions request response
     *
     */
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
            loadMobileMapPackage(mmpkFilePath);
        }else{
            // report to user that permission was denied
            Toast.makeText(MainActivity.this, getResources().getString(R.string.location_permission_denied),
                    Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * Load a mobile map package into a MapView
     *
     * @param mmpkFile Full path to mmpk file
     */
    private void loadMobileMapPackage(String mmpkFile){
        //[DocRef: Name=Open Mobile Map Package-android, Category=Work with maps, Topic=Create an offline map]
        // create the mobile map package
        mapPackage = new MobileMapPackage(mmpkFile);
        // load the mobile map package asynchronously
        mapPackage.loadAsync();

        // add done listener which will invoke when mobile map package has loaded
        mapPackage.addDoneLoadingListener(new Runnable() {
            @Override
            public void run() {
                // check load status and that the mobile map package has maps
                if(mapPackage.getLoadStatus() == LoadStatus.LOADED && mapPackage.getMaps().size() > 0){
                    // add the map from the mobile map package to the MapView
                    mMapView.setMap(mapPackage.getMaps().get(0));
                }else{
                    // Log an issue if the mobile map package fails to load
                    Log.e(TAG, mapPackage.getLoadError().getMessage());
                }
            }
        });
        //[DocRef: END]
    }

    @Override
    protected void onPause(){
        super.onPause();
        mMapView.pause();
    }

    @Override
    protected void onResume(){
        super.onResume();
        mMapView.resume();
    }
}