コード例 #1
0
  public EntityInfo loadNode(Node n) {
    long nodeId = n.getId(); // >> 1;
    try {
      String res =
          sendRequest(
              SITE_API + "api/0.6/node/" + nodeId,
              "GET",
              null,
              ctx.getString(R.string.loading_poi_obj) + nodeId,
              false); //$NON-NLS-1$ //$NON-NLS-2$
      if (res != null) {
        OsmBaseStorage st = new OsmBaseStorage();
        st.parseOSM(
            new ByteArrayInputStream(res.getBytes("UTF-8")), null, null, true); // $NON-NLS-1$
        EntityId id = new Entity.EntityId(EntityType.NODE, nodeId);
        //				Node entity = (Node) st.getRegisteredEntities().get(id);
        entityInfo = st.getRegisteredEntityInfo().get(id);
        return entityInfo;
      }

    } catch (IOException e) {
      log.error("Loading node failed " + nodeId, e); // $NON-NLS-1$
      AccessibleToast.makeText(
              ctx, ctx.getResources().getString(R.string.error_io_error), Toast.LENGTH_LONG)
          .show();
    } catch (SAXException e) {
      log.error("Loading node failed " + nodeId, e); // $NON-NLS-1$
      AccessibleToast.makeText(
              ctx, ctx.getResources().getString(R.string.error_io_error), Toast.LENGTH_LONG)
          .show();
    }
    return null;
  }
コード例 #2
0
 public void checkExternalStorage() {
   String state = Environment.getExternalStorageState();
   if (Environment.MEDIA_MOUNTED.equals(state)) {
     // ok
   } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
     AccessibleToast.makeText(this, R.string.sd_mounted_ro, Toast.LENGTH_LONG).show();
   } else {
     AccessibleToast.makeText(this, R.string.sd_unmounted, Toast.LENGTH_LONG).show();
   }
 }
コード例 #3
0
 private void handleResult(
     final GPXUtilities.GPXFile result, final String name, final boolean save) {
   if (result != null) {
     if (result.warning != null) {
       AccessibleToast.makeText(mapActivity, result.warning, Toast.LENGTH_LONG).show();
     } else {
       if (save) {
         new SaveAsyncTask(result, name).execute();
       } else {
         showGpxOnMap(result);
       }
     }
   } else {
     AccessibleToast.makeText(mapActivity, R.string.error_reading_gpx, Toast.LENGTH_LONG).show();
   }
 }
コード例 #4
0
ファイル: SettingsActivity.java プロジェクト: aitolos/Osmand
  private void warnAboutChangingStorage(final String newValue) {
    final String newDir = newValue != null ? newValue.trim() : newValue;
    File path = new File(newDir);
    path.mkdirs();
    if (!path.canRead() || !path.exists()) {
      AccessibleToast.makeText(this, R.string.specified_dir_doesnt_exist, Toast.LENGTH_LONG).show();
      return;
    }

    Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(getString(R.string.application_dir_change_warning));
    builder.setPositiveButton(
        R.string.default_buttons_yes,
        new OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            // edit the preference
            osmandSettings.setExternalStorageDirectory(newDir);
            getMyApplication().getResourceManager().resetStoreDirectory();
            reloadIndexes();
            updateApplicationDirTextAndSummary();
          }
        });
    builder.setNegativeButton(R.string.default_buttons_cancel, null);
    builder.show();
  }
コード例 #5
0
  @Override
  public String getUrlToLoad(int x, int y, int zoom) {
    if (zoom > maxZoom) return null;
    SQLiteConnection db = getDatabase();
    if (db == null || db.isReadOnly() || urlTemplate == null) {
      return null;
    }

    if (TileSourceManager.RULE_BEANSHELL.equalsIgnoreCase(rule)) {
      try {
        if (bshInterpreter == null) {
          bshInterpreter = new Interpreter();
          bshInterpreter.eval(urlTemplate);
        }
        return (String) bshInterpreter.eval("getTileUrl(" + zoom + "," + x + "," + y + ");");
      } catch (bsh.EvalError e) {
        LOG.debug("getUrlToLoad Error" + e.getMessage());
        AccessibleToast.makeText(ctx, e.getMessage(), Toast.LENGTH_LONG).show();
        LOG.error(e.getMessage(), e);
        return null;
      }
    } else {
      return MessageFormat.format(
          urlTemplate, zoom + "", x + "", y + ""); // $NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
    }
  }
