需求:
网页h5的input选择相机和系统相册,并且返回压缩的图片到h5。
代码:
1、WebView代码
package com.zql.sdk;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.webkit. Interface;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
/**
* 浏览器组件
* Created by zst on 2018/5/16.
*/
public class WebViewActivity extends Activity implements View. Listener {
public static final String INTENT_URL = \"intent_url\";//请求连接
public static final String INTENT_PARAMS_STRING = \"intent_params_string\";//请求参数字符串
public static final String INTENT_REQUEST_WAY = \"intent_request_way\";//请求方式(POST/GET)
private WebView wvShow;
private TextView tv_back_ ;
private TextView tv_ ;
private ImageView iv_back;
private TextView tv_right;
public ValueCallback<Uri[]> uploadMessage;
private ValueCallback<Uri> mUploadMessage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_ );//去掉标题栏
setContentView(R.layout.activity_web_view);
tv_back_ = (TextView) findViewById(R.id.tv_back_ );
tv_ = (TextView) findViewById(R.id.tv_ );
iv_back = (ImageView) findViewById(R.id.iv_back);
tv_right = (TextView) findViewById(R.id.tv_right);
iv_back.set Listener(this);
tv_back_ .set Listener(this);
tv_right.set Listener(this);
initView();
initData();
}
private void initData() {
String intentUrl = getIntent().getStringExtra(INTENT_URL);
String intentParams = getIntent().getStringExtra(INTENT_PARAMS_STRING);
String intentRequestWay = getIntent().getStringExtra(INTENT_REQUEST_WAY);
Log.e(\"WebView请求\", \"连接:\" + intentUrl + \".....\" + \"参数:\" + intentParams);
if (intentRequestWay.equals(\"GET\")) {
wvShow.loadUrl(intentUrl + \"?\" + intentParams);//get请求
} else if (intentRequestWay.equals(\"POST\")) {
wvShow.postUrl(intentUrl, intentParams.getBytes());//post请求
} else {
Toast.makeText(WebViewActivity.this, \"请求方式参数错误\", Toast.LENGTH_SHORT).show();
}
//// wvShow.loadUrl(\"http://qas-gw.baofoo.com/merchant_page?CODE=6d8950fc495c2a63106ce45d2647e21aec04001b53b3d7aac2f8af3b3d24f84a6c51c92843814b270eb28ead11820178fad5a20a7278f042\");//get请求
//
// String htmlData = \"<!DOCTYPE html>\\n\" +
// \"<html>\\n\" +
// \"<head>\\n\" +
// \" < charset=\\\"utf-8\\\">\\n\" +
// \" < name=\\\"viewport\\\" content=\\\"width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no\\\">\\n\" +
// \" < name=\\\"apple-mobile-web-app-capable\\\" content=\\\"yes\\\">\\n\" +
// \" < name=\\\"apple-mobile-web-app-status-bar-style\\\" content=\\\"black\\\">\\n\" +
// \" < >修改资料</ >\\n\" +
// \" < src=\\\"./jquery-1.8.3.js\\\"></ >\\n\" +
// \"</head>\\n\" +
// \"\\n\" +
// \"<body>\\n\" +
// \" <div className=\\\"image-uploader\\\">\\n\" +
// \" <input id=\\\"imgInput\\\" className=\\\"imgInput\\\" type=\\\"file\\\" accept=\\\"image/*\\\" />\\n\" +
// \" <img id=\\\"imgShow\\\" className=\\\"imgShow\\\" />\\n\" +
// \" </div>\\n\" +
// \"\\n\" +
// \"< > \\n\" +
// \" $(\'#imgInput\').change(function () {\\n\" +
// \" readURL(this);\\n\" +
// \"});\\n\" +
// \"\\n\" +
// \"function readURL(input){\\n\" +
// \" if (input.files && input.files[0]) {\\n\" +
// \" const reader = new FileReader();\\n\" +
// \" reader.readAsDataURL(input.files[0]);\\n\" +
// \" reader. = (e) => {\\n\" +
// \" $(\'#imgShow\').attr(\'src\', e.target.result);\\n\" +
// \" };\\n\" +
// \" };\\n\" +
// \" };\\n\" +
// \"</ >\\n\" +
// \"</body>\\n\" +
// \"</html>\";
//
// Log.e(\"网页\", htmlData);
//
// wvShow.loadDataWith URL(null, htmlData, \"text/html\", \"utf-8\", null);
}
private void initView() {
wvShow = (WebView) findViewById(R.id.wv_body);
wvShow.getSettings().set Enabled(true);//允许与js 交互
wvShow.getSettings().setDefaultTextEncodingName(\"utf-8\");//支持中文
//在js中调用本地java方法
wvShow.add Interface(new JsInterface(this), \"androidYZH\");
wvShow.getSettings().setDomStorageEnabled(true);//允许缓存、开启DOM(双重重定向白屏问题)
wvShow.setWebViewClient(new WebViewClient() {
//覆盖shouldOverrideUrlLoading 方法
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url == null) return false;
try {
if (url.startsWith(\"http:\") || url.startsWith(\"https:\")) {
view.loadUrl(url);
return true;
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
} catch (Exception e) { //防止crash (如果手机上没有安装处理某个scheme开头的url的APP, 会导致crash)
return false;
}
}
});
wvShow.setWebChromeClient(new WebChromeClient() {//监听网页加载
@Override
public void onProgressChanged(WebView view, int newProgress) {
// if (newProgress == 100) {
// // 网页加载完成
// pbProgress.setVisibility(View.GONE);
// } else {
// // 加载中
// pbProgress.setProgress(newProgress);
// }
super.onProgressChanged(view, newProgress);
}
@Override
public void onReceived (WebView view, String ) {
super.onReceived (view, );
tv_ .setText( );
}
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
Log.e(\"点击\", \"1\");
ImgUtil.choicePhoto(WebViewActivity.this);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
openFileChooser(uploadMsg);
Log.e(\"点击\", \"3\");
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg);
Log.e(\"点击\", \"4\");
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
if (uploadMessage != null) {
uploadMessage.onReceiveValue(null);
uploadMessage = null;
}
uploadMessage = filePathCallback;
Log.e(\"点击\", \"2\");
ImgUtil.choicePhoto(WebViewActivity.this);
return true;
}
});
}
@Override
public void (View v) {
int i = v.getId();
if (i == R.id.iv_back) {
if (wvShow.canGoBack()) {
wvShow.goBack();
} else {
finish();
}
} else if (i == R.id.tv_back_ ) {
finish();
}
}
/**
* js调用原生方法
*/
private class JsInterface {
private Context mContext;
public JsInterface(Context context) {
this.mContext = context;
}
@ Interface
public void closeH5(String name) {//关闭sdk
Log.e(\"网页\", \"方法入参:\" + name);
finish();
}
@ Interface
public void downloadFile(String name) {//下载文件
Log.e(\"网页\", \"方法入参:\" + name);
//这里是把地址用默认浏览器打开,在浏览器中下载
Uri uri = Uri.parse(name);
Intent intent = new Intent();
intent.setAction(\"android.intent.action.VIEW\");
intent.setData(uri);
startActivity(intent);
}
}
//重写Activity的 事件,判断当用户按下“返回”按钮,webview返回上一页
@Override
public boolean (int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && wvShow.canGoBack()) {
wvShow.goBack();
return true;
} else {
finish();
}
return super. (keyCode, event);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == RESULT_OK) {//正确返回
switch (requestCode) {
case ImgUtil.TAKE_PHOTO://相机返回
Log.e(\"返回相机\", ImgUtil.imageUri.toString());
//相机返回rui
//Uri uriTake = ImgUtil.imageUri;
Uri uriTake = null;
try {
uriTake = ImgUtil.getCompressUri(WebViewActivity.this, ImgUtil.imageUri);
} catch (IOException e) {
e.printStackTrace();
}
//显示在页面
if (uploadMessage == null) return;
Uri[] imgTaskUris = {uriTake};
uploadMessage.onReceiveValue(imgTaskUris);
uploadMessage = null;
if (null == mUploadMessage) return;
Uri result = intent == null || resultCode != MainActivity.RESULT_OK ? null : uriTake;
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
break;
case ImgUtil.CHOOSE_PHOTO://相册返回
try {
if (intent != null) {
//相册返回
Log.e(\"返回\", \"intent2:\" + intent.getData().toString() + \"...\" + uploadMessage);
//相册返回uri
//Uri uriChoose = intent.getData();
Uri uriChoose = ImgUtil.getCompressUri(WebViewActivity.this, intent.getData());
//显示在页面
if (uploadMessage == null) return;
Uri[] imgChooseUris = {uriChoose};
uploadMessage.onReceiveValue(imgChooseUris);
//uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent));
uploadMessage = null;
Log.e(\"返回\", \"intent3:\" + WebChromeClient.FileChooserParams.parseResult(resultCode, intent).toString());
}
break;
} catch (Exception e) {
e.printStackTrace();
UiUtil.showToast(this, \"图片选择失败\");
}
break;
}
} else {
UiUtil.showToast(this, \"图片选择失败\");
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case ImgUtil.REQUEST_CODE_ALBUM://相册存储权限
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
ImgUtil.openAlbum(this);
} else {
UiUtil.showToast(this, \"选择图库需要同意权限\");
}
break;
case ImgUtil.REQUEST_CODE_CAMERA://相机拍照权限
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {//允许
ImgUtil.openCamera(WebViewActivity.this);
} else {//拒绝
UiUtil.showToast(this, \"只有同意相机权限,才能使用扫码功能\");
}
break;
default:
}
}
}
2、ImgUtil.java工具类
1)、选择相机方法(选择相机的方法还有额外的代码,具体点击这里)
2)、选择相册方法
3)、压缩图片方法
package com.zql.sdk;
import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.data .Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.widget.Toast;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* 图片工具类
* Created by xiaoshuai on 2018/8/17.
*/
public class ImgUtil {
public static final int TAKE_PHOTO = 1;//拍照
public static final int CHOOSE_PHOTO = 2;//选择相册
public static final int REQUEST_CODE_CAMERA = 3;//相机权限请求
public static final int REQUEST_CODE_ALBUM = 4;//相册权限请求
public static Uri imageUri;//相机拍照图片保存地址
/**
* 选择图片,从图库、相机
*
* @param activity 上下文
*/
public static void choicePhoto(final Activity activity) {
//采用的是系统Dialog作为选择弹框
new AlertDialog.Builder(activity).set (\"上传头像\")//设置对话框标题
.setPositiveButton(\"拍照\", new DialogInterface. Listener() {//添加确定按钮
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void (DialogInterface dialog, int which) {
ArrayList<String> permissions = new ArrayList<>();
if (activity.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
permissions.add(Manifest.permission.CAMERA);
}
if (permissions.size() == 0) {//有权限,跳转
//打开相机-兼容7.0
ImgUtil.openCamera(activity);
} else {
activity.requestPermissions(permissions.toArray(new String[permissions.size()]), REQUEST_CODE_CAMERA);
}
// if (Build.VERSION.SDK_INT >= 23) {//检查相机权限
// ArrayList<String> permissions = new ArrayList<>();
// if (activity.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
// permissions.add(Manifest.permission.CAMERA);
// }
//
// if (permissions.size() == 0) {//有权限,跳转
// //打开相机-兼容7.0
// openCamera(activity);
// } else {
// activity.requestPermissions(permissions.toArray(new String[permissions.size()]), REQUEST_CODE_CAMERA);
// }
// } else {
// //打开相机-兼容7.0
// openCamera(activity);
// }
}
}).
setNegativeButton(\"系统相册\", new DialogInterface. Listener() {
@Override
public void (DialogInterface dialog, int which) {
//如果有权限申请,请在Activity中onRequestPermissionsResult权限返回里面重新调用openAlbum()
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_ALBUM);
} else {
openAlbum(activity);
}
}
}).show();//在按键响应事件中显示此对话框
}
/**
* 打开相机
* 兼容7.0
*
* @param activity
*/
public static void openCamera(Activity activity) {
// 创建File对象,用于存储拍照后的图片
File outputImage = new File(activity.getExternalCacheDir(), \"output_image.jpg\");
try {
if (outputImage.exists()) {
outputImage.delete();
}
outputImage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
if (Build.VERSION.SDK_INT < 24) {
imageUri = Uri.fromFile(outputImage);
} else {
//Android 7.0系统开始 使用本地真实的Uri路径不安全,使用FileProvider封装共享Uri
//参数二:fileprovider绝对路径 com.dyb.testcamerademo:项目包名
imageUri = FileProvider.getUriForFile(activity, \"com.zql.sdk.fileprovider\", outputImage);
}
// 启动相机程序
Intent intent = new Intent(\"android.media.action.IMAGE_CAPTURE\");
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
activity.startActivityForResult(intent, TAKE_PHOTO);
}
/**
* 打开图库
* @param activity
*/
public static void openAlbum(Activity activity) {
//调用系统图库的意图
Intent choosePicIntent = new Intent(Intent.ACTION_PICK, null);
choosePicIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, \"image/*\");
activity.startActivityForResult(choosePicIntent, CHOOSE_PHOTO);
//打开系统默认的软件
//Intent intent = new Intent(\"android.intent.action.GET_CONTENT\");
//intent.setType(\"image/*\");
//activity.startActivityForResult(intent, CHOOSE_PHOTO); // 打开相册
}
/**
* 通过uri获取路径filepath
* @param context
* @param uri
* @return
*/
public static String getFilePath( final Context context, final Uri uri ) {
if ( null == uri ) return null;
final String scheme = uri.getScheme();
String data = null;
if ( scheme == null )
data = uri.getPath();
else if ( ContentResolver.SCHEME_FILE.equals( scheme ) ) {
data = uri.getPath();
} else if ( ContentResolver.SCHEME_CONTENT.equals( scheme ) ) {
Cursor cursor = context.getContentResolver().query( uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null );
if ( null != cursor ) {
if ( cursor.moveToFirst() ) {
int index = cursor.getColumnIndex( MediaStore.Images.ImageColumns.DATA );
if ( index > -1 ) {
data = cursor.getString( index );
}
}
cursor.close();
}
}
return data;
}
/**
* 得到byte[]
* LeanCloud上传文件是需要byte[]数组的
* 这里对传入的图片Uri压缩,并转换为byte[]后返回
*
* @param activity 上下文
* @param uri 传入图片的Uri
* @return byte[]
*/
public static byte[] getImgByteFromUri(Activity activity, Uri uri) throws IOException {
//先进行尺寸压缩
Bitmap bitmap = getBitmapFormUri(activity, uri);
//再进行质量压缩
ByteArrayOutputStream out = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);//100表示不压缩,直接放到out里面
int options = 90;//压缩比例
while (out.toByteArray().length / 1024 > 200) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
out.reset(); // 重置baos即清空baos
bitmap.compress(Bitmap.CompressFormat.JPEG, options, out);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;// 每次都减少10
}
Log.e(\"压缩-提交\", out.toByteArray().length + \"\");
byte[] bs = out.toByteArray();//转换为byte提交
return bs;
}
public static Uri getCompressUri(Activity activity, Uri uri) throws IOException {
//先进行尺寸压缩
Bitmap bitmap = getBitmapFormUri(activity, uri);
Uri uriCompress = Uri.parse(MediaStore.Images.Media.insertImage(activity.getContentResolver(), bitmap, null,null));
// //再进行质量压缩
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);//100表示不压缩,直接放到out里面
// int options = 90;//压缩比例
// while (out.toByteArray().length / 1024 > 200) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
// out.reset(); // 重置baos即清空baos
// bitmap.compress(Bitmap.CompressFormat.JPEG, options, out);// 这里压缩options%,把压缩后的数据存放到baos中
// options -= 10;// 每次都减少10
// }
// Log.e(\"压缩-提交\", out.toByteArray().length + \"\");
//
// byte[] bs = out.toByteArray();//转换为byte提交
return uriCompress;
}
/**
* 图片尺寸压缩
*
* 宽度高度不一样:依靠规定的高或宽其一最大值来做界限
* 高度宽度一样:依照规定的宽度压缩
*
* @param uri
*/
public static Bitmap getBitmapFormUri(Activity ac, Uri uri) throws FileNotFoundException, IOException {
InputStream input = ac.getContentResolver().openInputStream(uri);
BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
onlyBoundsOptions.inJustDecodeBounds = true;
onlyBoundsOptions.inDither = true;//optional
onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional
BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
input.close();
int originalWidth = onlyBoundsOptions.outWidth;
int originalHeight = onlyBoundsOptions.outHeight;
if ((originalWidth == -1) || (originalHeight == -1))
return null;
//图片分辨率以750x450为标准
float hh = 800f;//这里设置高度为750f
float ww = 800f;//这里设置宽度为450f
float sq = 800f;//这里设置正方形为300f
//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
Log.e(\"缩放\", originalWidth + \"...\" + originalHeight);
int be = 1;//be=1表示不缩放
if (originalWidth > originalHeight && originalWidth > ww) {//如果宽度大,根据宽度固定大小缩放
be = (int) (originalWidth / ww);
} else if (originalWidth < originalHeight && originalHeight > hh) {//如果高度高,根据宽度固定大小缩放
be = (int) (originalHeight / hh);
} else if (originalWidth == originalHeight && originalWidth > sq) {//如果高度和宽度一样,根据任意一边大小缩放
//be = (int) (originalHeight / sq);
be = (int) (originalWidth / sq);
}
if (be <= 0) {//如果缩放比比1小,那么保持原图不缩放
be = 1;
}
Log.e(\"缩放\", be + \"\");
//比例压缩
BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
bitmapOptions.inSampleSize = be;//设置缩放比例
bitmapOptions.inDither = true;//optional
bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optional
input = ac.getContentResolver().openInputStream(uri);
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
input.close();
return bitmap;//再进行质量压缩
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
继续阅读与本文标签相同的文章
上一篇 :
一步一步跟我学易语言之变量的有效范围
-
Axure RP 9 For Mac软件安装教程
2026-05-18栏目: 教程
-
功能超多还不占内存,果然浓缩的都是精华!
2026-05-18栏目: 教程
-
PC端如何不再窗口切换、实现沉浸式资料收集?
2026-05-18栏目: 教程
-
不蒸馒头争口气,哈弗H6、博越这些国产SUV让合资品牌不得不忌惮
2026-05-18栏目: 教程
-
中国移动向携号转网妥协,必须满足这一条件,网友:套路太深!
2026-05-18栏目: 教程
