1. 程式人生 > >Android WebView 選擇圖片並上傳(呼叫相機拍照/相簿/選擇檔案)

Android WebView 選擇圖片並上傳(呼叫相機拍照/相簿/選擇檔案)

前言:

這個功能其實我才剛接觸。不熟...在這個給大家提供的都是經過本人驗證之後的一些案例。可以在專案中跑的。

最近專案嵌入混合開發,都是使用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 執行時許可權是存在一些出入的,在這方面的適配會有些複雜)

另外圖片選擇不是很建議用原生的,建議還是用第三方的圖片選擇框架。這就自己看自己的需求改了