当前位置: 移动技术网 > 移动技术>移动开发>Android > Android网页H5 Input选择相机和系统相册

Android网页H5 Input选择相机和系统相册

2019年08月01日  | 移动技术网移动技术  | 我要评论

需求:

网页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;//再进行质量压缩
  }
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网