コード例 #6
0
 private boolean checkRunning() {
   if (getCurrentRunningTask() != null) {
     AccessibleToast.makeText(app, R.string.wait_current_task_finished, Toast.LENGTH_SHORT).show();
     return true;
   }
   return false;
 }
コード例 #7
0
 private void selectAll() {
   final DownloadIndexAdapter listAdapter = (DownloadIndexAdapter) getExpandableListAdapter();
   int selected = 0;
   for (int j = 0; j < listAdapter.getGroupCount(); j++) {
     for (int i = 0; i < listAdapter.getChildrenCount(j); i++) {
       IndexItem es = listAdapter.getChild(j, i);
       if (!getEntriesToDownload().containsKey(es)) {
         selected++;
         getEntriesToDownload()
             .put(
                 es,
                 es.createDownloadEntry(
                     getClientContext(), type, new ArrayList<DownloadEntry>(1)));
       }
     }
   }
   AccessibleToast.makeText(
           this,
           MessageFormat.format(getString(R.string.items_were_selected), selected),
           Toast.LENGTH_SHORT)
       .show();
   listAdapter.notifyDataSetInvalidated();
   if (selected > 0) {
     updateDownloadButton(true);
   }
 }
コード例 #8
0
 @Override
 protected void onPostExecute(String result) {
   LocalOpenstreetmapActivity.this.setProgressBarIndeterminateVisibility(false);
   if (result != null) {
     AccessibleToast.makeText(
             LocalOpenstreetmapActivity.this,
             getString(R.string.local_osm_changes_backup_failed) + " " + result,
             Toast.LENGTH_LONG)
         .show();
   } else {
     AccessibleToast.makeText(
             LocalOpenstreetmapActivity.this,
             getString(
                 R.string.local_osm_changes_backup_successful, osmchange.getAbsolutePath()),
             Toast.LENGTH_LONG)
         .show();
   }
 }
コード例 #9
0
 public void changeZoom(float newZoom) {
   newZoom = Math.round(newZoom * OsmandMapTileView.ZOOM_DELTA) * OsmandMapTileView.ZOOM_DELTA_1;
   boolean changeLocation = settings.AUTO_ZOOM_MAP.get();
   mapView.getAnimatedDraggingThread().startZooming(newZoom, changeLocation);
   if (app.getInternalAPI().accessibilityEnabled())
     AccessibleToast.makeText(
             this, getString(R.string.zoomIs) + " " + String.valueOf(newZoom), Toast.LENGTH_SHORT)
         .show(); //$NON-NLS-1$
   showAndHideMapPosition();
 }
コード例 #10
0
  @Override
  public Node loadNode(Amenity n) {
    if (n.getId() % 2 == 1) {
      // that's way id
      return null;
    }
    long nodeId = n.getId() >> 1;
    try {
      String res =
          sendRequest(
              SITE_API + "api/0.6/node/" + nodeId,
              "GET",
              null,
              ctx.getString(R.string.loading_poi_obj) + nodeId,
              false); //$NON-NLS-1$ //$NON-NLS-2$
      if (res != null) {
        OsmBaseStorage st = new OsmBaseStorage();
        st.parseOSM(
            new ByteArrayInputStream(res.getBytes("UTF-8")), null, null, true); // $NON-NLS-1$
        EntityId id = new Entity.EntityId(EntityType.NODE, nodeId);
        Node entity = (Node) st.getRegisteredEntities().get(id);
        entityInfo = st.getRegisteredEntityInfo().get(id);
        // check whether this is node (because id of node could be the same as relation)
        if (entity != null && MapUtils.getDistance(entity.getLatLon(), n.getLocation()) < 50) {
          return entity;
        }
        return null;
      }

    } catch (IOException e) {
      log.error("Loading node failed " + nodeId, e); // $NON-NLS-1$
      AccessibleToast.makeText(
              ctx, ctx.getResources().getString(R.string.error_io_error), Toast.LENGTH_LONG)
          .show();
    } catch (SAXException e) {
      log.error("Loading node failed " + nodeId, e); // $NON-NLS-1$
      AccessibleToast.makeText(
              ctx, ctx.getResources().getString(R.string.error_io_error), Toast.LENGTH_LONG)
          .show();
    }
    return null;
  }
