现在混合开发APP已经
成为了一种趋势,某些功能用H5解决的就用H5来做了,最近遇到一个需求,就是在H5界面里面有一个图片上传功能,还有附件下载功能,安卓的
webView如果不通过一些设置的话是不可以的。下面要说的就是用H5来打开手机的图库,并进行图片上传功能,还有下载功能。
首先是要继承WebChromeClient这个类,WebChromeClient主要辅助WebView处理Javascript的对话框、网站图标、网站title、加载进度等。
-
class MyWebChromeClient extends WebChromeClient {
-
-
-
public void openFileChooser(ValueCallback<Uri> uploadMsg,
-
-
if (mUploadMessage != null)
-
-
mUploadMessage = uploadMsg;
-
selectImage(RESULT_CODE_PICK_FROM_ALBUM_BELLOW_LOLLILOP);
-
-
-
-
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
-
openFileChooser(uploadMsg, "");
-
-
-
-
public void openFileChooser(ValueCallback<Uri> uploadMsg,
-
String acceptType, String capture) {
-
openFileChooser(uploadMsg, acceptType);
-
-
-
-
public boolean onShowFileChooser(WebView webView,
-
ValueCallback<Uri[]> filePathCallback,
-
FileChooserParams fileChooserParams) {
-
mUploadCallbackAboveL = filePathCallback;
-
selectImage(RESULT_CODE_PICK_FROM_ALBUM_ABOVE_LOLLILOP);
-
-
-
-
-
public void onProgressChanged(WebView view, int newProgress) {
-
super.onProgressChanged(view, newProgress);
-
-
openFileChooser和onShowFileChooser方法,当网络上页面点击了<input
type="file"/>的标签时,不同版本的SDK调用openFileChooser或者onShowFileChooser。
选
择完图片后,进入onActivityResult,根据不同的requestCode值区分开AndroidSDK
5.0以上和5.0以下,5.0以下传回Uri对象,5.0以上传回Uri数组。其中处理下onActivityResult传回来的意图数据,将
Intent数据转换乌里分类中翻译。
-
-
-
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-
super.onActivityResult(requestCode, resultCode, data);
-
if (mUploadMessage == null && mUploadCallbackAboveL == null) {
-
-
-
-
-
case RESULT_CODE_PICK_FROM_ALBUM_BELLOW_LOLLILOP:
-
uri = afterChosePic(data);
-
if (mUploadMessage != null) {
-
mUploadMessage.onReceiveValue(uri);
-
-
-
-
case RESULT_CODE_PICK_FROM_ALBUM_ABOVE_LOLLILOP:
-
-
uri = afterChosePic(data);
-
-
mUploadCallbackAboveL.onReceiveValue(new Uri[] { });
-
mUploadCallbackAboveL = null;
-
-
-
if (mUploadCallbackAboveL != null && uri != null) {
-
mUploadCallbackAboveL.onReceiveValue(new Uri[] { uri });
-
mUploadCallbackAboveL = null;
-
-
-
mUploadCallbackAboveL = null;
-
-
-
-
-
-
-
-
-
-
package com.lwd.webviewupimg;
-
-
-
-
import android.annotation.SuppressLint;
-
import android.app.Activity;
-
import android.content.ContentResolver;
-
import android.content.Intent;
-
import android.database.Cursor;
-
import android.graphics.Bitmap;
-
-
import android.os.Bundle;
-
import android.os.Environment;
-
import android.provider.MediaStore.Images.ImageColumns;
-
import android.view.KeyEvent;
-
import android.view.View;
-
import android.webkit.ValueCallback;
-
import android.webkit.WebChromeClient;
-
import android.webkit.WebSettings;
-
import android.webkit.WebSettings.LayoutAlgorithm;
-
import android.webkit.WebView;
-
import android.webkit.WebViewClient;
-
-
-
-
-
-
@SuppressLint("SetJavaScriptEnabled")
-
public class WebViewActivity extends Activity{
-
-
private ValueCallback<Uri> mUploadMessage;
-
private ValueCallback<Uri[]> mUploadCallbackAboveL;
-
private final int RESULT_CODE_PICK_FROM_ALBUM_BELLOW_LOLLILOP = 1;
-
private final int RESULT_CODE_PICK_FROM_ALBUM_ABOVE_LOLLILOP = 2;
-
private String url = "";//这里添加含有图片上传功能的H5页面访问地址即可。
-
String compressPath = "";
-
-
protected void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_welcome);
-
-
-
-
-
webview = (WebView) findViewById(R.id.webview);
-
-
-
-
@SuppressWarnings("deprecation")
-
private void initWebView(){
-
webview.setScrollBarStyle(View.GONE);
-
webview.getSettings().setJavaScriptEnabled(true);
-
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
-
webview.getSettings().setDomStorageEnabled(false);
-
webview.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
-
webview.getSettings().setPluginState(WebSettings.PluginState.ON);
-
webview.getSettings().setAllowFileAccess(true);
-
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
-
webview.getSettings().setLayoutAlgorithm(LayoutAlgorithm.NORMAL);
-
webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
-
webview.getSettings().setUseWideViewPort(true);
-
webview.getSettings().setLoadWithOverviewMode(true);
-
webview.getSettings().setAllowContentAccess(true);
-
-
webview.setWebViewClient(new WebClient());
-
webview.setWebChromeClient(new MyWebChromeClient());
-
-
-
-
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-
super.onActivityResult(requestCode, resultCode, data);
-
if (mUploadMessage == null && mUploadCallbackAboveL == null) {
-
-
-
-
-
case RESULT_CODE_PICK_FROM_ALBUM_BELLOW_LOLLILOP:
-
uri = afterChosePic(data);
-
if (mUploadMessage != null) {
-
mUploadMessage.onReceiveValue(uri);
-
-
-
-
case RESULT_CODE_PICK_FROM_ALBUM_ABOVE_LOLLILOP:
-
-
uri = afterChosePic(data);
-
-
mUploadCallbackAboveL.onReceiveValue(new Uri[] { });
-
mUploadCallbackAboveL = null;
-
-
-
if (mUploadCallbackAboveL != null && uri != null) {
-
mUploadCallbackAboveL.onReceiveValue(new Uri[] { uri });
-
mUploadCallbackAboveL = null;
-
-
-
mUploadCallbackAboveL = null;
-
-
-
-
-
-
-
-
-
-
private Uri afterChosePic(Intent data) {
-
-
-
-
String path = getRealFilePath(data.getData());
-
String[] names = path.split("\\.");
-
-
-
endName = names[names.length - 1];
-
-
-
compressPath = compressPath.split("\\.")[0] + "." + endName;
-
-
-
-
newFile = FileUtils.compressFile(path, compressPath);
-
-
-
-
return Uri.fromFile(newFile);
-
-
-
-
-
public String getRealFilePath(final Uri uri) {
-
-
-
-
final String scheme = uri.getScheme();
-
-
-
-
} else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
-
-
} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
-
Cursor cursor = getContentResolver().query(uri,
-
new String[] { ImageColumns.DATA }, null, null, null);
-
-
if (cursor.moveToFirst()) {
-
int index = cursor.getColumnIndexOrThrow(ImageColumns.DATA);
-
-
data = cursor.getString(index);
-
-
-
-
-
-
-
-
-
public void onBackPressed() {
-
-
-
-
-
-
-
-
private class WebClient extends WebViewClient {
-
-
-
public void onPageStarted(WebView view, String url, Bitmap favicon) {
-
super.onPageStarted(view, url, favicon);
-
-
-
-
public boolean shouldOverrideUrlLoading(WebView view, String url) {
-
-
-
-
-
-
public void onPageFinished(WebView view, String url) {
-
super.onPageFinished(view, url);
-
-
-
-
public boolean onKeyDown(int keyCode, KeyEvent event) {
-
if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
-
-
-
-
return super.onKeyDown(keyCode, event);
-
-
/**打开图库,同时
处理图片(项目业务需要统一命名)*/
-
private void selectImage(int resultCode) {
-
compressPath = Environment.getExternalStorageDirectory().getPath() + "/QWB/temp";
-
File file = new File(compressPath);
-
-
-
-
compressPath = compressPath + File.separator + "compress.png";
-
File image = new File(compressPath);
-
-
-
-
Intent intent = new Intent(
-
Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
-
startActivityForResult(intent, resultCode);
-
-
-
-
-
-
class MyWebChromeClient extends WebChromeClient {
-
//openFileChooser(隐藏方法)仅适用
android5.0以下的环境,android5.0及以上使用onShowFileChooser
-
-
-
public void openFileChooser(ValueCallback<Uri> uploadMsg,
-
-
if (mUploadMessage != null)
-
-
mUploadMessage = uploadMsg;
-
selectImage(RESULT_CODE_PICK_FROM_ALBUM_BELLOW_LOLLILOP);
-
-
-
-
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
-
openFileChooser(uploadMsg, "");
-
-
-
-
public void openFileChooser(ValueCallback<Uri> uploadMsg,
-
String acceptType, String capture) {
-
openFileChooser(uploadMsg, acceptType);
-
-
-
-
public boolean onShowFileChooser(WebView webView,
-
ValueCallback<Uri[]> filePathCallback,
-
FileChooserParams fileChooserParams) {
-
mUploadCallbackAboveL = filePathCallback;
-
selectImage(RESULT_CODE_PICK_FROM_ALBUM_ABOVE_LOLLILOP);
-
-
-
-
-
public void onProgressChanged(WebView view, int newProgress) {
-
super.onProgressChanged(view, newProgress);
-
-
-
-
-
package com.lwd.webviewupimg;
-
-
import java.io.BufferedOutputStream;
-
import java.io.ByteArrayOutputStream;
-
-
import java.io.FileOutputStream;
-
import java.io.IOException;
-
-
import android.graphics.Bitmap;
-
import android.graphics.Bitmap.CompressFormat;
-
import android.graphics.Bitmap.Config;
-
import android.graphics.BitmapFactory;
-
import android.graphics.Matrix;
-
import android.media.ExifInterface;
-
import android.text.TextUtils;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
public static File compressFile(String oldpath, String newPath) {
-
Bitmap compressBitmap = FileUtils.decodeFile(oldpath);
-
Bitmap newBitmap = ratingImage(oldpath, compressBitmap);
-
ByteArrayOutputStream os = new ByteArrayOutputStream();
-
newBitmap.compress(CompressFormat.PNG, 100, os);
-
byte[] bytes = os.toByteArray();
-
-
-
-
file = FileUtils.getFileFromBytes(bytes, newPath);
-
-
-
-
-
if(!newBitmap.isRecycled()){
-
-
-
-
-
if(compressBitmap != null ){
-
if(!compressBitmap.isRecycled()){
-
compressBitmap.recycle();
-
-
-
-
-
-
-
-
private static Bitmap ratingImage(String filePath,Bitmap bitmap){
-
int degree = readPictureDegree(filePath);
-
return rotaingImageView(degree, bitmap);
-
-
-
-
-
-
-
-
-
public static Bitmap rotaingImageView(int angle , Bitmap bitmap) {
-
-
Matrix matrix = new Matrix();;
-
matrix.postRotate(angle);
-
System.out.println("angle2=" + angle);
-
-
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
-
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
-
-
-
-
-
-
-
-
-
public static int readPictureDegree(String path) {
-
-
-
ExifInterface exifInterface = new ExifInterface(path);
-
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
-
-
case ExifInterface.ORIENTATION_ROTATE_90:
-
-
-
case ExifInterface.ORIENTATION_ROTATE_180:
-
-
-
case ExifInterface.ORIENTATION_ROTATE_270:
-
-
-
-
} catch (IOException e) {
-
-
-
-
-
-
-
-
-
-
-
-
-
public static File getFileFromBytes(byte[] b, String outputFile) {
-
-
BufferedOutputStream stream = null;
-
-
ret = new File(outputFile);
-
FileOutputStream fstream = new FileOutputStream(ret);
-
stream = new BufferedOutputStream(fstream);
-
-
-
// log.error("helper:get file from byte process error!");
-
-
-
-
-
-
} catch (IOException e) {
-
// log.error("helper:get file from byte process error!");
-
-
-
-
-
-
-
-
-
-
-
-
-
-
public static Bitmap decodeFile(String fPath) {
-
BitmapFactory.Options opts = new BitmapFactory.Options();
-
opts.inJustDecodeBounds = true;
-
opts.inDither = false; // Disable Dithering mode
-
opts.inPurgeable = true; // Tell to gc that whether it needs free
-
opts.inInputShareable = true; // Which kind of reference will be used to
-
BitmapFactory.decodeFile(fPath, opts);
-
final int REQUIRED_SIZE = 200;
-
-
if (opts.outHeight > REQUIRED_SIZE || opts.outWidth > REQUIRED_SIZE) {
-
final int heightRatio = Math.round((float) opts.outHeight
-
/ (float) REQUIRED_SIZE);
-
final int widthRatio = Math.round((float) opts.outWidth
-
/ (float) REQUIRED_SIZE);
-
scale = heightRatio < widthRatio ? heightRatio : widthRatio;//
-
-
Log.i("scale", "scal ="+ scale);
-
opts.inJustDecodeBounds = false;
-
opts.inSampleSize = scale;
-
Bitmap bm = BitmapFactory.decodeFile(fPath, opts).copy(Config.ARGB_8888, false);
-
-
-
-
-
-
-
-
-
-
public static void setMkdir(String path)
-
-
File file = new File(path);
-
-
-
-
Log.e("file", "目录不存在 创建目录 ");
-
-
-
-
-
-
-
-
-
-
-
public static String getFileName(String url)
-
-
int lastIndexStart = url.lastIndexOf("/");
-
-
-
return url.substring(lastIndexStart+1, url.length());
-
-
-
-
-
-
-
-
-
-
-
public static void delFile(String path) {
-
if (!TextUtils.isEmpty(path)) {
-
File file = new File(path);
-
-
-
-
-
-
上面介绍了webView的上传,下面来介绍一下WebView的下载功能,
WebView
控制调用相应的WEB页面进行展示。当碰到页面有下载链接的时候,点击上去是一点反应都没有的。原来是因为WebView默认没有开启文件下载的功能,如
果要实现文件下载的功能,需要设置WebView的DownloadListener,通过实现自己的DownloadListener来实现文件的下
载。具体操作如下:
1、设置WebView的DownloadListener:
webView.setDownloadListener(new MyWebViewDownLoadListener());
2、实现MyWebViewDownLoadListener这个类,具体可以如下这样:
-
private class MyWebViewDownLoadListener implements DownloadListener{
-
-
-
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,
-
-
Log.i("tag", "url="+url);
-
Log.i("tag", "userAgent="+userAgent);
-
Log.i("tag", "contentDisposition="+contentDisposition);
-
Log.i("tag", "mimetype="+mimetype);
-
Log.i("tag", "contentLength="+contentLength);
-
Uri uri = Uri.parse(url);
-
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-
-
-
这只是调用系统中已经内置的浏览器进行下载,还没有WebView本身进行的文件下载,不过,这也基本上满足我们的应用场景了。
我在项目中的运用
项目要求这样:
1,需要使用WebView加载一个网页;
2,网页中有文件下载的链接,点击后需要下载文件到SDcard;
3,然后自动打开文件;
下面是具体解决办法
第一步,对WebView进行一系列设置。
-
WebView webview=(WebView)layout.findViewById(R.id.webview);
-
webview.getSettings().setJavaScriptEnabled(true);
-
webview.setWebChromeClient(new MyWebChromeClient());
-
-
-
webview.loadUrl(jcrs_sub.get(position).addr);
-
-
webview.setWebViewClient(new MyWebViewClient());
-
webview.setDownloadListener(new MyWebViewDownLoadListener());
-
-
-
public class MyWebViewClient extends WebViewClient {
-
-
-
public boolean shouldOverviewUrlLoading(WebView view, String url) {
-
L.i("shouldOverviewUrlLoading");
-
-
-
-
-
public void onPageStarted(WebView view, String url, Bitmap favicon) {
-
-
-
-
-
public void onPageFinished(WebView view, String url) {
-
-
-
-
-
public void onReceivedError(WebView view, int errorCode,
-
String description, String failingUrl) {
-
-
-
-
-
-
-
-
public boolean onKeyDown(int keyCode, KeyEvent event) {
-
-
-
-
-
-
-
-
private class MyWebViewDownLoadListener implements DownloadListener {
-
-
-
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,
-
-
if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
-
Toast t=Toast.makeText(mContext, "需要SD卡。", Toast.LENGTH_LONG);
-
t.setGravity(Gravity.CENTER, 0, 0);
-
-
-
-
DownloaderTask task=new DownloaderTask();
-
-
-
-
-
-
private class DownloaderTask extends AsyncTask<String, Void, String> {
-
-
public DownloaderTask() {
-
-
-
-
protected String doInBackground(String... params) {
-
-
-
-
String fileName=url.substring(url.lastIndexOf("/")+1);
-
fileName=URLDecoder.decode(fileName);
-
Log.i("tag", "fileName="+fileName);
-
-
File directory=Environment.getExternalStorageDirectory();
-
File file=new File(directory,fileName);
-
-
Log.i("tag", "The file has already exists.");
-
-
-
-
HttpClient client = new DefaultHttpClient();
-
-
HttpGet get = new HttpGet(url);
-
HttpResponse response = client.execute(get);
-
if(HttpStatus.SC_OK==response.getStatusLine().getStatusCode()){
-
HttpEntity entity = response.getEntity();
-
InputStream input = entity.getContent();
-
-
writeToSDCard(fileName,input);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
protected void onCancelled() {
-
-
-
-
-
-
protected void onPostExecute(String result) {
-
-
super.onPostExecute(result);
-
-
-
Toast t=Toast.makeText(mContext, "连接错误!请稍后再试!", Toast.LENGTH_LONG);
-
t.setGravity(Gravity.CENTER, 0, 0);
-
-
-
-
-
Toast t=Toast.makeText(mContext, "已保存到SD卡。", Toast.LENGTH_LONG);
-
t.setGravity(Gravity.CENTER, 0, 0);
-
-
File directory=Environment.getExternalStorageDirectory();
-
File file=new File(directory,result);
-
Log.i("tag", "Path="+file.getAbsolutePath());
-
-
Intent intent = getFileIntent(file);
-
-
-
-
-
-
-
protected void onPreExecute() {
-
-
-
-
-
-
-
protected void onProgressUpdate(Void... values) {
-
-
super.onProgressUpdate(values);
-
-
-
-
经过上面的操作就完成了webView的上传和下载功能了。本人亲自测试过了,是有效果的,