Android Volley Https SSL自签名证书和Google Maps API

3
我们正在使用Android Volley,并使用一个自认证的SSL,它可以正常工作。但现在我们想要实现Google Maps,但它不起作用;它只是显示一个灰色屏幕,没有任何错误提示。这是我们Volley的实现方式: enter image description here
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);
}

这是我们的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; }

地图活动(MapActivity)是由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));
}}

以及它的位置:

<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" />

在activity_maps.xml中,
我们如何实现地图Activity呢?谢谢!

1
请展示您实现地图并设置其位置的代码。 - Barns
1
日志里有错误信息吗?也许与API密钥和身份验证相关的内容? - xomena
{btsdaf} - Ramon
1个回答

3
尝试将Google地图客户端调用添加到hostnameVerifier中:

返回主机名.compareTo("OUR_SERVER_HOSTNAME")==0 || 主机名.compareTo("clients4.google.com") == 0;

由于使用了HostnameVerfiier类,因此API的调用会被您的代码捕获。


谢谢,你救了我的一个月! - Ramon
你救了我几天的痛苦,谢谢。 - Makari Kevin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接