This page uses v9.7.1 of the Mapbox Maps SDK. A newer version of the SDK is available. Learn about the latest version, v10.5.0, in the Maps SDK ...
Youareusinganoutdatedbrowserandwillencountersomeproblemswithourwebsite.Pleaseconsiderupgrading.UpgradeNowLegacyThisfeatureisnolongerinactivedevelopment.MapsSDKforAndroidv9SearchGuidesExamplesAlldocsMapsSDKforAndroidv9ExamplesOfflinemanagerOfflinemanagerAnewerversionoftheMapsSDKisavailableThispageusesv9.7.1oftheMapboxMapsSDK.AnewerversionoftheSDKisavailable.Learnaboutthelatestversion,v10.5.0,intheMapsSDKdocumentation.Yourbrowserdoesn'tsupportHTML5video.Openlinktothevideo.NoteThisexampleisapartoftheMapboxAndroidDemoapp.Youcanfindthevaluesforallreferencedresourcesintheresdirectory.Forexample,seeres/values/activity_strings.xmlforR.string.*referencesusedinthisexample.activity_offline_managerViewonGitHubCopyOfflineManagerActivity.javaViewonGitHubpackagecom.mapbox.mapboxandroiddemo.examples.offline;importandroid.app.AlertDialog;importandroid.content.DialogInterface;importandroid.os.Bundle;importandroidx.annotation.NonNull;importandroidx.appcompat.app.AppCompatActivity;importandroid.view.View;importandroid.widget.Button;importandroid.widget.EditText;importandroid.widget.ProgressBar;importandroid.widget.Toast;importcom.mapbox.mapboxandroiddemo.R;importcom.mapbox.mapboxsdk.Mapbox;importcom.mapbox.mapboxsdk.camera.CameraPosition;importcom.mapbox.mapboxsdk.camera.CameraUpdateFactory;importcom.mapbox.mapboxsdk.geometry.LatLngBounds;importcom.mapbox.mapboxsdk.maps.MapView;importcom.mapbox.mapboxsdk.maps.MapboxMap;importcom.mapbox.mapboxsdk.maps.OnMapReadyCallback;importcom.mapbox.mapboxsdk.maps.Style;importcom.mapbox.mapboxsdk.offline.OfflineManager;importcom.mapbox.mapboxsdk.offline.OfflineRegion;importcom.mapbox.mapboxsdk.offline.OfflineRegionError;importcom.mapbox.mapboxsdk.offline.OfflineRegionStatus;importcom.mapbox.mapboxsdk.offline.OfflineTilePyramidRegionDefinition;importorg.json.JSONObject;importjava.util.ArrayList;importtimber.log.Timber;/***Download,view,navigateto,anddeleteanofflineregion.*/publicclassOfflineManagerActivityextendsAppCompatActivity{privatestaticfinalStringTAG="OffManActivity";//JSONencoding/decodingpublicstaticfinalStringJSON_CHARSET="UTF-8";publicstaticfinalStringJSON_FIELD_REGION_NAME="FIELD_REGION_NAME";//UIelementsprivateMapViewmapView;privateMapboxMapmap;privateProgressBarprogressBar;privateButtondownloadButton;privateButtonlistButton;privatebooleanisEndNotified;privateintregionSelected;//OfflineobjectsprivateOfflineManagerofflineManager;privateOfflineRegionofflineRegion;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);//Mapboxaccesstokenisconfiguredhere.Thisneedstobecalledeitherinyourapplication//objectorinthesameactivitywhichcontainsthemapview.Mapbox.getInstance(this,getString(R.string.access_token));//ThiscontainstheMapViewinXMLandneedstobecalledaftertheaccesstokenisconfigured.setContentView(R.layout.activity_offline_manager);//SetuptheMapViewmapView=findViewById(R.id.mapView);mapView.onCreate(savedInstanceState);mapView.getMapAsync(newOnMapReadyCallback(){@OverridepublicvoidonMapReady(@NonNullMapboxMapmapboxMap){map=mapboxMap;mapboxMap.setStyle(Style.MAPBOX_STREETS,newStyle.OnStyleLoaded(){@OverridepublicvoidonStyleLoaded(@NonNullStylestyle){//AssignprogressBarforlateruseprogressBar=findViewById(R.id.progress_bar);//SetuptheofflineManagerofflineManager=OfflineManager.getInstance(OfflineManagerActivity.this);//Bottomnavigationbarbuttonclicksarehandledhere.//DownloadofflinebuttondownloadButton=findViewById(R.id.download_button);downloadButton.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewview){downloadRegionDialog();}});//ListofflineregionslistButton=findViewById(R.id.list_button);listButton.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewview){downloadedRegionList();}});}});}});}//OverrideActivitylifecyclemethods@OverridepublicvoidonResume(){super.onResume();mapView.onResume();}@OverrideprotectedvoidonStart(){super.onStart();mapView.onStart();}@OverrideprotectedvoidonStop(){super.onStop();mapView.onStop();}@OverridepublicvoidonPause(){super.onPause();mapView.onPause();}@OverrideprotectedvoidonSaveInstanceState(BundleoutState){super.onSaveInstanceState(outState);mapView.onSaveInstanceState(outState);}@OverrideprotectedvoidonDestroy(){super.onDestroy();mapView.onDestroy();}@OverridepublicvoidonLowMemory(){super.onLowMemory();mapView.onLowMemory();}privatevoiddownloadRegionDialog(){//Setupdownloadinteraction.Displayadialog//whentheuserclicksdownloadbuttonandrequire//auser-providedregionnameAlertDialog.Builderbuilder=newAlertDialog.Builder(OfflineManagerActivity.this);finalEditTextregionNameEdit=newEditText(OfflineManagerActivity.this);regionNameEdit.setHint(getString(R.string.set_region_name_hint));//Buildthedialogboxbuilder.setTitle(getString(R.string.dialog_title)).setView(regionNameEdit).setMessage(getString(R.string.dialog_message)).setPositiveButton(getString(R.string.dialog_positive_button),newDialogInterface.OnClickListener(){@OverridepublicvoidonClick(DialogInterfacedialog,intwhich){StringregionName=regionNameEdit.getText().toString();//Requirearegionnametobeginthedownload.//Iftheuser-providedstringisempty,display//atoastmessageanddonotbegindownload.if(regionName.length()==0){Toast.makeText(OfflineManagerActivity.this,getString(R.string.dialog_toast),Toast.LENGTH_SHORT).show();}else{//BegindownloadprocessdownloadRegion(regionName);}}}).setNegativeButton(getString(R.string.dialog_negative_button),newDialogInterface.OnClickListener(){@OverridepublicvoidonClick(DialogInterfacedialog,intwhich){dialog.cancel();}});//Displaythedialogbuilder.show();}privatevoiddownloadRegion(finalStringregionName){//Defineofflineregionparameters,includingbounds,//min/maxzoom,andmetadata//StarttheprogressBarstartProgress();//Createofflinedefinitionusingthecurrent//styleandboundariesofvisiblemapareamap.getStyle(newStyle.OnStyleLoaded(){@OverridepublicvoidonStyleLoaded(@NonNullStylestyle){StringstyleUrl=style.getUri();LatLngBoundsbounds=map.getProjection().getVisibleRegion().latLngBounds;doubleminZoom=map.getCameraPosition().zoom;doublemaxZoom=map.getMaxZoomLevel();floatpixelRatio=OfflineManagerActivity.this.getResources().getDisplayMetrics().density;OfflineTilePyramidRegionDefinitiondefinition=newOfflineTilePyramidRegionDefinition(styleUrl,bounds,minZoom,maxZoom,pixelRatio);//BuildaJSONObjectusingtheuser-definedofflineregiontitle,//convertitintostring,anduseittocreateametadatavariable.//ThemetadatavariablewilllaterbepassedtocreateOfflineRegion()byte[]metadata;try{JSONObjectjsonObject=newJSONObject();jsonObject.put(JSON_FIELD_REGION_NAME,regionName);Stringjson=jsonObject.toString();metadata=json.getBytes(JSON_CHARSET);}catch(Exceptionexception){Timber.e("Failedtoencodemetadata:%s",exception.getMessage());metadata=null;}//CreatetheofflineregionandlaunchthedownloadofflineManager.createOfflineRegion(definition,metadata,newOfflineManager.CreateOfflineRegionCallback(){@OverridepublicvoidonCreate(OfflineRegionofflineRegion){Timber.d("Offlineregioncreated:%s",regionName);OfflineManagerActivity.this.offlineRegion=offlineRegion;launchDownload();}@OverridepublicvoidonError(Stringerror){Timber.e("Error:%s",error);}});}});}privatevoidlaunchDownload(){//Setupanobservertohandledownloadprogressand//notifytheuserwhentheregionisfinisheddownloadingofflineRegion.setObserver(newOfflineRegion.OfflineRegionObserver(){@OverridepublicvoidonStatusChanged(OfflineRegionStatusstatus){//Computeapercentagedoublepercentage=status.getRequiredResourceCount()>=0?(100.0*status.getCompletedResourceCount()/status.getRequiredResourceCount()):0.0;if(status.isComplete()){//DownloadcompleteendProgress(getString(R.string.end_progress_success));return;}elseif(status.isRequiredResourceCountPrecise()){//SwitchtodeterminatestatesetPercentage((int)Math.round(percentage));}//LogwhatisbeingcurrentlydownloadedTimber.d("%s/%sresources;%sbytesdownloaded.",String.valueOf(status.getCompletedResourceCount()),String.valueOf(status.getRequiredResourceCount()),String.valueOf(status.getCompletedResourceSize()));}@OverridepublicvoidonError(OfflineRegionErrorerror){Timber.e("onErrorreason:%s",error.getReason());Timber.e("onErrormessage:%s",error.getMessage());}@OverridepublicvoidmapboxTileCountLimitExceeded(longlimit){Timber.e("Mapboxtilecountlimitexceeded:%s",limit);}});//ChangetheregionstateofflineRegion.setDownloadState(OfflineRegion.STATE_ACTIVE);}privatevoiddownloadedRegionList(){//Buildaregionlistwhentheuserclicksthelistbutton//Resettheregionselectedintto0regionSelected=0;//QuerytheDBasynchronouslyofflineManager.listOfflineRegions(newOfflineManager.ListOfflineRegionsCallback(){@OverridepublicvoidonList(finalOfflineRegion[]offlineRegions){//Checkresult.Ifnoregionshavebeen//downloadedyet,notifyuserandreturnif(offlineRegions==null||offlineRegions.length==0){Toast.makeText(getApplicationContext(),getString(R.string.toast_no_regions_yet),Toast.LENGTH_SHORT).show();return;}//AddalloftheregionnamestoalistArrayListofflineRegionsNames=newArrayList<>();for(OfflineRegionofflineRegion:offlineRegions){offlineRegionsNames.add(getRegionName(offlineRegion));}finalCharSequence[]items=offlineRegionsNames.toArray(newCharSequence[offlineRegionsNames.size()]);//BuildadialogcontainingthelistofregionsAlertDialogdialog=newAlertDialog.Builder(OfflineManagerActivity.this).setTitle(getString(R.string.navigate_title)).setSingleChoiceItems(items,0,newDialogInterface.OnClickListener(){@OverridepublicvoidonClick(DialogInterfacedialog,intwhich){//TrackwhichregiontheuserselectsregionSelected=which;}}).setPositiveButton(getString(R.string.navigate_positive_button),newDialogInterface.OnClickListener(){@OverridepublicvoidonClick(DialogInterfacedialog,intid){Toast.makeText(OfflineManagerActivity.this,items[regionSelected],Toast.LENGTH_LONG).show();//GettheregionboundsandzoomLatLngBoundsbounds=(offlineRegions[regionSelected].getDefinition()).getBounds();doubleregionZoom=(offlineRegions[regionSelected].getDefinition()).getMinZoom();//CreatenewcamerapositionCameraPositioncameraPosition=newCameraPosition.Builder().target(bounds.getCenter()).zoom(regionZoom).build();//Movecameratonewpositionmap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));}}).setNeutralButton(getString(R.string.navigate_neutral_button_title),newDialogInterface.OnClickListener(){@OverridepublicvoidonClick(DialogInterfacedialog,intid){//MakeprogressBarindeterminateand//setittovisibletosignalthat//thedeletionprocesshasbegunprogressBar.setIndeterminate(true);progressBar.setVisibility(View.VISIBLE);//BeginthedeletionprocessofflineRegions[regionSelected].delete(newOfflineRegion.OfflineRegionDeleteCallback(){@OverridepublicvoidonDelete(){//Oncetheregionisdeleted,removethe//progressBaranddisplayatoastprogressBar.setVisibility(View.INVISIBLE);progressBar.setIndeterminate(false);Toast.makeText(getApplicationContext(),getString(R.string.toast_region_deleted),Toast.LENGTH_LONG).show();}@OverridepublicvoidonError(Stringerror){progressBar.setVisibility(View.INVISIBLE);progressBar.setIndeterminate(false);Timber.e("Error:%s",error);}});}}).setNegativeButton(getString(R.string.navigate_negative_button_title),newDialogInterface.OnClickListener(){@OverridepublicvoidonClick(DialogInterfacedialog,intid){//Whentheusercancels,don'tdoanything.//Thedialogwillautomaticallyclose}}).create();dialog.show();}@OverridepublicvoidonError(Stringerror){Timber.e("Error:%s",error);}});}privateStringgetRegionName(OfflineRegionofflineRegion){//GettheregionnamefromtheofflineregionmetadataStringregionName;try{byte[]metadata=offlineRegion.getMetadata();Stringjson=newString(metadata,JSON_CHARSET);JSONObjectjsonObject=newJSONObject(json);regionName=jsonObject.getString(JSON_FIELD_REGION_NAME);}catch(Exceptionexception){Timber.e("Failedtodecodemetadata:%s",exception.getMessage());regionName=String.format(getString(R.string.region_name),offlineRegion.getID());}returnregionName;}//ProgressbarmethodsprivatevoidstartProgress(){//DisablebuttonsdownloadButton.setEnabled(false);listButton.setEnabled(false);//StartandshowtheprogressbarisEndNotified=false;progressBar.setIndeterminate(true);progressBar.setVisibility(View.VISIBLE);}privatevoidsetPercentage(finalintpercentage){progressBar.setIndeterminate(false);progressBar.setProgress(percentage);}privatevoidendProgress(finalStringmessage){//Don'tnotifymorethanonceif(isEndNotified){return;}//EnablebuttonsdownloadButton.setEnabled(true);listButton.setEnabled(true);//StopandhidetheprogressbarisEndNotified=true;progressBar.setIndeterminate(false);progressBar.setVisibility(View.GONE);//ShowatoastToast.makeText(OfflineManagerActivity.this,message,Toast.LENGTH_LONG).show();}}Copy