Issue with loading .mmpk file from Internal Storage for Offline Use

1363
1
Jump to solution
04-11-2018 07:35 PM
JoelSmith-Lowe
New Contributor II

Hi All,

I am currently developing an Android application that will use esri ArcGIS Android SDK for its Map Activity.

Currently I have been able to get it working using online servers which is great but I am wanting that Activity to load a local .mmpk file to use instead of using online services to get map tiles.

I have stored the file devlabs-package.mmpk on the root folder of Internal Storage. (Folder contains folders like Android, DCIM, Download, Pictures, etc is stored.

I have been unsuccessful after trying to follow the following guide which from what I can tell is simply reading the map data from an SD card instead of the phones internal storage. Display a map while offline | ArcGIS for Developers 

I can confirm that when I add the else statement below it will load but will load using online servers instead of the local .mmpk file but for testing purposes I have removed the statement as I do not want to use online servers at all at this stage of development.

private void setupMobileMap() {
    if (mMapView != null) {
        File mmpkFile = new File(Environment.getDataDirectory(),"devlabs-package.mmpk");
        final MobileMapPackage mapPackage = new MobileMapPackage(mmpkFile.getAbsolutePath());
        mapPackage.addDoneLoadingListener(new Runnable() {
            @Override
            public void run() {
                // Verify the file loaded and there is at least one map
                if (mapPackage.getLoadStatus() == LoadStatus.LOADED && mapPackage.getMaps().size() > 0) {
                    mMapView.setMap(mapPackage.getMaps().get(0));
                } else {
                    // inflate MapView from layout
                    mMapView = (MapView) findViewById(R.id.mapView);
                    // create a map with the BasemapType topographic
                    ArcGISMap map = new ArcGISMap(Basemap.Type.TOPOGRAPHIC, 34.056295, -117.195800, 16);
                    // set the map to be displayed in this view
                    mMapView.setMap(map);
                    // Error if the mobile map package fails to load or there are no maps included in the package
                    //setupMap();
                }
            }
        });
        mapPackage.loadAsync();
    }

Using the code below without the else statement, it loads the API but no tiles are loaded because I believe I am not telling android to look at Internal Storage instead of SD Card or External Storage that is included in the sample code that is in the tutorial linked above.

CURRENT CODE: (Everything except else statement for test purposes)

Activity Name: MapsActivity

import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;

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

import java.io.File;

public class MapsActivity extends AppCompatActivity {

    private MapView mMapView;

    private void setupMobileMap() {
        if (mMapView != null) {
            File mmpkFile = new File(Environment.getExternalStorageDirectory(), "devlabs-package.mmpk");
            final MobileMapPackage mapPackage = new MobileMapPackage(mmpkFile.getAbsolutePath());
            mapPackage.addDoneLoadingListener(new Runnable() {
                @Override
                public void run() {
                    // Verify the file loaded and there is at least one map
                    if (mapPackage.getLoadStatus() == LoadStatus.LOADED && mapPackage.getMaps().size() > 0) {
                        mMapView.setMap(mapPackage.getMaps().get(0));
                    }
                }
            });
            mapPackage.loadAsync();
        }


    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);
        // inflate MapView from layout
        mMapView = (MapView) findViewById(R.id.mapView);
        setupMobileMap();
        // create a map with the BasemapType topographic
       // ArcGISMap map = new ArcGISMap(Basemap.Type.TOPOGRAPHIC, 34.056295, -117.195800, 16);
        // set the map to be displayed in this view
       //mMapView.setupMap(map);
    }


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

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

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMapView.dispose();
    }
}

Also below is permissions I have included in the AndroidManifest.xml which I believe to be all that is required for offline map read/write access but I could be wrong.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>

Any assistance or suggestions would be greatly appreciated, in the meantime I will try load the sample app and try using it instead of my own application to see if I can find out anything more that I might of missed.

Sample App: https://developers.arcgis.com/labs/android/create-a-basic-android-project.zip 

Kind Regards,

Joel.

0 Kudos
1 Solution

Accepted Solutions
JoelSmith-Lowe
New Contributor II

I have resolved my issue !

I had the code right, it was Android Permissions that was causing the issue.

Could someone from ArcGIS please add this to the tutorial posted above as this will really help early adopters that are developing. The tutorial is great but recent changes to the Android OS has made extra steps required which I have included a resolution below.

Explanation of why issue occurs.

Beginning with Android 6.0 (API level 23) dangerous permissions need to be allowed by the user even if the manifest includes the required permission.

Resolution (without including code to prompt user for required permissions):

Install App > Go to Settings > Search for App Permissions > Select Storage > Flick the switch to allow your app access.

View solution in original post

0 Kudos
1 Reply
JoelSmith-Lowe
New Contributor II

I have resolved my issue !

I had the code right, it was Android Permissions that was causing the issue.

Could someone from ArcGIS please add this to the tutorial posted above as this will really help early adopters that are developing. The tutorial is great but recent changes to the Android OS has made extra steps required which I have included a resolution below.

Explanation of why issue occurs.

Beginning with Android 6.0 (API level 23) dangerous permissions need to be allowed by the user even if the manifest includes the required permission.

Resolution (without including code to prompt user for required permissions):

Install App > Go to Settings > Search for App Permissions > Select Storage > Flick the switch to allow your app access.

0 Kudos