Android网页H5 Input选择相机和系统相册
程序员文章站
2022-06-04 12:19:18
需求:
网页h5的input选择相机和系统相册,并且返回压缩的图片到h5。
代码:
1、webview代码
package com.zql.sdk;...
需求:
网页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.javascriptinterface; 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.onclicklistener { 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_title; private textview tv_title; 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_title);//去掉标题栏 setcontentview(r.layout.activity_web_view); tv_back_title = (textview) findviewbyid(r.id.tv_back_title); tv_title = (textview) findviewbyid(r.id.tv_title); iv_back = (imageview) findviewbyid(r.id.iv_back); tv_right = (textview) findviewbyid(r.id.tv_right); iv_back.setonclicklistener(this); tv_back_title.setonclicklistener(this); tv_right.setonclicklistener(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" + // " <meta charset=\"utf-8\">\n" + // " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1,maximum-scale=1,user-scalable=no\">\n" + // " <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n" + // " <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black\">\n" + // " <title>修改资料</title>\n" + // " <script src=\"./jquery-1.8.3.js\"></script>\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" + // "<script> \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.onload = (e) => {\n" + // " $('#imgshow').attr('src', e.target.result);\n" + // " };\n" + // " };\n" + // " };\n" + // "</script>\n" + // "</body>\n" + // "</html>"; // // log.e("网页", htmldata); // // wvshow.loaddatawithbaseurl(null, htmldata, "text/html", "utf-8", null); } private void initview() { wvshow = (webview) findviewbyid(r.id.wv_body); wvshow.getsettings().setjavascriptenabled(true);//允许与js 交互 wvshow.getsettings().setdefaulttextencodingname("utf-8");//支持中文 //在js中调用本地java方法 wvshow.addjavascriptinterface(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 onreceivedtitle(webview view, string title) { super.onreceivedtitle(view, title); tv_title.settext(title); } 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 onclick(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_title) { finish(); } } /** * js调用原生方法 */ private class jsinterface { private context mcontext; public jsinterface(context context) { this.mcontext = context; } @javascriptinterface public void closeh5(string name) {//关闭sdk log.e("网页", "方法入参:" + name); finish(); } @javascriptinterface 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的onkeydown事件,判断当用户按下“返回”按钮,webview返回上一页 @override public boolean onkeydown(int keycode, keyevent event) { if ((keycode == keyevent.keycode_back) && wvshow.cangoback()) { wvshow.goback(); return true; } else { finish(); } return super.onkeydown(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.database.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).settitle("上传头像")//设置对话框标题 .setpositivebutton("拍照", new dialoginterface.onclicklistener() {//添加确定按钮 @requiresapi(api = build.version_codes.m) @override public void onclick(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.onclicklistener() { @override public void onclick(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;//再进行质量压缩 } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。