Android Volley Https SSL self signed and Google Maps API

匿名 (未验证) 提交于 2019-12-03 08:57:35

问题:

We are working with Android Volley and using a self certificated SSL that works correctly, but now we want to implement Google Maps and it doesn't work; it just doesn't throws any error, it just shows a greyed out screen

This is our implementation of Volley:

public class AppSingleton { private static AppSingleton mAppSingletonInstance; private RequestQueue mRequestQueue; private static Context mContext;  private AppSingleton(Context context) {     mContext = context;     mRequestQueue = getRequestQueue(); }  public static synchronized AppSingleton getInstance(Context context) {     if (mAppSingletonInstance == null) {         mAppSingletonInstance = new AppSingleton(context);     }     return mAppSingletonInstance; }  private RequestQueue getRequestQueue() {     if (mRequestQueue == null) {         mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext(), new HurlStack(null, getSocketFactory()));     }     return mRequestQueue; }  public <T> void addToRequestQueue(Request<T> req, String tag) {     req.setTag(tag);     getRequestQueue().add(req); }

And this is our getSocketFactory:

private SSLSocketFactory getSocketFactory() {  CertificateFactory cf = null; try {     cf = CertificateFactory.getInstance("X.509");     InputStream caInput = mContext.getResources().openRawResource(OUR_CERT);     Certificate ca;     try {         ca = cf.generateCertificate(caInput);         Log.e("CERT", "ca=" + ((X509Certificate) ca).getSubjectDN());     } finally {         caInput.close();     }       String keyStoreType = KeyStore.getDefaultType();     KeyStore keyStore = KeyStore.getInstance(keyStoreType);     keyStore.load(null, null);     keyStore.setCertificateEntry("ca", ca);       String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();     TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);     tmf.init(keyStore);       HostnameVerifier hostnameVerifier = new HostnameVerifier() {         @Override         public boolean verify(String hostname, SSLSession session) {              Log.e("CipherUsed", session.getCipherSuite());             return hostname.compareTo("OUR_SERVER_HOSTNAME")==0;          }     };       HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);     SSLContext context = null;     context = SSLContext.getInstance("TLS");      context.init(null, tmf.getTrustManagers(), null);     HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());      SSLSocketFactory sf = context.getSocketFactory();       return sf;  } catch (CertificateException | NoSuchAlgorithmException | KeyStoreException | IOException | KeyManagementException e) {     e.printStackTrace(); }  return  null; }

The MapActivity is the generic one created by Android Studio:

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {  private GoogleMap mMap;  @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_maps2);     SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()             .findFragmentById(R.id.map);     mapFragment.getMapAsync(this); }  @Override public void onMapReady(GoogleMap googleMap) {     mMap = googleMap;      // Add a marker in Sydney and move the camera     LatLng sydney = new LatLng(-34, 151);     mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));     mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); }}

And its location:

<fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:map="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="cat.amb.parcandride.MapsActivity" />

In a activity_maps.xml

How could we implement the Map Activity? Thank you!

回答1:

Try to add the google map clients call to the hostnameVerifier:

return hostname.compareTo("OUR_SERVER_HOSTNAME")==0 || hostname.compareTo("clients4.google.com") == 0;

for some reason the call to the API gets caught by your code once the HostnameVerfiier class is used.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!