コード例 #11
0
    @Override
    protected void onPostExecute(final String warning) {
      final String msg =
          warning == null
              ? MessageFormat.format(
                  application.getString(R.string.gpx_saved_sucessfully), result.path)
              : warning;
      AccessibleToast.makeText(mapActivity, msg, Toast.LENGTH_LONG).show();

      showGpxOnMap(result);
    }
コード例 #12
0
 @Override
 protected void onPostExecute(String result) {
   if (result != null) {
     AccessibleToast.makeText(DownloadIndexActivity.this, result, Toast.LENGTH_LONG).show();
   }
   View mainView = findViewById(R.id.MainLayout);
   if (mainView != null) {
     mainView.setKeepScreenOn(false);
   }
   updateLoadedFiles();
   ((DownloadIndexAdapter) getExpandableListAdapter()).notifyDataSetInvalidated();
 }
コード例 #13
0
 protected void onPostExecute(Node n) {
   if (n == null) {
     AccessibleToast.makeText(
             activity,
             activity.getResources().getString(R.string.poi_error_poi_not_found),
             Toast.LENGTH_LONG)
         .show();
     return;
   }
   DeletePoiDialogFragment.createInstance(n)
       .show(activity.getSupportFragmentManager(), "DeletePoiDialogFragment");
 }
コード例 #14
0
 @Override
 protected void onPostExecute(Integer result) {
   listAdapter.notifyDataSetChanged();
   if (result != null) {
     AccessibleToast.makeText(
             LocalOpenstreetmapActivity.this,
             MessageFormat.format(
                 getString(R.string.local_openstreetmap_were_uploaded), result.intValue()),
             Toast.LENGTH_LONG)
         .show();
   }
   removeDialog(DIALOG_PROGRESS_UPLOAD);
 }
コード例 #15
0
 @Override
 protected void onProgressUpdate(Object... values) {
   for (Object o : values) {
     if (o instanceof DownloadEntry) {
       updateLoadedFiles();
       ((DownloadIndexAdapter) getExpandableListAdapter()).notifyDataSetInvalidated();
       findViewById(R.id.DownloadButton)
           .setVisibility(entriesToDownload.isEmpty() ? View.GONE : View.VISIBLE);
     } else if (o instanceof String) {
       AccessibleToast.makeText(DownloadIndexActivity.this, (String) o, Toast.LENGTH_LONG)
           .show();
     }
   }
   super.onProgressUpdate(values);
 }
コード例 #16
0
 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
   if (item.getItemId() == RELOAD_ID) {
     // re-create the thread
     downloadListIndexThread = new DownloadIndexListThread(this);
     downloadIndexList();
   } else {
     final DownloadIndexAdapter listAdapter = (DownloadIndexAdapter) getExpandableListAdapter();
     if (item.getItemId() == SELECT_ALL_ID) {
       int selected = 0;
       for (int i = 0; i < listAdapter.getChildrenCount(0); i++) {
         IndexItem es = listAdapter.getChild(0, i);
         if (!entriesToDownload.containsKey(es.getFileName())) {
           selected++;
           entriesToDownload.put(
               es.getFileName(), es.createDownloadEntry(DownloadIndexActivity.this));
         }
       }
       AccessibleToast.makeText(
               this,
               MessageFormat.format(getString(R.string.items_were_selected), selected),
               Toast.LENGTH_SHORT)
           .show();
       listAdapter.notifyDataSetInvalidated();
       if (selected > 0) {
         findViewById(R.id.DownloadButton).setVisibility(View.VISIBLE);
       }
     } else if (item.getItemId() == FILTER_EXISTING_REGIONS) {
       final Collection<String> listAlreadyDownloaded = listAlreadyDownloadedWithAlternatives();
       final List<IndexItem> filtered = new ArrayList<IndexItem>();
       for (String file : listAlreadyDownloaded) {
         IndexItem fileItem = listAdapter.getIndexFiles().get(file);
         if (fileItem != null) {
           filtered.add(fileItem);
         }
       }
       listAdapter.setIndexFiles(filtered);
     } else if (item.getItemId() == DESELECT_ALL_ID) {
       entriesToDownload.clear();
       listAdapter.notifyDataSetInvalidated();
       findViewById(R.id.DownloadButton).setVisibility(View.GONE);
     } else {
       return false;
     }
   }
   return true;
 }
