Reputation: 1150
I migrated the server from HTTP
to HTTPS
I have used self-signed certificate to send network requests with HttpUrlConnection
and it worked but for image loading it is not working as I have used Glide for Image loading.
javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.while loading images from https URL through glide library
Glide.with(mContext).load(currentItem.getImage_path().replace(" ", "%20"))
.listener(new RequestListener<String, GlideDrawable>() {
@Override
public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
genericViewHolder.imageView_1.setImageResource(R.drawable.image_thumbnail);
genericViewHolder.progressBar.setVisibility(View.GONE);
return false;
}
@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
genericViewHolder.progressBar.setVisibility(View.GONE);
return false;
}
}).into(genericViewHolder.imageView_1);
I tried using this link and used GlideModule but it does not seem to work. Please help.
Upvotes: 19
Views: 31348
Reputation: 41
I had this problem too. I used this link and I add 'kotlin-kapt' to plugins in build.gradle of the app so my dependencies was:
def glide_version = '4.15.1'
implementation "com.github.bumptech.glide:glide:$glide_version"
implementation "com.github.bumptech.glide:annotations:$glide_version"
implementation "com.github.bumptech.glide:okhttp3-integration:$glide_version"
kapt "com.github.bumptech.glide:compiler:$glide_version"
the code i used was:
public class UnsafeOkHttpClient {
public static OkHttpClient getUnsafeOkHttpClient() {
try {
@SuppressLint("CustomX509TrustManager") final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@SuppressLint("TrustAllX509TrustManager")
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@SuppressLint("TrustAllX509TrustManager")
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
//final SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.retryOnConnectionFailure(true);
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier((hostname, session) -> true);
return builder.build();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
and:
@GlideModule
class MyGlideAppModule : AppGlideModule() {
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
val client = UnsafeOkHttpClient.getUnsafeOkHttpClient()
val factory: OkHttpUrlLoader.Factory = OkHttpUrlLoader.Factory(client)
registry.replace(
GlideUrl::class.java,
InputStream::class.java, factory
)
}
}
and I add this meta-data to manifest:
<meta-data android:name="${applicationId}.network.MyGlideAppModule" android:value="AppGlideModule" />
I hode this be helpfull.
Upvotes: 2
Reputation: 820
You can use this code that I copied from the answer at Trusting all certificates with okHttp —
Create class UnsafeOkHttpClient.java
public class UnsafeOkHttpClient { public static OkHttpClient getUnsafeOkHttpClient() { try { // Create a trust manager that does not validate certificate chains final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { @Override public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String
authType) throws CertificateException { }
@Override public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String
authType) throws CertificateException { }
@Override public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[]{}; } } }; // Install the all-trusting trust manager final SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); // Create an ssl socket factory with our all-trusting manager final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]); builder.hostnameVerifier(new HostnameVerifier() { @Override public boolean verify(String hostname, SSLSession session) { return true; } }); OkHttpClient okHttpClient = builder.build(); return okHttpClient; } catch (Exception e) { throw new RuntimeException(e); } } }
Create a class MyGlideModule.java
@GlideModule public class MyGlideModule extends AppGlideModule { @Override public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) { OkHttpClient okHttpClient= UnsafeOkHttpClient.getUnsafeOkHttpClient(); registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okHttpClient)); } }
Create a class OkHttpStreamFetcher.java
public class OkHttpStreamFetcher implements DataFetcher<InputStream>, okhttp3.Callback { private static final String TAG = "OkHttpFetcher"; private final Call.Factory client; private final GlideUrl url; private InputStream stream; private ResponseBody responseBody; private DataCallback<? super InputStream> callback; private volatile Call call; // Public API. @SuppressWarnings("WeakerAccess") public OkHttpStreamFetcher(Call.Factory client, GlideUrl url) { this.client = client; this.url = url; } @Override public void loadData( @NonNull Priority priority, @NonNull final DataCallback<? super InputStream> callback) { Request.Builder requestBuilder = new Request.Builder().url(url.toStringUrl()); for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) { String key = headerEntry.getKey(); requestBuilder.addHeader(key, headerEntry.getValue()); } Request request = requestBuilder.build(); this.callback = callback; call = client.newCall(request); call.enqueue(this); } @Override public void onFailure(@NonNull Call call, @NonNull IOException e) { if (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, "OkHttp failed to obtain result", e); } callback.onLoadFailed(e); } @Override public void onResponse(@NonNull Call call, @NonNull Response response) { responseBody = response.body(); if (response.isSuccessful()) { long contentLength = Preconditions.checkNotNull(responseBody).contentLength(); stream = ContentLengthInputStream.obtain(responseBody.byteStream(),
contentLength); callback.onDataReady(stream); } else { callback.onLoadFailed(new HttpException(response.message(), response.code())); } }
@Override public void cleanup() { try { if (stream != null) { stream.close(); } } catch (IOException e) { // Ignored } if (responseBody != null) { responseBody.close(); } callback = null; } @Override public void cancel() { Call local = call; if (local != null) { local.cancel(); } } @NonNull @Override public Class<InputStream> getDataClass() { return InputStream.class; } @NonNull @Override public DataSource getDataSource() { return DataSource.REMOTE; } }
Create a class OkHttpUrlLoader.java
public class OkHttpUrlLoader implements ModelLoader<GlideUrl, InputStream> { private final Call.Factory client; // Public API. @SuppressWarnings("WeakerAccess") public OkHttpUrlLoader(@NonNull Call.Factory client) { this.client = client; } @Override public boolean handles(@NonNull GlideUrl url) { return true; } @Override public LoadData<InputStream> buildLoadData( @NonNull GlideUrl model, int width, int height, @NonNull Options options) { return new LoadData<>(model, new OkHttpStreamFetcher(client, model)); } public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> { private static volatile Call.Factory internalClient; private final Call.Factory client; private static Call.Factory getInternalClient() { if (internalClient == null) { synchronized (Factory.class) { if (internalClient == null) { internalClient = new OkHttpClient(); } } } return internalClient; } public Factory() { this(getInternalClient()); } public Factory(@NonNull Call.Factory client) { this.client = client; } @NonNull @Override public ModelLoader<GlideUrl, InputStream> build(MultiModelLoaderFactory multiFactory) { return new OkHttpUrlLoader(client); } @Override public void teardown() { // Do nothing, this instance doesn't own the client. } } }
Add app/build.gradle
implementation 'com.github.bumptech.glide:glide:4.10.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0' implementation("com.github.bumptech.glide:okhttp3-integration:4.2.0")
{ exclude group: 'glide-parent' }
In AndroidManifest.xml
<application> <meta-data android:name="Replace_your_package_name.UnsafeOkHttpClient" android:value="MyGlideModule" /> </application>
Upvotes: 5
Reputation: 1496
I have try to load https Image URL inside imagview using Glide 4.x. I have apply various developer answer inside my code but I didn't get success to load images. Finally I found a solution to load https image URL inside imageview using Glide. For that you have to follow below steps to attach certificate with glide request.
Step 1: You to import Latest glide library from glide official GitHub documentation. If you enable proguard then add code inside proguard file as per mention in glide documentation.
For Java developer
dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation("com.github.bumptech.glide:okhttp3-integration:4.11.0") {
exclude group: 'glide-parent'
}
}
For Kotling developer
dependencies {
implementation 'com.github.bumptech.glide:glide:4.11.0'
kapt 'com.github.bumptech.glide:compiler:4.11.0'
implementation("com.github.bumptech.glide:okhttp3-integration:4.11.0") {
exclude group: 'glide-parent'
}
}
Step 2: Once Glide Library successfully build with your project. UnsafeOkHttpClient clas. I have created this class in java but you can create this in kotlin as per your need.
public class OkHttpStreamFetcher implements DataFetcher<InputStream>, okhttp3.Callback {
private static final String TAG = "OkHttpFetcher";
private final Call.Factory client;
private final GlideUrl url;
private InputStream stream;
private ResponseBody responseBody;
private DataFetcher.DataCallback<? super InputStream> callback;
private volatile Call call;
// Public API.
@SuppressWarnings("WeakerAccess")
public OkHttpStreamFetcher(Call.Factory client, GlideUrl url) {
this.client = client;
this.url = url;
}
@Override
public void loadData(
@NonNull Priority priority, @NonNull final DataCallback<? super InputStream> callback) {
Request.Builder requestBuilder = new Request.Builder().url(url.toStringUrl());
for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) {
String key = headerEntry.getKey();
requestBuilder.addHeader(key, headerEntry.getValue());
}
Request request = requestBuilder.build();
this.callback = callback;
call = client.newCall(request);
call.enqueue(this);
}
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "OkHttp failed to obtain result", e);
}
callback.onLoadFailed(e);
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
responseBody = response.body();
if (response.isSuccessful()) {
long contentLength = Preconditions.checkNotNull(responseBody).contentLength();
stream = ContentLengthInputStream.obtain(responseBody.byteStream(), contentLength);
callback.onDataReady(stream);
} else {
callback.onLoadFailed(new HttpException(response.message(), response.code()));
}
}
@Override
public void cleanup() {
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {
// Ignored
}
if (responseBody != null) {
responseBody.close();
}
callback = null;
}
@Override
public void cancel() {
Call local = call;
if (local != null) {
local.cancel();
}
}
@NonNull
@Override
public Class<InputStream> getDataClass() {
return InputStream.class;
}
@NonNull
@Override
public DataSource getDataSource() {
return DataSource.REMOTE;
} }
Step 3: Now Start create on class which extends with AppGlideModule and @GlideModule annotation to that class. After annotation Rebuild your project and it will create one class GlideApp class inside your project. This class help us to send SSL request when glide try to load https url.
For Java Developer
@GlideModule
public class MyAppGlideModule extends AppGlideModule {
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
OkHttpClient okHttpClient= UnsafeOkHttpClient.getUnsafeOkHttpClient();
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okHttpClient));
}
}
For Kotlin Devloper
@GlideModule
class AppGlideModule : AppGlideModule(){
override fun registerComponents(@NonNull context: Context, @NonNull glide: Glide, @NonNull registry: Registry) {
val okHttpClient = UnsafeOkHttpClient.getUnsafeOkHttpClient()
registry.replace(GlideUrl::class.java, InputStream::class.java, OkHttpUrlLoader.Factory(okHttpClient))
}
}
Step 4: Use the GlideApp such as GlideApp.with(this).load(imgUrl).into(glide_test_iv1)
Summary: Glide 4.0 need not have declare "GlideModule" in AndroidManifest.xml. You just need to following steps:
YourAppGlideModule extends AppGlideModule, you can override function applyOptions in the YourAppGlideModule class.
You should make project in "android studio -> build -> make project", it will generate the GlideApp class.
Use the GlideApp such as GlideApp.with(this).load(imgUrl).into(glide_test_iv1)
Upvotes: 2
Reputation: 6693
Above both answer right but make sure also below dependency Add or change okhttp3-integration:4.4.0 version
implementation ('com.github.bumptech.glide:okhttp3-integration:4.4.0'){
exclude group: 'glide-parent'
}
Upvotes: 2
Reputation: 1126
For Glide 4
@GlideModule
public class MyGlideModule extends AppGlideModule {
@Override
public void registerComponents(@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
//To Attach Self Signed Ssl Certificate
/*OkHttpClient okHttpClient = new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, X509TrustManager)
.build();*/
//Unsafe Okhttp client
OkHttpClient okHttpClient= UnsafeHttpsClient.getUnsafeOkHttpClient();
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(okHttpClient));
}
}
Upvotes: -1
Reputation: 3835
The issue is about certificate follow this link -https://stackoverflow.com/a/39032433/4741746
This will bypass certificate and allow you to enter in system
see this link also -https://futurestud.io/tutorials/glide-module-example-accepting-self-signed-https-certificates
Create your custom GlideModule Class,OkHttpUrlLoader class and attach to you Glide as mention in above link
You have to put
<meta-data
android:name="io.futurestud.tutorials.glide.glidemodule.CustomImageSizeGlideModule"
android:value="GlideModule" />
Inside application tag of your AndroidMainifiest file https://github.com/fs-opensource/android-tutorials-glide/blob/master/app/src/main/AndroidManifest.xml
Upvotes: 12