Take a screenshot of the map.
      
   
    
How to use the sample
Pan and zoom to find an interesting location, then tap the camera icon to take a screenshot. The screenshot will be displayed. Note that there may be a small delay if the map is still rendering when you push the button.
How it works
- Wait for the map view to finish rendering the map.
- Call mapView.exportImageAsync()and set it to aListenableFuture<Bitmap>.
- On done, call get()on theListenableFuture<Bitmap>and save it to the device.
Relevant API
- MapView
- MapView.exportImageAsync
Tags
capture, export, image, print, screen capture, screenshot, share, shot
Sample Code
MainActivity.java
/* 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.takescreenshot;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.media.MediaActionSound;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
import com.esri.arcgisruntime.concurrent.ListenableFuture;
import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.BasemapStyle;
import com.esri.arcgisruntime.mapping.view.MapView;
public class MainActivity extends AppCompatActivity {
  private static final String TAG = MainActivity.class.getSimpleName();
  private final int requestCode = 2;
  private final String[] permission = { Manifest.permission.WRITE_EXTERNAL_STORAGE };
  private MapView mMapView;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // authentication with an API key or named user is required to access basemaps and other
    // location services
    ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY);
    // inflate MapView from layout
    mMapView = findViewById(R.id.mapView);
    // create a map with the Basemap Style Imagery with Labels
    ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_IMAGERY);
    // set the map to be displayed in this view
    mMapView.setMap(map);
  }
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
  }
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    // handle menu item selection
    int itemId = item.getItemId();
    if (itemId == R.id.CaptureMap) {
      // Check permissions to see if failure may be due to lack of permissions.
      boolean permissionCheck = ContextCompat.checkSelfPermission(this, permission[0]) ==
          PackageManager.PERMISSION_GRANTED;
      if (!permissionCheck) {
        // If permissions are not already granted, request permission from the user.
        ActivityCompat.requestPermissions(this, permission, requestCode);
      } else {
        captureScreenshotAsync();
      }
    }
    return true;
  }
  /**
   * capture the map as an image
   */
  private void captureScreenshotAsync() {
    // export the image from the mMapView
    final ListenableFuture<Bitmap> export = mMapView.exportImageAsync();
    export.addDoneListener(() -> {
      try {
        Bitmap currentMapImage = export.get();
        // play the camera shutter sound
        MediaActionSound sound = new MediaActionSound();
        sound.play(MediaActionSound.SHUTTER_CLICK);
        Log.d(TAG, "Captured the image!!");
        // save the exported bitmap to an image file
        SaveImageTask saveImageTask = new SaveImageTask();
        saveImageTask.execute(currentMapImage);
      } catch (Exception e) {
        Toast
            .makeText(getApplicationContext(), getResources().getString(R.string.map_export_failure) + e.getMessage(),
                Toast.LENGTH_SHORT).show();
        Log.e(TAG, getResources().getString(R.string.map_export_failure) + e.getMessage());
      }
    });
  }
  /**
   * save the bitmap image to file and open it
   *
   * @param bitmap
   * @throws IOException
   */
  private File saveToFile(Bitmap bitmap) throws IOException {
    // create a directory ArcGIS to save the file
    File root;
    File file = null;
    String fileName = "map-export-image" + System.currentTimeMillis() + ".png";
    root = getExternalFilesDir(null);
    File fileDir = new File(root.getAbsolutePath() + "/ArcGIS Export/");
    boolean isDirectoryCreated = fileDir.exists();
    if (!isDirectoryCreated) {
      isDirectoryCreated = fileDir.mkdirs();
    }
    if (isDirectoryCreated) {
      file = new File(fileDir, fileName);
      // write the bitmap to PNG file
      FileOutputStream fos = new FileOutputStream(file);
      bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
      // close the stream
      fos.flush();
      fos.close();
    }
    return file;
  }
  @Override
  public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    // If request is cancelled, the result arrays are empty.
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
      // Location permission was granted. This would have been triggered in response to failing to start the
      // LocationDisplay, so try starting this again.
      captureScreenshotAsync();
    } else {
      // If permission was denied, show toast to inform user what was chosen. If LocationDisplay is started again,
      // request permission UX will be shown again, option should be shown to allow never showing the UX again.
      // Alternative would be to disable functionality so request is not shown again.
      Toast.makeText(this, getString(R.string.storage_permission_denied), Toast.LENGTH_SHORT).show();
    }
  }
  @Override
  protected void onPause() {
    super.onPause();
    mMapView.pause();
  }
  @Override
  protected void onResume() {
    super.onResume();
    mMapView.resume();
  }
  @Override
  protected void onDestroy() {
    super.onDestroy();
    mMapView.dispose();
  }
  /**
   * AsyncTask class to save the bitmap as an image
   */
  private class SaveImageTask extends AsyncTask<Bitmap, Void, File> {
    @Override
    protected void onPreExecute() {
      // display a toast message to inform saving the map as an image
      Toast.makeText(getApplicationContext(), getResources().getString(R.string.map_export_message), Toast.LENGTH_SHORT)
          .show();
    }
    /**
     * save the file using a worker thread
     */
    @Override
    protected File doInBackground(Bitmap... mapBitmap) {
      try {
        return saveToFile(mapBitmap[0]);
      } catch (Exception e) {
        Log.e(TAG, getResources().getString(R.string.map_export_failure) + e.getMessage());
      }
      return null;
    }
    /**
     * Perform the work on UI thread to open the exported map image
     */
    @Override
    protected void onPostExecute(File file) {
      // Open the file to view
      Intent i = new Intent();
      i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
      i.setAction(Intent.ACTION_VIEW);
      i.setDataAndType(
          FileProvider.getUriForFile(MainActivity.this, getApplicationContext().getPackageName() + ".provider", file),
          "image/png");
      startActivity(i);
    }
  }
  public static class ScreenshotFileProvider extends FileProvider {}
}