2020/02/08 Added reference link 2020/02/10 Added the reason for using it asynchronously
Keep the code you wrote when you decided to support HTTPS communication using the client certificate as a memo in case you quit the company and can not see the source code. The reason why I stick to Okhttp is that I hated it because I was suffering from it long ago. Http (s) URLConnection There may be some parts that are sloppy in writing and some parts that are like a sermon to Buddha, but please forgive me because it is a memo for me.
<manifest ・ ・ ・
...
//Permissions for internet connection
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
build.gradle
・ ・ ・
dependencies {
・ ・ ・
implementation("com.squareup.okhttp3:okhttp:4.3.1")
1 and 2 are for HTTPS communication, 3 and 4 are for Okhttp It's getting harder to write so far ... FE Fukayuki 〇 I want to do it
Asynctask, not the main thread ... I'm writing in asynchronous processing I used to write in the main thread (MainActivity, etc.), but ... that? Why did you change it? → Originally, Asynctask used Httpurl connection. I tried using okhttp asynchronously and it was possible, and the operation of the application seems to be lighter, so I adopted it as it is (additional note)
AsyncHttps.java
package com.example.test;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
//Asynchronous processing
//A place for HTTPS communication
//The caller converted the image into a byte array and passed it to this act
public class AsyncHttps extends AsyncTask<byte[], Void, String>
{
private Context mContext;
public AsyncHttps(Context context)
{mContext = context;}
public static String res=null;
final Handler handler = new Handler();
//For array numbers in URLsList
public static int url_id = 0;
//Communication result storage variable
public static String result = null;
//Asynchronous processing
@Override
protected String doInBackground(byte[]... params)
{
//I realized that I should write the url list in another act as an array and send the array number at the source.
String urlSt = URLsList.URL[url_id];
byte[] word = params[0];
//
return result;
}
//For http communication
public void http_post(byte[] bytes)
{
//It seems to be a setting for sending using JSON
//Media Type needs to be changed according to what is sent(If it is an image"image/jpg"Feeling like)
MediaType mediaType= MediaType.parse("application/json; charset=utf-8");
//Request Body creation. Things to send
RequestBody requestBody = RequestBody.create(mediaType,bytes);
//It's like making a request and packing mail, right?(Texto)
Request request = new Request.Builder()
//Destination
.url(URLsList.URL[url_id])
.post(requestBody) //Contents to send
.build(); //Build up these
KeyManagerFactory keyManagerFactory;
//Password set when creating the certificate
final char[] PASSWORD = "***Password here***".toCharArray();
InputStream inputStream;
TrustManagerFactory trustManagerFactory;
SSLSocketFactory sslSocketFactory;
X509TrustManager trustManager;
try
{
//Specifying the client certificate file(Place it in the assets folder)
inputStream = mContext.getResources().getAssets().open("hogehage.pfx");
//As a reference, this extension was p12, so isn't that the case?
KeyStore keyStore = KeyStore.getInstance("PKCS12");
//From here on down, you can copy and paste without thinking about anything
keyStore.load(inputStream,PASSWORD);
trustManagerFactory = TrustManagerFactory.getInstance
(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager))
{
throw new IllegalStateException("Unexpected default trust managers:"
+ Arrays.toString(trustManagers));
}
trustManager = (X509TrustManager)trustManagers[0];
keyManagerFactory = KeyManagerFactory.getInstance("X509");
keyManagerFactory.init(keyStore,PASSWORD);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(),null,null);
sslSocketFactory = sslContext.getSocketFactory();
//Copy and paste so far
final OkHttpClient client = new OkHttpClient.Builder()
//.connectTimeout(10, TimeUnit.SECONDS) //Timeout setting 3 Musketeer
//.readTimeout(10, TimeUnit.SECONDS) //I don't know what you are setting
//.writeTimeout(10, TimeUnit.SECONDS) //See you later
.sslSocketFactory(sslSocketFactory,trustManager)
.build();
client.newCall(request).enqueue(new Callback()
{
@Override
public void onFailure(@NonNull Call call, IOException e)
{
//It seems that the processing when an exception occurs will be stable if it is processed separately.
failMessage();
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException
{
result = String.valueOf(response);
//If something comes back, I may or may not do something here
client.connectionPool().evictAll();
}
});
}catch (IOException e)//From here on, when something explodes, it will appear in the error tab log. There is nothing to touch.
{Log.e("error contents:", String.valueOf(e));}
catch (NoSuchAlgorithmException e)
{Log.e("error contents:", String.valueOf(e));}
catch (CertificateException e)
{Log.e("error contents:", String.valueOf(e));}
catch (UnrecoverableKeyException e)
{Log.e("error contents:", String.valueOf(e));}
catch (KeyStoreException e)
{Log.e("error contents:", String.valueOf(e));}
catch (KeyManagementException e)
{Log.e("error contents:", String.valueOf(e));}
}
//When an exception occurs(When something goes wrong)Processing
private void failMessage()
{Log.d("Communication result:","It was bad…");}
}
Okhttp Official: https://square.github.io/okhttp/ Client certificate authentication within the Android app: https://qiita.com/c_ume/items/d082ffd20b3316aab805 Now that SSLSocketFactory is deprecated on Android, what would be the best way to handle Client Certificate Authentication? https://stackoverflow.com/questions/31002159/now-that-sslsocketfactory-is-deprecated-on-android-what-would-be-the-best-way-t
Recommended Posts