mirror of
https://github.com/sismics/docs.git
synced 2024-11-25 15:17:57 +01:00
#57: Android: Migrate document resource to OkHttp
Closes #58: Android: OkHttpClient and cache as singleton
This commit is contained in:
parent
d9509474b0
commit
456fc5b991
@ -61,13 +61,6 @@
|
|||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
|
||||||
@ -75,6 +68,13 @@
|
|||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
|
||||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
|
||||||
@ -88,6 +88,7 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/it.sephiroth.android.library.imagezoom/imagezoom/1.0.5/jars" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/it.sephiroth.android.library.imagezoom/imagezoom/1.0.5/jars" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtimfe-classes" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtimfe-classes" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
|
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
|
||||||
|
@ -3,7 +3,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:2.0.0-alpha5'
|
classpath 'com.android.tools.build:gradle:2.0.0-alpha7'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
@ -17,7 +17,7 @@ import com.sismics.docs.adapter.LanguageAdapter;
|
|||||||
import com.sismics.docs.adapter.TagAutoCompleteAdapter;
|
import com.sismics.docs.adapter.TagAutoCompleteAdapter;
|
||||||
import com.sismics.docs.event.DocumentAddEvent;
|
import com.sismics.docs.event.DocumentAddEvent;
|
||||||
import com.sismics.docs.event.DocumentEditEvent;
|
import com.sismics.docs.event.DocumentEditEvent;
|
||||||
import com.sismics.docs.listener.JsonHttpResponseHandler;
|
import com.sismics.docs.listener.HttpCallback;
|
||||||
import com.sismics.docs.resource.DocumentResource;
|
import com.sismics.docs.resource.DocumentResource;
|
||||||
import com.sismics.docs.ui.form.Validator;
|
import com.sismics.docs.ui.form.Validator;
|
||||||
import com.sismics.docs.ui.form.validator.Required;
|
import com.sismics.docs.ui.form.validator.Required;
|
||||||
@ -35,7 +35,6 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import cz.msebera.android.httpclient.Header;
|
|
||||||
import de.greenrobot.event.EventBus;
|
import de.greenrobot.event.EventBus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,9 +173,9 @@ public class DocumentEditActivity extends AppCompatActivity {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Server callback
|
// Server callback
|
||||||
JsonHttpResponseHandler callback = new JsonHttpResponseHandler() {
|
HttpCallback callback = new HttpCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
public void onSuccess(JSONObject response) {
|
||||||
// Build a fake document JSON to update the UI
|
// Build a fake document JSON to update the UI
|
||||||
final JSONObject outputDoc = new JSONObject();
|
final JSONObject outputDoc = new JSONObject();
|
||||||
try {
|
try {
|
||||||
@ -211,7 +210,7 @@ public class DocumentEditActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
|
public void onFailure(JSONObject json, Exception e) {
|
||||||
Toast.makeText(DocumentEditActivity.this, R.string.error_editing_document, Toast.LENGTH_LONG).show();
|
Toast.makeText(DocumentEditActivity.this, R.string.error_editing_document, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ import com.sismics.docs.event.FileAddEvent;
|
|||||||
import com.sismics.docs.event.FileDeleteEvent;
|
import com.sismics.docs.event.FileDeleteEvent;
|
||||||
import com.sismics.docs.fragment.DocExportPdfFragment;
|
import com.sismics.docs.fragment.DocExportPdfFragment;
|
||||||
import com.sismics.docs.fragment.DocShareFragment;
|
import com.sismics.docs.fragment.DocShareFragment;
|
||||||
|
import com.sismics.docs.listener.HttpCallback;
|
||||||
import com.sismics.docs.listener.JsonHttpResponseHandler;
|
import com.sismics.docs.listener.JsonHttpResponseHandler;
|
||||||
import com.sismics.docs.model.application.ApplicationContext;
|
import com.sismics.docs.model.application.ApplicationContext;
|
||||||
import com.sismics.docs.resource.CommentResource;
|
import com.sismics.docs.resource.CommentResource;
|
||||||
@ -487,14 +488,14 @@ public class DocumentViewActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
// Actual delete server call
|
// Actual delete server call
|
||||||
final String documentId = document.optString("id");
|
final String documentId = document.optString("id");
|
||||||
DocumentResource.delete(DocumentViewActivity.this, documentId, new JsonHttpResponseHandler() {
|
DocumentResource.delete(DocumentViewActivity.this, documentId, new HttpCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
public void onSuccess(JSONObject response) {
|
||||||
EventBus.getDefault().post(new DocumentDeleteEvent(documentId));
|
EventBus.getDefault().post(new DocumentDeleteEvent(documentId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
|
public void onFailure(JSONObject json, Exception e) {
|
||||||
Toast.makeText(DocumentViewActivity.this, R.string.document_delete_failure, Toast.LENGTH_LONG).show();
|
Toast.makeText(DocumentViewActivity.this, R.string.document_delete_failure, Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,9 +647,9 @@ public class DocumentViewActivity extends AppCompatActivity {
|
|||||||
// Silently get the document to know if it is writable by the current user
|
// Silently get the document to know if it is writable by the current user
|
||||||
// If this call fails or is slow and the document is read-only,
|
// If this call fails or is slow and the document is read-only,
|
||||||
// write actions will be allowed and will fail
|
// write actions will be allowed and will fail
|
||||||
DocumentResource.get(this, document.optString("id"), new JsonHttpResponseHandler() {
|
DocumentResource.get(this, document.optString("id"), new HttpCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
public void onSuccess(JSONObject response) {
|
||||||
document = response;
|
document = response;
|
||||||
boolean writable = document.optBoolean("writable");
|
boolean writable = document.optBoolean("writable");
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ public class CommentListAdapter extends BaseAdapter {
|
|||||||
|
|
||||||
// Gravatar image
|
// Gravatar image
|
||||||
String gravatarUrl = "http://www.gravatar.com/avatar/" + comment.optString("creator_gravatar") + "?s=128d=identicon";
|
String gravatarUrl = "http://www.gravatar.com/avatar/" + comment.optString("creator_gravatar") + "?s=128d=identicon";
|
||||||
OkHttpUtil.picasso(context, null)
|
OkHttpUtil.picasso(context)
|
||||||
.load(gravatarUrl)
|
.load(gravatarUrl)
|
||||||
.into(gravatarImageView);
|
.into(gravatarImageView);
|
||||||
|
|
||||||
|
@ -66,9 +66,9 @@ public class FilePagerAdapter extends PagerAdapter {
|
|||||||
String fileUrl = PreferenceUtil.getServerUrl(context) + "/api/file/" + file.optString("id") + "/data?size=web";
|
String fileUrl = PreferenceUtil.getServerUrl(context) + "/api/file/" + file.optString("id") + "/data?size=web";
|
||||||
|
|
||||||
// Load image
|
// Load image
|
||||||
OkHttpUtil.picasso(context, authToken)
|
OkHttpUtil.picasso(context)
|
||||||
.load(fileUrl)
|
.load(fileUrl)
|
||||||
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
|
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE) // Don't memory cache the images
|
||||||
.into(fileImageView, new Callback.EmptyCallback() {
|
.into(fileImageView, new Callback.EmptyCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess() {
|
public void onSuccess() {
|
||||||
@ -109,7 +109,7 @@ public class FilePagerAdapter extends PagerAdapter {
|
|||||||
* @return Object
|
* @return Object
|
||||||
*/
|
*/
|
||||||
public JSONObject getObjectAt(int position) {
|
public JSONObject getObjectAt(int position) {
|
||||||
if (files == null) {
|
if (files == null || position < 0 || position >= files.size()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ import com.sismics.docs.R;
|
|||||||
import com.sismics.docs.adapter.ShareListAdapter;
|
import com.sismics.docs.adapter.ShareListAdapter;
|
||||||
import com.sismics.docs.event.ShareDeleteEvent;
|
import com.sismics.docs.event.ShareDeleteEvent;
|
||||||
import com.sismics.docs.event.ShareSendEvent;
|
import com.sismics.docs.event.ShareSendEvent;
|
||||||
|
import com.sismics.docs.listener.HttpCallback;
|
||||||
import com.sismics.docs.listener.JsonHttpResponseHandler;
|
import com.sismics.docs.listener.JsonHttpResponseHandler;
|
||||||
import com.sismics.docs.resource.DocumentResource;
|
import com.sismics.docs.resource.DocumentResource;
|
||||||
import com.sismics.docs.resource.ShareResource;
|
import com.sismics.docs.resource.ShareResource;
|
||||||
@ -122,9 +123,9 @@ public class DocShareFragment extends DialogFragment {
|
|||||||
final ProgressBar shareProgressBar = (ProgressBar) view.findViewById(R.id.shareProgressBar);
|
final ProgressBar shareProgressBar = (ProgressBar) view.findViewById(R.id.shareProgressBar);
|
||||||
|
|
||||||
shareListView.setEmptyView(shareProgressBar);
|
shareListView.setEmptyView(shareProgressBar);
|
||||||
DocumentResource.get(getActivity(), getArguments().getString("id"), new JsonHttpResponseHandler() {
|
DocumentResource.get(getActivity(), getArguments().getString("id"), new HttpCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
|
public void onSuccess(JSONObject response) {
|
||||||
document = response;
|
document = response;
|
||||||
JSONArray acls = response.optJSONArray("acls");
|
JSONArray acls = response.optJSONArray("acls");
|
||||||
shareProgressBar.setVisibility(View.GONE);
|
shareProgressBar.setVisibility(View.GONE);
|
||||||
@ -133,7 +134,7 @@ public class DocShareFragment extends DialogFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAllFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) {
|
public void onFailure(JSONObject json, Exception e) {
|
||||||
getDialog().cancel();
|
getDialog().cancel();
|
||||||
Toast.makeText(getActivity(), R.string.error_loading_shares, Toast.LENGTH_SHORT).show();
|
Toast.makeText(getActivity(), R.string.error_loading_shares, Toast.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,7 @@ import com.sismics.docs.util.ApplicationUtil;
|
|||||||
import com.sismics.docs.util.PreferenceUtil;
|
import com.sismics.docs.util.PreferenceUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.CookieManager;
|
|
||||||
import java.net.CookiePolicy;
|
|
||||||
import java.net.HttpCookie;
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.URI;
|
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
@ -22,18 +18,12 @@ import java.security.UnrecoverableKeyException;
|
|||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
import cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory;
|
import cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory;
|
||||||
import okhttp3.Interceptor;
|
|
||||||
import okhttp3.JavaNetCookieJar;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.Request;
|
|
||||||
import okhttp3.Response;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for API access.
|
* Base class for API access.
|
||||||
@ -41,7 +31,6 @@ import okhttp3.Response;
|
|||||||
* @author bgamard
|
* @author bgamard
|
||||||
*/
|
*/
|
||||||
public class BaseResource {
|
public class BaseResource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User-Agent to use.
|
* User-Agent to use.
|
||||||
*/
|
*/
|
||||||
@ -57,11 +46,6 @@ public class BaseResource {
|
|||||||
*/
|
*/
|
||||||
protected static AsyncHttpClient client = new AsyncHttpClient();
|
protected static AsyncHttpClient client = new AsyncHttpClient();
|
||||||
|
|
||||||
/**
|
|
||||||
* OkHttp client.
|
|
||||||
*/
|
|
||||||
protected static OkHttpClient okHttpClient = new OkHttpClient();
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// 20sec default timeout
|
// 20sec default timeout
|
||||||
client.setTimeout(60000);
|
client.setTimeout(60000);
|
||||||
@ -76,43 +60,6 @@ public class BaseResource {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// NOP
|
// NOP
|
||||||
}
|
}
|
||||||
|
|
||||||
// OkHttp configuration
|
|
||||||
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 null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Install the all-trusting trust manager
|
|
||||||
final SSLContext sslContext = SSLContext.getInstance("TLS");
|
|
||||||
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
|
|
||||||
final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
|
||||||
|
|
||||||
// Configure OkHttpClient
|
|
||||||
okHttpClient = okHttpClient.newBuilder()
|
|
||||||
.connectTimeout(30, TimeUnit.SECONDS)
|
|
||||||
.readTimeout(30, TimeUnit.SECONDS)
|
|
||||||
.writeTimeout(30, TimeUnit.SECONDS)
|
|
||||||
.hostnameVerifier(MySSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
|
|
||||||
.sslSocketFactory(sslSocketFactory)
|
|
||||||
.build();
|
|
||||||
} catch (Exception e) {
|
|
||||||
// NOP
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,46 +82,6 @@ public class BaseResource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Build an OkHttpClient.
|
|
||||||
*
|
|
||||||
* @param context Context
|
|
||||||
* @return OkHttpClient
|
|
||||||
*/
|
|
||||||
protected static OkHttpClient buildOkHttpClient(final Context context) {
|
|
||||||
// Header computation
|
|
||||||
if (USER_AGENT == null) {
|
|
||||||
USER_AGENT = "Sismics Docs Android " + ApplicationUtil.getVersionName(context) + "/Android " + Build.VERSION.RELEASE + "/" + Build.MODEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ACCEPT_LANGUAGE == null) {
|
|
||||||
Locale locale = Locale.getDefault();
|
|
||||||
ACCEPT_LANGUAGE = locale.getLanguage() + "_" + locale.getCountry();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cookie handling
|
|
||||||
com.sismics.docs.resource.cookie.PersistentCookieStore cookieStore = new com.sismics.docs.resource.cookie.PersistentCookieStore(context);
|
|
||||||
CookieManager cookieManager = new CookieManager(cookieStore, CookiePolicy.ACCEPT_ALL);
|
|
||||||
cookieStore.add(URI.create(PreferenceUtil.getServerUrl(context)),
|
|
||||||
new HttpCookie("auth_token", PreferenceUtil.getAuthToken(context))); // TODO Remove me when async http is ditched
|
|
||||||
|
|
||||||
// Runtime configuration
|
|
||||||
return okHttpClient.newBuilder()
|
|
||||||
.cookieJar(new JavaNetCookieJar(cookieManager))
|
|
||||||
.addNetworkInterceptor(new Interceptor() {
|
|
||||||
@Override
|
|
||||||
public Response intercept(Chain chain) throws IOException {
|
|
||||||
Request originalRequest = chain.request();
|
|
||||||
return chain.proceed(originalRequest.newBuilder()
|
|
||||||
.header("User-Agent", USER_AGENT)
|
|
||||||
.header("Accept-Language", ACCEPT_LANGUAGE)
|
|
||||||
// TODO necessary?? .method(originalRequest.method(), originalRequest.body())
|
|
||||||
.build());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Socket factory to allow self-signed certificates for Async HTTP Client.
|
* Socket factory to allow self-signed certificates for Async HTTP Client.
|
||||||
*
|
*
|
||||||
|
@ -2,12 +2,12 @@ package com.sismics.docs.resource;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import com.loopj.android.http.RequestParams;
|
|
||||||
import com.sismics.docs.listener.HttpCallback;
|
import com.sismics.docs.listener.HttpCallback;
|
||||||
import com.sismics.docs.listener.JsonHttpResponseHandler;
|
import com.sismics.docs.util.OkHttpUtil;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import okhttp3.FormBody;
|
||||||
import okhttp3.HttpUrl;
|
import okhttp3.HttpUrl;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
|
|
||||||
@ -35,8 +35,9 @@ public class DocumentResource extends BaseResource {
|
|||||||
.addQueryParameter("asc", "false")
|
.addQueryParameter("asc", "false")
|
||||||
.addQueryParameter("search", query)
|
.addQueryParameter("search", query)
|
||||||
.build())
|
.build())
|
||||||
|
.get()
|
||||||
.build();
|
.build();
|
||||||
buildOkHttpClient(context)
|
OkHttpUtil.buildClient(context)
|
||||||
.newCall(request)
|
.newCall(request)
|
||||||
.enqueue(HttpCallback.buildOkHttpCallback(callback));
|
.enqueue(HttpCallback.buildOkHttpCallback(callback));
|
||||||
}
|
}
|
||||||
@ -46,12 +47,16 @@ public class DocumentResource extends BaseResource {
|
|||||||
*
|
*
|
||||||
* @param context Context
|
* @param context Context
|
||||||
* @param id ID
|
* @param id ID
|
||||||
* @param responseHandler Callback
|
* @param callback Callback
|
||||||
*/
|
*/
|
||||||
public static void get(Context context, String id, JsonHttpResponseHandler responseHandler) {
|
public static void get(Context context, String id, HttpCallback callback) {
|
||||||
init(context);
|
Request request = new Request.Builder()
|
||||||
|
.url(HttpUrl.parse(getApiUrl(context) + "/document/" + id))
|
||||||
client.get(getApiUrl(context) + "/document/" + id, responseHandler);
|
.get()
|
||||||
|
.build();
|
||||||
|
OkHttpUtil.buildClient(context)
|
||||||
|
.newCall(request)
|
||||||
|
.enqueue(HttpCallback.buildOkHttpCallback(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,12 +64,16 @@ public class DocumentResource extends BaseResource {
|
|||||||
*
|
*
|
||||||
* @param context Context
|
* @param context Context
|
||||||
* @param id ID
|
* @param id ID
|
||||||
* @param responseHandler Callback
|
* @param callback Callback
|
||||||
*/
|
*/
|
||||||
public static void delete(Context context, String id, JsonHttpResponseHandler responseHandler) {
|
public static void delete(Context context, String id, HttpCallback callback) {
|
||||||
init(context);
|
Request request = new Request.Builder()
|
||||||
|
.url(HttpUrl.parse(getApiUrl(context) + "/document/" + id))
|
||||||
client.delete(getApiUrl(context) + "/document/" + id, responseHandler);
|
.delete()
|
||||||
|
.build();
|
||||||
|
OkHttpUtil.buildClient(context)
|
||||||
|
.newCall(request)
|
||||||
|
.enqueue(HttpCallback.buildOkHttpCallback(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -76,19 +85,27 @@ public class DocumentResource extends BaseResource {
|
|||||||
* @param tagIdList Tags ID list
|
* @param tagIdList Tags ID list
|
||||||
* @param language Language
|
* @param language Language
|
||||||
* @param createDate Create date
|
* @param createDate Create date
|
||||||
* @param responseHandler Callback
|
* @param callback Callback
|
||||||
*/
|
*/
|
||||||
public static void add(Context context, String title, String description,
|
public static void add(Context context, String title, String description,
|
||||||
Set<String> tagIdList, String language, long createDate, JsonHttpResponseHandler responseHandler) {
|
Set<String> tagIdList, String language, long createDate, HttpCallback callback) {
|
||||||
init(context);
|
FormBody.Builder formBuilder = new FormBody.Builder()
|
||||||
|
.add("title", title)
|
||||||
|
.add("description", description)
|
||||||
|
.add("language", language)
|
||||||
|
.add("create_date", Long.toString(createDate));
|
||||||
|
String[] tagIdArray = tagIdList.toArray(new String[tagIdList.size()]);
|
||||||
|
for (int i = 0; i < tagIdArray.length; i++) {
|
||||||
|
formBuilder.add("tags", tagIdArray[i]);
|
||||||
|
}
|
||||||
|
|
||||||
RequestParams params = new RequestParams();
|
Request request = new Request.Builder()
|
||||||
params.put("title", title);
|
.url(HttpUrl.parse(getApiUrl(context) + "/document"))
|
||||||
params.put("description", description);
|
.put(formBuilder.build())
|
||||||
params.put("tags", tagIdList);
|
.build();
|
||||||
params.put("language", language);
|
OkHttpUtil.buildClient(context)
|
||||||
params.put("create_date", createDate);
|
.newCall(request)
|
||||||
client.put(getApiUrl(context) + "/document", params, responseHandler);
|
.enqueue(HttpCallback.buildOkHttpCallback(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,19 +118,27 @@ public class DocumentResource extends BaseResource {
|
|||||||
* @param tagIdList Tags ID list
|
* @param tagIdList Tags ID list
|
||||||
* @param language Language
|
* @param language Language
|
||||||
* @param createDate Create date
|
* @param createDate Create date
|
||||||
* @param responseHandler Callback
|
* @param callback Callback
|
||||||
*/
|
*/
|
||||||
public static void edit(Context context, String id, String title, String description,
|
public static void edit(Context context, String id, String title, String description,
|
||||||
Set<String> tagIdList, String language, long createDate, JsonHttpResponseHandler responseHandler) {
|
Set<String> tagIdList, String language, long createDate, HttpCallback callback) {
|
||||||
init(context);
|
FormBody.Builder formBuilder = new FormBody.Builder()
|
||||||
|
.add("title", title)
|
||||||
|
.add("description", description)
|
||||||
|
.add("language", language)
|
||||||
|
.add("create_date", Long.toString(createDate));
|
||||||
|
String[] tagIdArray = tagIdList.toArray(new String[tagIdList.size()]);
|
||||||
|
for (int i = 0; i < tagIdArray.length; i++) {
|
||||||
|
formBuilder.add("tags", tagIdArray[i]);
|
||||||
|
}
|
||||||
|
|
||||||
RequestParams params = new RequestParams();
|
Request request = new Request.Builder()
|
||||||
params.put("title", title);
|
.url(HttpUrl.parse(getApiUrl(context) + "/document/" + id))
|
||||||
params.put("description", description);
|
.post(formBuilder.build())
|
||||||
params.put("tags", tagIdList);
|
.build();
|
||||||
params.put("language", language);
|
OkHttpUtil.buildClient(context)
|
||||||
params.put("create_date", createDate);
|
.newCall(request)
|
||||||
client.post(getApiUrl(context) + "/document/" + id, params, responseHandler);
|
.enqueue(HttpCallback.buildOkHttpCallback(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,23 +1,29 @@
|
|||||||
package com.sismics.docs.util;
|
package com.sismics.docs.util;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.jakewharton.picasso.OkHttp3Downloader;
|
import com.jakewharton.picasso.OkHttp3Downloader;
|
||||||
|
import com.sismics.docs.resource.cookie.PersistentCookieStore;
|
||||||
import com.squareup.picasso.Picasso;
|
import com.squareup.picasso.Picasso;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.CookieManager;
|
||||||
|
import java.net.CookiePolicy;
|
||||||
|
import java.net.HttpCookie;
|
||||||
|
import java.net.URI;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.net.ssl.HostnameVerifier;
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLSession;
|
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
import javax.net.ssl.X509TrustManager;
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
import okhttp3.Cache;
|
import okhttp3.Cache;
|
||||||
import okhttp3.Interceptor;
|
import okhttp3.Interceptor;
|
||||||
|
import okhttp3.JavaNetCookieJar;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
@ -29,57 +35,27 @@ import okhttp3.Response;
|
|||||||
*/
|
*/
|
||||||
public class OkHttpUtil {
|
public class OkHttpUtil {
|
||||||
/**
|
/**
|
||||||
* Build a Picasso object with base config.
|
* OkHttp singleton client.
|
||||||
*
|
|
||||||
* @param context Context
|
|
||||||
* @param authToken Auth token
|
|
||||||
* @return Picasso object
|
|
||||||
*/
|
*/
|
||||||
public static Picasso picasso(Context context, final String authToken) {
|
private static OkHttpClient okHttpClient = new OkHttpClient();
|
||||||
OkHttpClient okHttpClient = buildOkHttpClient()
|
|
||||||
.addInterceptor(new Interceptor() {
|
|
||||||
@Override
|
|
||||||
public Response intercept(Interceptor.Chain chain) throws IOException {
|
|
||||||
final Request original = chain.request();
|
|
||||||
final Request.Builder requestBuilder = original.newBuilder()
|
|
||||||
.header("Cookie", "auth_token=" + authToken)
|
|
||||||
.header("Cache-Control", "max-age=" + (3600 * 24 * 365))
|
|
||||||
.method(original.method(), original.body());
|
|
||||||
return chain.proceed(requestBuilder.build());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.cache(new Cache(context.getCacheDir(),
|
|
||||||
PreferenceUtil.getIntegerPreference(context, PreferenceUtil.PREF_CACHE_SIZE, 0) * 1000000))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Picasso picasso = new Picasso.Builder(context)
|
|
||||||
.downloader(new OkHttp3Downloader(okHttpClient))
|
|
||||||
.build();
|
|
||||||
picasso.setIndicatorsEnabled(false);
|
|
||||||
return picasso;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the cache.
|
* Singleton cache.
|
||||||
*
|
|
||||||
* @param context Context
|
|
||||||
*/
|
*/
|
||||||
public static void clearCache(Context context) {
|
private static Cache cache = null;
|
||||||
Cache cache = new Cache(context.getCacheDir(),
|
|
||||||
PreferenceUtil.getIntegerPreference(context, PreferenceUtil.PREF_CACHE_SIZE, Integer.MAX_VALUE));
|
|
||||||
try {
|
|
||||||
cache.evictAll();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e("OKHttpUtil", "Error clearing cache", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a OkHttpClient accepting all SSL certificates.
|
* User-Agent to use.
|
||||||
*
|
|
||||||
* @return OkHttpClient.Builder
|
|
||||||
*/
|
*/
|
||||||
private static OkHttpClient.Builder buildOkHttpClient() {
|
protected static String userAgent = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accept-Language header.
|
||||||
|
*/
|
||||||
|
protected static String acceptLanguage = null;
|
||||||
|
|
||||||
|
static {
|
||||||
|
// OkHttp configuration
|
||||||
try {
|
try {
|
||||||
// Create a trust manager that does not validate certificate chains
|
// Create a trust manager that does not validate certificate chains
|
||||||
final TrustManager[] trustAllCerts = new TrustManager[] {
|
final TrustManager[] trustAllCerts = new TrustManager[] {
|
||||||
@ -102,22 +78,114 @@ public class OkHttpUtil {
|
|||||||
// Install the all-trusting trust manager
|
// Install the all-trusting trust manager
|
||||||
final SSLContext sslContext = SSLContext.getInstance("TLS");
|
final SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
|
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||||
|
final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
||||||
|
|
||||||
// Create an ssl socket factory with our all-trusting manager
|
// Configure OkHttpClient
|
||||||
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
okHttpClient = okHttpClient.newBuilder()
|
||||||
|
.connectTimeout(30, TimeUnit.SECONDS)
|
||||||
OkHttpClient.Builder builder = new OkHttpClient.Builder();
|
.readTimeout(30, TimeUnit.SECONDS)
|
||||||
builder.sslSocketFactory(sslSocketFactory);
|
.writeTimeout(30, TimeUnit.SECONDS)
|
||||||
builder.hostnameVerifier(new HostnameVerifier() {
|
.sslSocketFactory(sslSocketFactory)
|
||||||
@Override
|
.build();
|
||||||
public boolean verify(String hostname, SSLSession session) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return builder;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
// NOP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a Picasso object with base config.
|
||||||
|
*
|
||||||
|
* @param context Context
|
||||||
|
* @return Picasso object
|
||||||
|
*/
|
||||||
|
public static Picasso picasso(Context context) {
|
||||||
|
OkHttpClient okHttpClient = buildClient(context)
|
||||||
|
.newBuilder()
|
||||||
|
.addInterceptor(new Interceptor() {
|
||||||
|
@Override
|
||||||
|
public Response intercept(Interceptor.Chain chain) throws IOException { // Override cache configuration
|
||||||
|
final Request original = chain.request();
|
||||||
|
final Request.Builder requestBuilder = original.newBuilder()
|
||||||
|
.header("Cache-Control", "max-age=" + (3600 * 24 * 365))
|
||||||
|
.method(original.method(), original.body());
|
||||||
|
return chain.proceed(requestBuilder.build());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.cache(getCache(context))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Picasso picasso = new Picasso.Builder(context)
|
||||||
|
.downloader(new OkHttp3Downloader(okHttpClient))
|
||||||
|
.build();
|
||||||
|
picasso.setIndicatorsEnabled(false); // Debug stuff
|
||||||
|
return picasso;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get and eventually build the singleton cache.
|
||||||
|
*
|
||||||
|
* @param context Context
|
||||||
|
* @return Cache
|
||||||
|
*/
|
||||||
|
private static Cache getCache(Context context) {
|
||||||
|
if (cache == null) {
|
||||||
|
cache = new Cache(context.getCacheDir(),
|
||||||
|
PreferenceUtil.getIntegerPreference(context, PreferenceUtil.PREF_CACHE_SIZE, 0) * 1000000);
|
||||||
|
}
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the HTTP cache.
|
||||||
|
*
|
||||||
|
* @param context Context
|
||||||
|
*/
|
||||||
|
public static void clearCache(Context context) {
|
||||||
|
Cache cache = getCache(context);
|
||||||
|
try {
|
||||||
|
cache.evictAll();
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e("OKHttpUtil", "Error clearing cache", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an OkHttpClient.
|
||||||
|
*
|
||||||
|
* @param context Context
|
||||||
|
* @return OkHttpClient
|
||||||
|
*/
|
||||||
|
public static OkHttpClient buildClient(final Context context) {
|
||||||
|
// One-time header computation
|
||||||
|
if (userAgent == null) {
|
||||||
|
userAgent = "Sismics Docs Android " + ApplicationUtil.getVersionName(context) + "/Android " + Build.VERSION.RELEASE + "/" + Build.MODEL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acceptLanguage == null) {
|
||||||
|
Locale locale = Locale.getDefault();
|
||||||
|
acceptLanguage = locale.getLanguage() + "_" + locale.getCountry();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cookie handling
|
||||||
|
PersistentCookieStore cookieStore = new PersistentCookieStore(context);
|
||||||
|
CookieManager cookieManager = new CookieManager(cookieStore, CookiePolicy.ACCEPT_ALL);
|
||||||
|
cookieStore.add(URI.create(PreferenceUtil.getServerUrl(context)),
|
||||||
|
new HttpCookie("auth_token", PreferenceUtil.getAuthToken(context))); // TODO Remove me when async http is ditched
|
||||||
|
|
||||||
|
// Runtime configuration
|
||||||
|
return okHttpClient.newBuilder()
|
||||||
|
.cookieJar(new JavaNetCookieJar(cookieManager))
|
||||||
|
.addNetworkInterceptor(new Interceptor() {
|
||||||
|
@Override
|
||||||
|
public Response intercept(Chain chain) throws IOException {
|
||||||
|
Request originalRequest = chain.request();
|
||||||
|
return chain.proceed(originalRequest.newBuilder()
|
||||||
|
.header("User-Agent", userAgent)
|
||||||
|
.header("Accept-Language", acceptLanguage)
|
||||||
|
// TODO necessary?? .method(originalRequest.method(), originalRequest.body())
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user