Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8457141
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 10, 20262026-06-10T12:44:01+00:00 2026-06-10T12:44:01+00:00

I’m trying to load map tiles from an internal SSL server. The SSL certificate’s

  • 0

I’m trying to load map tiles from an internal SSL server. The SSL certificate’s root of trust is not recognized by the Android system.

W/o*.o*.t*.m*.MapTileDow*(2837): IOException downloading MapTile: /8/37/4 :
javax.net.ssl.SSLPeerUnverifiedException: No peer certificate

I’m already familiar with the problem and have solved it in the rest of the application based on this excellent SO answer. Essentially, I extended my own SSLSocketFactory and X509TrustManager which load my SSL certificate’s root of trust from a .bks file bundled with the app. To create a secure connection, I call ((HttpsURLConnection) connection).setSSLSocketFactory(mySSLSocketFactory) and the certificate is verified using my classes with my root of trust.

My question is how do I do the same thing for osmdroid? I’m creating my own XYTileSource where I set the URL, file extension, size, etc. of my map tiles. I see that osmdroid creates its connections to download map tile images in MapTileDownloader. I can write my own replacement class that will address the SSL issue in the same manner, but how do I tell osmdroid to use my custom downloader instead of the default?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-10T12:44:02+00:00Added an answer on June 10, 2026 at 12:44 pm

    It turns out this is possible without changing the source of osmdroid, due to the public MapView(Context context, int tileSizePixels, ResourceProxy resourceProxy, MapTileProviderBase aTileProvider) constrtuctor.

    Assuming you already have a custom class like MySSLSocketFactory (which extends javax.net.ssl.SSLSocketFactory), the basic process looks like this:

    1. Create a drop-in replacement class for MapTileDownloader to perform the download in a way that makes use of MySSLSocketFactory. Let’s call this MyTileDownloader.

    2. Create a drop-in replacement class for MapTileProviderBasic that instantiates your custom MyTileDownloader. Let’s call this MyTileProvider.

    3. Instantiate your tile source as a new XYTileSource (no need to write a custom class).

    4. Instantiate MyTileProvider with your tile source instance.

    5. Instantiate MapVew with your tile provider instance.


    MySSLSocketFactory is left as an exercise for the reader. See this post.


    MyTileDownloader looks something like this:

    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.UnknownHostException;
    
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLSocketFactory;
    
    import org.osmdroid.tileprovider.MapTile;
    import org.osmdroid.tileprovider.MapTileRequestState;
    import org.osmdroid.tileprovider.modules.IFilesystemCache;
    import org.osmdroid.tileprovider.modules.INetworkAvailablityCheck;
    import org.osmdroid.tileprovider.modules.MapTileDownloader;
    import org.osmdroid.tileprovider.modules.MapTileModuleProviderBase;
    import org.osmdroid.tileprovider.tilesource.BitmapTileSourceBase.LowMemoryException;
    import org.osmdroid.tileprovider.tilesource.ITileSource;
    import org.osmdroid.tileprovider.tilesource.OnlineTileSourceBase;
    import org.osmdroid.tileprovider.util.StreamUtils;
    
    import android.graphics.drawable.Drawable;
    import android.text.TextUtils;
    import android.util.Log;
    
    /**
     * A drop-in replacement for {@link MapTileDownloader}. This loads tiles from an
     * HTTP or HTTPS server, making use of a custom {@link SSLSocketFactory} for SSL
     * peer verification.
     */
    public class MyTileDownloader extends MapTileModuleProviderBase {
        private static final String TAG = "MyMapTileDownloader";
    
        protected OnlineTileSourceBase mTileSource;
        protected final IFilesystemCache mFilesystemCache;
        protected final INetworkAvailablityCheck mNetworkAvailablityCheck;
        protected final SSLSocketFactory mSSLSocketFactory;
    
        public MyTileDownloader(ITileSource pTileSource,
                IFilesystemCache pFilesystemCache,
                INetworkAvailablityCheck pNetworkAvailablityCheck,
                SSLSocketFactory pSSLSocketFactory) {
            super(4, TILE_DOWNLOAD_MAXIMUM_QUEUE_SIZE);
            setTileSource(pTileSource);
            mFilesystemCache = pFilesystemCache;
            mNetworkAvailablityCheck = pNetworkAvailablityCheck;
            mSSLSocketFactory = pSSLSocketFactory;
        }
    
        public ITileSource getTileSource() {
            return mTileSource;
        }
    
        @Override
        public void setTileSource(final ITileSource tileSource) {
            // We are only interested in OnlineTileSourceBase tile sources
            if (tileSource instanceof OnlineTileSourceBase)
                mTileSource = (OnlineTileSourceBase) tileSource;
            else
                mTileSource = null;
        }
    
        @Override
        public boolean getUsesDataConnection() {
            return true;
        }
    
        @Override
        protected String getName() {
            return "Online Tile Download Provider";
        }
    
        @Override
        protected String getThreadGroupName() {
            return "downloader";
        }
    
        @Override
        public int getMinimumZoomLevel() {
            return (mTileSource != null ? mTileSource.getMinimumZoomLevel()
                    : MINIMUM_ZOOMLEVEL);
        }
    
        @Override
        public int getMaximumZoomLevel() {
            return (mTileSource != null ? mTileSource.getMaximumZoomLevel()
                    : MAXIMUM_ZOOMLEVEL);
        }
    
        @Override
        protected Runnable getTileLoader() {
            return new TileLoader();
        };
    
        private class TileLoader extends MapTileModuleProviderBase.TileLoader {
            @Override
            public Drawable loadTile(final MapTileRequestState aState)
                    throws CantContinueException {
                if (mTileSource == null)
                    return null;
    
                InputStream in = null;
                OutputStream out = null;
                final MapTile tile = aState.getMapTile();
    
                try {
                    if (mNetworkAvailablityCheck != null
                            && !mNetworkAvailablityCheck.getNetworkAvailable()) {
                        if (DEBUGMODE)
                            Log.d(TAG, "Skipping " + getName()
                                    + " due to NetworkAvailabliltyCheck.");
                        return null;
                    }
    
                    final String tileURLString = mTileSource.getTileURLString(tile);
                    if (DEBUGMODE)
                        Log.d(TAG, "Downloading Maptile from url: " + tileURLString);
    
                    if (TextUtils.isEmpty(tileURLString))
                        return null;
    
                    // Create an HttpURLConnection to download the tile
                    URL url = new URL(tileURLString);
                    HttpURLConnection connection = (HttpURLConnection) url
                            .openConnection();
                    connection.setConnectTimeout(30000);
                    connection.setReadTimeout(30000);
    
                    // Use our custom SSLSocketFactory for secure connections
                    if ("https".equalsIgnoreCase(url.getProtocol()))
                        ((HttpsURLConnection) connection)
                                .setSSLSocketFactory(mSSLSocketFactory);
    
                    // Open the input stream
                    in = new BufferedInputStream(connection.getInputStream(),
                            StreamUtils.IO_BUFFER_SIZE);
    
                    // Check to see if we got success
                    if (connection.getResponseCode() != 200) {
                        Log.w(TAG, "Problem downloading MapTile: " + tile
                                + " HTTP response: " + connection.getHeaderField(0));
                        return null;
                    }
    
                    // Read the tile into an in-memory byte array
                    final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
                    out = new BufferedOutputStream(dataStream,
                            StreamUtils.IO_BUFFER_SIZE);
                    StreamUtils.copy(in, out);
                    out.flush();
                    final byte[] data = dataStream.toByteArray();
                    final ByteArrayInputStream byteStream = new ByteArrayInputStream(
                            data);
    
                    // Save the data to the filesystem cache
                    if (mFilesystemCache != null) {
                        mFilesystemCache.saveFile(mTileSource, tile, byteStream);
                        byteStream.reset();
                    }
                    final Drawable result = mTileSource.getDrawable(byteStream);
                    return result;
    
                } catch (final UnknownHostException e) {
                    Log.w(TAG, "UnknownHostException downloading MapTile: " + tile
                            + " : " + e);
                    throw new CantContinueException(e);
    
                } catch (final LowMemoryException e) {
                    Log.w(TAG, "LowMemoryException downloading MapTile: " + tile
                            + " : " + e);
                    throw new CantContinueException(e);
    
                } catch (final FileNotFoundException e) {
                    Log.w(TAG, "Tile not found: " + tile + " : " + e);
    
                } catch (final IOException e) {
                    Log.w(TAG, "IOException downloading MapTile: " + tile + " : "
                            + e);
    
                } catch (final Throwable e) {
                    Log.e(TAG, "Error downloading MapTile: " + tile, e);
    
                } finally {
                    StreamUtils.closeStream(in);
                    StreamUtils.closeStream(out);
                }
                return null;
            }
    
            @Override
            protected void tileLoaded(final MapTileRequestState pState,
                    final Drawable pDrawable) {
                // Don't return the tile Drawable because we'll wait for the fs
                // provider to ask for it. This prevent flickering when a load
                // of delayed downloads complete for tiles that we might not
                // even be interested in any more.
                super.tileLoaded(pState, null);
            }
        }
    }
    

    MyTileProvider looks something like this.

    Note that you’ll need a way to get access to your instance of MySSLSocketFactory inside this class. This is left as an exercise for the reader. I did this using app.getSSLSocketFactory(), where app is an instance of a custom class that extends Application, but your mileage may vary.

    import javax.net.ssl.SSLSocketFactory;
    
    import org.osmdroid.tileprovider.IMapTileProviderCallback;
    import org.osmdroid.tileprovider.IRegisterReceiver;
    import org.osmdroid.tileprovider.MapTileProviderArray;
    import org.osmdroid.tileprovider.MapTileProviderBasic;
    import org.osmdroid.tileprovider.modules.INetworkAvailablityCheck;
    import org.osmdroid.tileprovider.modules.MapTileFileArchiveProvider;
    import org.osmdroid.tileprovider.modules.MapTileFilesystemProvider;
    import org.osmdroid.tileprovider.modules.NetworkAvailabliltyCheck;
    import org.osmdroid.tileprovider.modules.TileWriter;
    import org.osmdroid.tileprovider.tilesource.ITileSource;
    import org.osmdroid.tileprovider.util.SimpleRegisterReceiver;
    
    import android.content.Context;
    
    /**
     * A drop-in replacement for {@link MapTileProviderBasic}. This top-level tile
     * provider implements a basic tile request chain which includes a
     * {@link MapTileFilesystemProvider} (a file-system cache), a
     * {@link MapTileFileArchiveProvider} (archive provider), and a
     * {@link MyTileDownloader} (downloads map tiles via tile source).
     */
    public class MyTileProvider extends MapTileProviderArray implements
            IMapTileProviderCallback {
        public MyTileProvider(final Context pContext, final ITileSource pTileSource) {
            this(new SimpleRegisterReceiver(pContext),
                    new NetworkAvailabliltyCheck(pContext), pTileSource, app
                            .getSSLSocketFactory());
        }
    
        protected MyTileProvider(final IRegisterReceiver pRegisterReceiver,
                final INetworkAvailablityCheck aNetworkAvailablityCheck,
                final ITileSource pTileSource,
                final SSLSocketFactory pSSLSocketFactory) {
            super(pTileSource, pRegisterReceiver);
    
            // Look for raw tiles on the file system
            final MapTileFilesystemProvider fileSystemProvider = new MapTileFilesystemProvider(
                    pRegisterReceiver, pTileSource);
            mTileProviderList.add(fileSystemProvider);
    
            // Look for tile archives on the file system
            final MapTileFileArchiveProvider archiveProvider = new MapTileFileArchiveProvider(
                    pRegisterReceiver, pTileSource);
            mTileProviderList.add(archiveProvider);
    
            // Look for raw tiles on the Internet
            final TileWriter tileWriter = new TileWriter();
            final MyTileDownloader downloaderProvider = new MyTileDownloader(
                    pTileSource, tileWriter, aNetworkAvailablityCheck,
                    pSSLSocketFactory);
            mTileProviderList.add(downloaderProvider);
        }
    }
    

    Finally, the instantiation looks something like this:

    XYTileSource tileSource = new XYTileSource("MapQuest", null, 3, 8, 256, ".jpg",
        "https://10.0.0.1/path/to/your/map/tiles/");
    MapTileProviderBase tileProvider = new MyTileProvider(context, tileSource);
    ResourceProxy resourceProxy = new DefaultResourceProxyImpl(context);
    MapView mapView = new MapView(context, 256, resourceProxy, tileProvider);
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
I am trying to understand how to use SyndicationItem to display feed which is
Basically, what I'm trying to create is a page of div tags, each has
link Im having trouble converting the html entites into html characters, (&# 8217;) i
For some reason, after submitting a string like this Jack’s Spindle from a text
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
I am trying to render a haml file in a javascript response like so:
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
I'm trying to select an H1 element which is the second-child in its group
I have a text area in my form which accepts all possible characters from

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.