Android: Не работает диалог выбора файла в webview
Задача: в контексте webview приложения для android, не открывается диалоговое окно выбора файла, в виду отсутствия в «базовом» варианте работы webview необходимых обработчиков. Решение описываемое в статье 2020года не работает в 2022 году
Решение: в конце 2022 года, рабочая минимальная обвязка для обработки выбора файлов такова:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
public class MainActivity extends AppCompatActivity { private ValueCallback<Uri[]> fileChooserCallback; private WebView mbrowser; Uri home = Uri.parse("https://цукмсцумкцу.ru/choser.php"); //загрузки изображений private ValueCallback<Uri> mUploadMessage; public ValueCallback<Uri[]> uploadMessage; public static final int REQUEST_SELECT_FILE = 100; public static final int REQUEST_QR_CODE = 200; private final static int FILECHOOSER_RESULTCODE = 1; public final static int CHILD_FINISH = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mbrowser=(WebView) findViewById(R.id.main_webview); mbrowser.getSettings().setJavaScriptEnabled(true); // разрешен javascript mbrowser.getSettings().setDatabaseEnabled(true); // хранение данных во встроенной БД в браузере mbrowser.getSettings().setDomStorageEnabled(true); mbrowser.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); // разрешать открывать окна mbrowser.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView vw, WebResourceRequest request) { if (request.getUrl().toString().contains(home.getHost())) { vw.loadUrl(request.getUrl().toString()); } else { Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl()); vw.getContext().startActivity(intent); } return true; } }); mbrowser.setWebChromeClient(new WebChromeClient() { @Override public void onPermissionRequest(final PermissionRequest request) { request.grant(request.getResources()); } @Override public boolean onShowFileChooser(WebView vw, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { if (fileChooserCallback != null) { fileChooserCallback.onReceiveValue(null); } fileChooserCallback = filePathCallback; Intent selectionIntent = new Intent(Intent.ACTION_GET_CONTENT); selectionIntent.addCategory(Intent.CATEGORY_OPENABLE); selectionIntent.setType("*/*"); Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); chooserIntent.putExtra(Intent.EXTRA_INTENT, selectionIntent); startActivityForResult(chooserIntent, 0); return true; } }); mbrowser.setOnKeyListener((v, keyCode, event) -> { WebView vw = (WebView) v; if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK && vw.canGoBack()) { vw.goBack(); return true; } return false; }); mbrowser.setDownloadListener((uri, userAgent, contentDisposition, mimetype, contentLength) -> handleURI(uri)); mbrowser.setOnLongClickListener(v -> { handleURI(((WebView) v).getHitTestResult().getExtra()); return true; }); mbrowser.loadUrl(home.toString()); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { super.onActivityResult(requestCode, resultCode, intent); fileChooserCallback.onReceiveValue(new Uri[]{Uri.parse(intent.getDataString())}); fileChooserCallback = null; } private void handleURI(String uri) { if (uri != null) { Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(uri.replaceFirst("^blob:", ""))); startActivity(i); } } } |