コード例 #17
0
  public static void commitNode(
      final OsmPoint.Action action,
      final Node n,
      final EntityInfo info,
      final String comment,
      final boolean closeChangeSet,
      final Runnable successAction,
      final Activity activity,
      final OpenstreetmapUtil openstreetmapUtil) {
    if (info == null && OsmPoint.Action.CREATE != action) {

      AccessibleToast.makeText(
              activity,
              activity.getResources().getString(R.string.poi_error_info_not_loaded),
              Toast.LENGTH_LONG)
          .show();
      return;
    }
    new AsyncTask<Void, Void, Node>() {
      ProgressDialog progress;

      @Override
      protected void onPreExecute() {
        progress =
            ProgressDialog.show(
                activity,
                activity.getString(R.string.uploading),
                activity.getString(R.string.uploading_data));
        super.onPreExecute();
      }

      @Override
      protected Node doInBackground(Void... params) {
        return openstreetmapUtil.commitNodeImpl(action, n, info, comment, closeChangeSet);
      }

      @Override
      protected void onPostExecute(Node result) {
        progress.dismiss();
        if (result != null) {
          successAction.run();
        }
      }
    }.execute();
  }
コード例 #18
0
ファイル: POIMapLayer.java プロジェクト: rogere66/Osmand
 @Override
 public boolean onSingleTap(PointF point) {
   List<Amenity> am = new ArrayList<Amenity>();
   getAmenityFromPoint(point, am);
   if (!am.isEmpty()) {
     StringBuilder res = new StringBuilder();
     for (int i = 0; i < MAXIMUM_SHOW_AMENITIES && i < am.size(); i++) {
       Amenity n = am.get(i);
       if (i > 0) {
         res.append("\n\n");
       }
       buildPoiInformation(res, n);
     }
     AccessibleToast.makeText(view.getContext(), res.toString(), Toast.LENGTH_SHORT).show();
     return true;
   }
   return false;
 }
コード例 #19
0
ファイル: FavoritesLayer.java プロジェクト: rezakhn/Osmand
 @Override
 public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
   List<FavouritePoint> favs = new ArrayList<FavouritePoint>();
   getFavoriteFromPoint(tileBox, point, favs);
   if (!favs.isEmpty()) {
     StringBuilder res = new StringBuilder();
     int i = 0;
     for (FavouritePoint fav : favs) {
       if (i++ > 0) {
         res.append("\n\n");
       }
       res.append(
           view.getContext().getString(R.string.favorite) + " : " + fav.getName()); // $NON-NLS-1$
     }
     AccessibleToast.makeText(view.getContext(), res.toString(), Toast.LENGTH_LONG).show();
     return true;
   }
   return false;
 }
コード例 #20
0
 protected void downloadFilesPreCheckSpace() {
   double sz = 0;
   for (DownloadEntry es : entriesToDownload.values()) {
     sz += es.sizeMB;
   }
   // get availabile space
   File dir = settings.extendOsmandPath("");
   double asz = -1;
   if (dir.canRead()) {
     StatFs fs = new StatFs(dir.getAbsolutePath());
     asz = (((long) fs.getAvailableBlocks()) * fs.getBlockSize()) / (1 << 20);
   }
   if (asz != -1 && asz < sz) {
     AccessibleToast.makeText(
             this, getString(R.string.download_files_not_enough_space, sz, asz), Toast.LENGTH_LONG)
         .show();
   } else {
     Builder builder = new AlertDialog.Builder(this);
     if (asz > 0 && sz / asz > 0.8) {
       builder.setMessage(
           MessageFormat.format(
               getString(R.string.download_files_question_space),
               entriesToDownload.size(),
               sz,
               asz));
     } else {
       builder.setMessage(
           MessageFormat.format(
               getString(R.string.download_files_question), entriesToDownload.size(), sz));
     }
     builder.setPositiveButton(
         R.string.default_buttons_yes,
         new DialogInterface.OnClickListener() {
           @Override
           public void onClick(DialogInterface dialog, int which) {
             showDialog(DIALOG_PROGRESS_FILE);
           }
         });
     builder.setNegativeButton(R.string.default_buttons_no, null);
     builder.show();
   }
 }
