package com.ladjzero.uzlee;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Build;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.MotionEvent;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import com.ladjzero.uzlee.utils.UilUtils;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.orhanobut.logger.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
/**
* Created by chenzhuo on 16-1-31.
*/
public class WebView2 extends WebView {
private static final String TAG = "WebView2";
private final String JS_INTERFACE_NAME = "WebView2";
private boolean isEverScrolled;
private ActionMode mActionMode;
public WebView2(Context context) {
super(context);
this.addJavascriptInterface(this, JS_INTERFACE_NAME);
}
public WebView2(Context context, AttributeSet attrs) {
super(context, attrs);
this.addJavascriptInterface(this, JS_INTERFACE_NAME);
}
public WebView2(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.addJavascriptInterface(this, JS_INTERFACE_NAME);
}
@TargetApi(21)
public WebView2(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
this.addJavascriptInterface(this, JS_INTERFACE_NAME);
}
public WebView2(Context context, AttributeSet attrs, int defStyleAttr, boolean privateBrowsing) {
super(context, attrs, defStyleAttr, privateBrowsing);
this.addJavascriptInterface(this, JS_INTERFACE_NAME);
}
public boolean finishActionMode() {
if (mActionMode != null) {
mActionMode.finish();
mActionMode = null;
return true;
} else {
return false;
}
}
@Override
public ActionMode startActionMode(ActionMode.Callback callback) {
mActionMode = super.startActionMode(callback);
return mActionMode;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean toReturn = super.onTouchEvent(event);
int action = event.getAction();
if (action == MotionEvent.ACTION_MOVE) {
if (isEverScrolled) {
requestDisallowInterceptTouchEvent(true);
toReturn = true;
}
} else {
isEverScrolled = false;
}
return toReturn;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
isEverScrolled = true;
}
public Bitmap toBitmap() {
this.setDrawingCacheEnabled(true);
this.buildDrawingCache();
return toBitmap(1);
}
public Bitmap toBitmap(float radio) {
int width = (int) (this.getWidth() * radio);
int height = (int) (this.getContentHeight() * this.getScale() * radio);
if (width < 100) {
return null;
}
Bitmap bitmap;
try {
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.scale(radio, radio);
this.draw(canvas);
} catch (OutOfMemoryError error) {
bitmap = toBitmap(radio * 0.9f);
}
return bitmap;
}
public static abstract class ImageCacheClient extends WebViewClient {
// Close streams once webview is detached.
// Or webview would hung up next time.
protected abstract boolean isCancelled();
protected boolean shouldInterceptRequest(String uri) {
return uri.startsWith("http") && (uri.contains(".jpg") || uri.contains(".jpeg") || uri.contains(".png") || uri.contains(".gif"));
}
public abstract boolean shouldDownloadImage();
@Override
public WebResourceResponse shouldInterceptRequest(final WebView view, final String url) {
Logger.i("shouldInterceptRequest");
WebResourceResponse res = null;
if (shouldInterceptRequest(url)) {
UilUtils uil = UilUtils.getInstance();
final File cache = uil.getFile(url);
if (cache == null) {
Logger.t(TAG).e("cache file is null.");
} else if (cache.exists()) {
try {
res = new WebResourceResponse(getMimeType(url), "binary", new FileInputStream(cache));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else if (shouldDownloadImage()) {
try {
final PipedInputStream pipeIn = new PipedInputStream();
final PipedOutputStream pipeOs = new PipedOutputStream(pipeIn);
new Thread(new Runnable() {
@Override
public void run() {
try {
if (isCancelled()) {
pipeOs.close();
return;
}
ImageLoader.getInstance().loadImageSync(url);
InputStream imgIn = new FileInputStream(cache);
byte[] buffer = new byte[1024];
try {
int len = imgIn.read(buffer);
while (len != -1 && !isCancelled()) {
pipeOs.write(buffer, 0, len);
len = imgIn.read(buffer);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
imgIn.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
pipeOs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
pipeOs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
res = new WebResourceResponse(getMimeType(url), "binary", pipeIn);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return res;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return shouldInterceptRequest(view, request.getUrl().toString());
}
protected String getMimeType(String uri) {
if (uri.endsWith(".jpg") && uri.endsWith(".jpeg")) {
return "image/jpeg";
} else if (uri.endsWith(".png")) {
return "image/png";
} else if (uri.endsWith(".gif")) {
return "image/gif";
} else {
return "image/*";
}
}
}
}