Android 网页h5 Input选择相机和系统相册
生活随笔
收集整理的這篇文章主要介紹了
Android 网页h5 Input选择相机和系统相册
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
需求:
網頁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;@Overrideprotected 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 方法@Overridepublic 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() {//監聽網頁加載@Overridepublic void onProgressChanged(WebView view, int newProgress) { // if (newProgress == 100) { // // 網頁加載完成 // pbProgress.setVisibility(View.GONE); // } else { // // 加載中 // pbProgress.setProgress(newProgress); // }super.onProgressChanged(view, newProgress);}@Overridepublic 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;}});}@Overridepublic 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;}@JavascriptInterfacepublic void closeH5(String name) {//關閉sdkLog.e("網頁", "方法入參:" + name);finish();}@JavascriptInterfacepublic 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返回上一頁@Overridepublic 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)@Overrideprotected 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, "圖片選擇失敗");}}@Overridepublic 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)@Overridepublic 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.0ImgUtil.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() {@Overridepublic 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即清空baosbitmap.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;//optionalonlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optionalBitmapFactory.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;//這里設置高度為750ffloat ww = 800f;//這里設置寬度為450ffloat 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;//optionalbitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//optionalinput = ac.getContentResolver().openInputStream(uri);Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);input.close();return bitmap;//再進行質量壓縮}}?
總結
以上是生活随笔為你收集整理的Android 网页h5 Input选择相机和系统相册的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python字符串去除空格,python
- 下一篇: 互联网日报 | 宝马iX3正式中国首发亮