コード例 #21
0
 @Override
 public void onListItemClick(ListView parent, View v, int position, long id) {
   final PoiFilter filter = ((AmenityAdapter) getListAdapter()).getItem(position);
   if (filter.getFilterId().equals(PoiFilter.CUSTOM_FILTER_ID)) {
     filter.clearFilter();
     showEditActivity(filter);
     return;
   }
   if (!(filter instanceof NameFinderPoiFilter)) {
     ResourceManager rm = ((OsmandApplication) getApplication()).getResourceManager();
     if (!rm.containsAmenityRepositoryToSearch(filter instanceof SearchByNameFilter)) {
       AccessibleToast.makeText(
           this, R.string.data_to_search_poi_not_available, Toast.LENGTH_LONG);
       return;
     }
   }
   final Intent newIntent = new Intent(SearchPoiFilterActivity.this, SearchPOIActivity.class);
   newIntent.putExtra(SearchPOIActivity.AMENITY_FILTER, filter.getFilterId());
   updateIntentToLaunch(newIntent);
   startActivityForResult(newIntent, 0);
 }
コード例 #22
0
ファイル: OsmBugsLayer.java プロジェクト: Boothy99/Osmand
 @Override
 public boolean onSingleTap(PointF point, RotatedTileBox tileBox) {
   ArrayList<OpenStreetNote> list = new ArrayList<OpenStreetNote>();
   getBugFromPoint(tileBox, point, list);
   if (!list.isEmpty()) {
     StringBuilder res = new StringBuilder();
     int i = 0;
     for (OpenStreetNote o : list) {
       if (i++ > 0) {
         res.append("\n\n");
       }
       res.append(
           activity.getString(R.string.osb_bug_name)
               + " : "
               + o.getCommentDescription()); // $NON-NLS-1$
     }
     AccessibleToast.makeText(activity, res.toString(), Toast.LENGTH_LONG).show();
     return true;
   }
   return false;
 }
コード例 #23
0
 @Override
 protected void onPostExecute(String result) {
   if (result != null && result.length() > 0) {
     AccessibleToast.makeText(ctx, result, Toast.LENGTH_LONG).show();
   }
   currentDownloads.clear();
   if (uiActivity != null) {
     View mainView = uiActivity.findViewById(R.id.MainLayout);
     if (mainView != null) {
       mainView.setKeepScreenOn(false);
     }
     DownloadIndexAdapter adapter =
         ((DownloadIndexAdapter) uiActivity.getExpandableListAdapter());
     if (adapter != null) {
       adapter.setLoadedFiles(indexActivatedFileNames, indexFileNames);
     }
   }
   currentRunningTask.remove(this);
   if (uiActivity != null) {
     uiActivity.updateProgress(false);
   }
 }
コード例 #24
0
 @Override
 protected void onProgressUpdate(Object... values) {
   for (Object o : values) {
     if (o instanceof DownloadEntry) {
       if (uiActivity != null) {
         ((DownloadIndexAdapter) uiActivity.getExpandableListAdapter())
             .notifyDataSetInvalidated();
         uiActivity.updateDownloadButton(false);
       }
     } else if (o instanceof IndexItem) {
       entriesToDownload.remove(o);
       if (uiActivity != null) {
         ((DownloadIndexAdapter) uiActivity.getExpandableListAdapter())
             .notifyDataSetInvalidated();
         uiActivity.updateDownloadButton(false);
       }
     } else if (o instanceof String) {
       AccessibleToast.makeText(ctx, (String) o, Toast.LENGTH_LONG).show();
     }
   }
   super.onProgressUpdate(values);
 }
