Android-WebView支持input file啟用相機/選取照片

来源:https://www.cnblogs.com/maggieq8324/archive/2019/08/26/11414769.html
-Advertisement-
Play Games

webview要調起input file拍照或者選取文件功能,可以在webview.setWebChromeClient方法中重寫指定的方法,來攔截webview的input事件,並做我們相應的操作。 Android代碼 這裡的java代碼是來攔截input事件的,裡面做了很多api版本的判斷,不同 ...


webview要調起input-file拍照或者選取文件功能,可以在webview.setWebChromeClient方法中重寫指定的方法,來攔截webview的input事件,並做我們相應的操作。

Android代碼

webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if (newProgress == 100) {
                    progressBar.setVisibility(View.GONE);//載入完網頁進度條消失
                } else {
                    progressBar.setProgress(newProgress);//設置進度值
                    progressBar.setVisibility(View.VISIBLE);//開始載入網頁時顯示進度條
                }
            }
 
            /**
             * 8(Android 2.2) <= API <= 10(Android 2.3)回調此方法
             */
            private void openFileChooser(android.webkit.ValueCallback<Uri> uploadMsg) {
                Log.e("WangJ", "運行方法 openFileChooser-1");
                // (2)該方法回調時說明版本API < 21,此時將結果賦值給 mUploadCallbackBelow,使之 != null
                mUploadCallbackBelow = uploadMsg;
                takePhoto();
            }
 
            /**
             * 11(Android 3.0) <= API <= 15(Android 4.0.3)回調此方法
             */
            public void openFileChooser(android.webkit.ValueCallback<Uri> uploadMsg, String acceptType) {
                Log.e("WangJ", "運行方法 openFileChooser-2 (acceptType: " + acceptType + ")");
                // 這裡我們就不區分input的參數了,直接用拍照
                openFileChooser(uploadMsg);
            }
 
            /**
             * 16(Android 4.1.2) <= API <= 20(Android 4.4W.2)回調此方法
             */
            public void openFileChooser(android.webkit.ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
                Log.e("WangJ", "運行方法 openFileChooser-3 (acceptType: " + acceptType + "; capture: " + capture + ")");
                // 這裡我們就不區分input的參數了,直接用拍照
                openFileChooser(uploadMsg);
            }
 
            /**
             * API >= 21(Android 5.0.1)回調此方法
             */
            @Override
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> valueCallback, FileChooserParams fileChooserParams) {
                Log.e("WangJ", "運行方法 onShowFileChooser");
                // (1)該方法回調時說明版本API >= 21,此時將結果賦值給 mUploadCallbackAboveL,使之 != null
                mUploadCallbackAboveL = valueCallback;
                takePhoto();
                return true;
            }
        });

這裡的java代碼是來攔截input事件的,裡面做了很多api版本的判斷,不同版本的api調用不同的方法,下麵是一些其他方法:

調起相機/選擇文件的方法:takePhoto();

 /**
     * 調用相機
     */
    private void takePhoto() {
        // 指定拍照存儲位置的方式調起相機
        String filePath = Environment.getExternalStorageDirectory() + File.separator
                + Environment.DIRECTORY_PICTURES + File.separator;
        String fileName = "IMG_" + DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
        imageUri = Uri.fromFile(new File(filePath + fileName));
 
//        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
//        startActivityForResult(intent, REQUEST_CODE);
 
        // 選擇圖片(不包括相機拍照),則不用成功後發刷新圖庫的廣播
//        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
//        i.addCategory(Intent.CATEGORY_OPENABLE);
//        i.setType("image/*");
//        startActivityForResult(Intent.createChooser(i, "Image Chooser"), REQUEST_CODE);
 
        Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
 
        Intent Photo = new Intent(Intent.ACTION_PICK,
                android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
 
        Intent chooserIntent = Intent.createChooser(Photo, "Image Chooser");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});
 
        startActivityForResult(chooserIntent, REQUEST_CODE);
    }

onActivityResult回調:

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {
            // 經過上邊(1)、(2)兩個賦值操作,此處即可根據其值是否為空來決定採用哪種處理方法
            if (mUploadCallbackBelow != null) {
                chooseBelow(resultCode, data);
            } else if (mUploadCallbackAboveL != null) {
                chooseAbove(resultCode, data);
            } else {
                Toast.makeText(this, "發生錯誤", Toast.LENGTH_SHORT).show();
            }
        }
    }

其他一些方法:

