Android WebView 選擇圖片並上傳(呼叫相機拍照/相簿/選擇檔案)
阿新 • • 發佈:2019-02-14
前言:
這個功能其實我才剛接觸。不熟...在這個給大家提供的都是經過本人驗證之後的一些案例。可以在專案中跑的。
最近專案嵌入混合開發,都是使用WebView來跳轉,頁面展示。有用到這個圖片上傳的功能。
原本是一臉懵的,查了很多資料看一些大神都寫的很多程式碼很複雜(原諒我是小白)
正文:
先看一下效果先:
程式碼:
我這裡程式碼都是寫在Fragment裡面的 直接看 initWeb()方法就好了
/** * Created by WL-鬼 on 2017/7/10. */ public class WebFragment extends BaseFragment { private String webUrl = APIConstants.WEB_ROOT + "index.php"; private static volatile WebFragment webFragment; @BindView(R.id.h5WebView) WebView h5WebView; @BindView(R.id.tribal_web_progressbar) ProgressBar webProgressBar; public ValueCallback<Uri[]> mUploadMessageForAndroid5; public ValueCallback<Uri> mUploadMessage; public final static int FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5 = 2; private final static int FILE_CHOOSER_RESULT_CODE = 1;// 表單的結果回撥 private Uri imageUri; @Override public int getLayoutRes() { return R.layout.fragment_web; } @Override public void init(Bundle savedInstanceState) { initWeb(); } @Override public void initEvent() { } // 初始化webview @SuppressLint("SetJavaScriptEnabled") private void initWeb() { WebSettings mWebSettings = h5WebView.getSettings(); mWebSettings.setJavaScriptEnabled(true); //允許載入javaScript mWebSettings.setSupportZoom(true); //是否允許縮放 mWebSettings.setUseWideViewPort(true); //設定載入進來的頁面自適應手機螢幕 mWebSettings.setLoadWithOverviewMode(true); mWebSettings.setCacheMode(WebSettings.LOAD_DEFAULT); mWebSettings.setRenderPriority(WebSettings.RenderPriority.HIGH); h5WebView.canGoBack(); h5WebView.loadUrl(webUrl); //H5載入連結監聽 h5WebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { Intent intent = null; //根據攔截的url來判斷是否攔截跳轉 if (url.contains("test")) { intent = new Intent(getContext(), Test.class); } else if (url.contains("returnBackController")) { ... }else if (url.contains("....")) { h5WebView.loadUrl("javascript:reload()"); }else { h5WebView.loadUrl(webUrl); } if (intent != null){ startActivity(intent); } return true; } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); } }); //H5介面載入進度監聽 h5WebView.setWebChromeClient(new WebChromeClient(){ @Override public void onProgressChanged(WebView view, int newProgress) { if (webProgressBar != null){ if (newProgress > 95){ webProgressBar.setVisibility(View.GONE); }else if (newProgress < 95 && webProgressBar.getVisibility() == View.GONE){ webProgressBar.setVisibility(View.VISIBLE); } webProgressBar.setProgress(newProgress); } super.onProgressChanged(view, newProgress); } // For Android < 5.0 public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) { openFileChooserImpl(uploadMsg); } // For Android => 5.0 public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> uploadMsg, WebChromeClient.FileChooserParams fileChooserParams) { onenFileChooseImpleForAndroid(uploadMsg); return false; } }); /** * 監聽手機返回按鍵,點選返回H5就返回上一級 */ h5WebView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK) && h5WebView.canGoBack()) { h5WebView.goBack(); return true; } return false; } }); } /** * android 5.0 以下開啟圖片選擇(原生) * * 可以自己改圖片選擇框架。 */ private void openFileChooserImpl(ValueCallback<Uri> uploadMsg) { mUploadMessage = uploadMsg; Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.addCategory(Intent.CATEGORY_OPENABLE); i.setType("image/*"); startActivityForResult(Intent.createChooser(i, "File Chooser"), FILE_CHOOSER_RESULT_CODE); } /** * android 5.0(含) 以上開啟圖片選擇(原生) * * 可以自己改圖片選擇框架。 */ private void onenFileChooseImpleForAndroid(ValueCallback<Uri[]> filePathCallback) { mUploadMessageForAndroid5 = filePathCallback; Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT); contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE); contentSelectionIntent.setType("image/*"); Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent); chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser"); startActivityForResult(chooserIntent, FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5); } @Override public void onActivityResult(int requestCode, int resultCode,Intent intent) { Uri result = (intent == null || resultCode != Activity.RESULT_OK) ? null: intent.getData(); switch (requestCode){ case FILE_CHOOSER_RESULT_CODE: //android 5.0以下 選擇圖片回撥 if (null == mUploadMessage) return; mUploadMessage.onReceiveValue(result); mUploadMessage = null; break; case FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5: //android 5.0(含) 以上 選擇圖片回撥 if (null == mUploadMessageForAndroid5) return; if (result != null) { mUploadMessageForAndroid5.onReceiveValue(new Uri[]{result}); } else { mUploadMessageForAndroid5.onReceiveValue(new Uri[]{}); } mUploadMessageForAndroid5 = null; break; } } }
這就是所需的許可權,記得在AndroidManifest.xml中進行配置. (這裡不知道有沒有遺漏)
<uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-feature android:name="android.hardware.camera" /> <!-- 使用照相機許可權 --> <uses-feature android:name="android.hardware.camera.autofocus" /> <!-- 自動聚焦許可權 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
當然這裡面是有些缺陷的,例如沒有執行時許可權、適配Android6.0 - 7.0 。 Android 7.0 開始資源共享問題。
這邊文章還有很大的優化、修改的地方的。
(因為國產手機中,一些廠商都是自家深度定製的Android 系統。
所以一些執行時許可權是和Google釋出的Android 執行時許可權是存在一些出入的,在這方面的適配會有些複雜)
另外圖片選擇不是很建議用原生的,建議還是用第三方的圖片選擇框架。這就自己看自己的需求改了