コード例 #25
0
ファイル: DownloadTilesDialog.java プロジェクト: AmZaf/Osmand
  public void openDialog() {
    BaseMapLayer mainLayer = mapView.getMainLayer();
    if (!(mainLayer instanceof MapTileLayer) || !((MapTileLayer) mainLayer).isVisible()) {
      AccessibleToast.makeText(ctx, R.string.maps_could_not_be_downloaded, Toast.LENGTH_SHORT)
          .show();
    }
    final ITileSource mapSource = ((MapTileLayer) mainLayer).getMap();
    if (mapSource == null || !mapSource.couldBeDownloadedFromInternet()) {
      AccessibleToast.makeText(ctx, R.string.maps_could_not_be_downloaded, Toast.LENGTH_SHORT)
          .show();
      return;
    }
    final RotatedTileBox rb = mapView.getCurrentRotatedTileBox();
    final int max = mapSource.getMaximumZoomSupported();
    // get narrow zoom
    final int zoom = rb.getZoom();

    // calculate pixel rectangle
    AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
    LayoutInflater inflater =
        (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.download_tiles, null);

    ((TextView) view.findViewById(R.id.MinZoom)).setText(zoom + ""); // $NON-NLS-1$
    ((TextView) view.findViewById(R.id.MaxZoom)).setText(max + ""); // $NON-NLS-1$
    final SeekBar seekBar = (SeekBar) view.findViewById(R.id.ZoomToDownload);
    seekBar.setMax(max - zoom);
    seekBar.setProgress((max - zoom) / 2);

    final TextView downloadText = ((TextView) view.findViewById(R.id.DownloadDescription));
    final String template = ctx.getString(R.string.tiles_to_download_estimated_size);

    updateLabel(zoom, rb.getLatLonBounds(), downloadText, template, seekBar.getProgress());
    seekBar.setOnSeekBarChangeListener(
        new SeekBar.OnSeekBarChangeListener() {

          @Override
          public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            updateLabel(zoom, rb.getLatLonBounds(), downloadText, template, progress);
          }

          @Override
          public void onStartTrackingTouch(SeekBar seekBar) {}

          @Override
          public void onStopTrackingTouch(SeekBar seekBar) {}
        });

    builder.setPositiveButton(
        R.string.shared_string_download,
        new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            dialog.dismiss();
            run(zoom, seekBar.getProgress(), rb.getLatLonBounds(), mapSource);
          }
        });
    builder.setNegativeButton(R.string.shared_string_cancel, null);
    builder.setView(view);
    builder.show();
  }
コード例 #26
0
 @Override
 public void showToastMessage(String msg) {
   AccessibleToast.makeText(this, msg, Toast.LENGTH_LONG).show();
 }
コード例 #27
0
 @Override
 public void showToastMessage(int msgId, Object... args) {
   AccessibleToast.makeText(this, getString(msgId, args), Toast.LENGTH_LONG).show();
 }
コード例 #28
0
ファイル: SettingsActivity.java プロジェクト: aitolos/Osmand
  public static void installMapLayers(
      final Activity activity, final ResultMatcher<TileSourceTemplate> result) {
    final OsmandSettings settings = ((OsmandApplication) activity.getApplication()).getSettings();
    final Map<String, String> entriesMap = settings.getTileSourceEntries();
    if (!settings.isInternetConnectionAvailable(true)) {
      AccessibleToast.makeText(activity, R.string.internet_not_available, Toast.LENGTH_LONG).show();
      return;
    }
    final List<TileSourceTemplate> downloaded =
        TileSourceManager.downloadTileSourceTemplates(Version.getVersionAsURLParam(activity));
    if (downloaded == null || downloaded.isEmpty()) {
      AccessibleToast.makeText(activity, R.string.error_io_error, Toast.LENGTH_SHORT).show();
      return;
    }
    Builder builder = new AlertDialog.Builder(activity);
    String[] names = new String[downloaded.size()];
    for (int i = 0; i < names.length; i++) {
      names[i] = downloaded.get(i).getName();
    }
    final boolean[] selected = new boolean[downloaded.size()];
    builder.setMultiChoiceItems(
        names,
        selected,
        new DialogInterface.OnMultiChoiceClickListener() {

          @Override
          public void onClick(DialogInterface dialog, int which, boolean isChecked) {
            selected[which] = isChecked;
            if (entriesMap.containsKey(downloaded.get(which).getName()) && isChecked) {
              AccessibleToast.makeText(
                      activity, R.string.tile_source_already_installed, Toast.LENGTH_SHORT)
                  .show();
            }
          }
        });
    builder.setNegativeButton(R.string.default_buttons_cancel, null);
    builder.setTitle(R.string.select_tile_source_to_install);
    builder.setPositiveButton(
        R.string.default_buttons_apply,
        new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            List<TileSourceTemplate> toInstall = new ArrayList<TileSourceTemplate>();
            for (int i = 0; i < selected.length; i++) {
              if (selected[i]) {
                toInstall.add(downloaded.get(i));
              }
            }
            for (TileSourceTemplate ts : toInstall) {
              if (settings.installTileSource(ts)) {
                if (result != null) {
                  result.publish(ts);
                }
              }
            }
            // at the end publish null to show end of process
            if (!toInstall.isEmpty() && result != null) {
              result.publish(null);
            }
          }
        });

    builder.show();
  }