/**
     * Android API < 21(Android 5.0)版本的回調處理
     * @param resultCode 選取文件或拍照的返回碼
     * @param data 選取文件或拍照的返回結果
     */
    private void chooseBelow(int resultCode, Intent data) {
        Log.e("WangJ", "返回調用方法--chooseBelow");
 
        if (RESULT_OK == resultCode) {
            updatePhotos();
 
            if (data != null) {
                // 這裡是針對文件路徑處理
                Uri uri = data.getData();
                if (uri != null) {
                    Log.e("WangJ", "系統返回URI:" + uri.toString());
                    mUploadCallbackBelow.onReceiveValue(uri);
                } else {
                    mUploadCallbackBelow.onReceiveValue(null);
                }
            } else {
                // 以指定圖像存儲路徑的方式調起相機,成功後返回data為空
                Log.e("WangJ", "自定義結果:" + imageUri.toString());
                mUploadCallbackBelow.onReceiveValue(imageUri);
            }
        } else {
            mUploadCallbackBelow.onReceiveValue(null);
        }
        mUploadCallbackBelow = null;
    }
 
    /**
     * Android API >= 21(Android 5.0) 版本的回調處理
     * @param resultCode 選取文件或拍照的返回碼
     * @param data 選取文件或拍照的返回結果
     */
    private void chooseAbove(int resultCode, Intent data) {
        Log.e("WangJ", "返回調用方法--chooseAbove");
 
        if (RESULT_OK == resultCode) {
            updatePhotos();
 
            if (data != null) {
                // 這裡是針對從文件中選圖片的處理
                Uri[] results;
                Uri uriData = data.getData();
                if (uriData != null) {
                    results = new Uri[]{uriData};
                    for (Uri uri : results) {
                        Log.e("WangJ", "系統返回URI:" + uri.toString());
                    }
                    mUploadCallbackAboveL.onReceiveValue(results);
                } else {
                    mUploadCallbackAboveL.onReceiveValue(null);
                }
            } else {
                Log.e("WangJ", "自定義結果:" + imageUri.toString());
                mUploadCallbackAboveL.onReceiveValue(new Uri[]{imageUri});
            }
        } else {
            mUploadCallbackAboveL.onReceiveValue(null);
        }
        mUploadCallbackAboveL = null;
    }
 
    private void updatePhotos() {
        // 該廣播即使多發(即選取照片成功時也發送)也沒有關係,只是喚醒系統刷新媒體文件
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(imageUri);
        sendBroadcast(intent);
    }

相關的全局變數:

private android.webkit.ValueCallback<Uri[]> mUploadCallbackAboveL;
private android.webkit.ValueCallback<Uri> mUploadCallbackBelow;
private Uri imageUri;
private int REQUEST_CODE = 1234;

原文參考鏈接:https://blog.csdn.net/qq_35373333/article/details/79565629


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 基本安裝參考https://www.jianshu.com/p/8b27ff71429f 按此方案裝的時候會遇到各種flask版本不相容的問題,所以 第一步:裝好anaconda 第二部:保證好高於VC++14的環境,沒有的話可以去簡書https://www.jianshu.com/p/8b27ff ...
  • 最近在使用java操作遠程的mysql資料庫的時候,第一次請求非常的慢,而且極其容易引起系統的崩潰報錯連接超時 下麵就這個問題來解決下把 大部分我們的mysql中的配置信息時這樣的(本人的修改過,自查宿主的mysql信息) 其中的配置信息,網上也有很多的介紹,這裡邊就不詳細的介紹了, 其中有一個(我 ...
  • 最近在看《Pentaho Kettle 解決方案》,看到 ETL子系統,發現信息量比較大,用簡短的語句做一下筆記。 ETL子系統有34種子系統,被分成4個部分:抽取、清洗和更正、發佈、管理。 一、抽取 子系統1:數據剖析系統 指從不同源系統中搜集數據的統計信息或其他相關信息的過程,目的是分析不同數據 ...
  • 這種情況上傳個jre 並指定下就好了~/database/runInstaller -jreLoc /usr/local/jre1.8.0_191/ ...
  • 本篇文章主要學習了MySQL的索引的數據結構的認識,以及一些索引優化的註意事項,做一個大概的瞭解即可。 ...
  • 一、HBase過濾器簡介 Hbase 提供了種類豐富的過濾器(filter)來提高數據處理的效率,用戶可以通過內置或自定義的過濾器來對數據進行過濾,所有的過濾器都在服務端生效,即謂詞下推(predicate push down)。這樣可以保證過濾掉的數據不會被傳送到客戶端,從而減輕網路傳輸和客戶端處 ...
  • CMake與NDK搭配使用時,可以配置的部分變數: 1. :指定Android的目標版本,對應 目錄下的版本。通常情況下是 中的 ,這樣就能確保所有大於等於 的設備都可以使用編譯生成的庫。 但是也有例外,比如:當 時,即使 為`18 ANDROID_PLATFORM=android 21 $NDK/ ...
  • 混淆原理 代碼編譯階段將符號(方法名、屬性名等)替換成隨機生成的字元串 長話短說,直接上步驟。 混淆集成步驟 步驟一、創建shell文件(confuse.sh)並配置相應的運行環境。 在項目根目錄下新建一個文件夾 這裡取文件夾名稱為CodeObfuscation,如下圖所示 在上一步的文件下新建一個 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...