How to read data in blob in webview on android?

I have a server that creates a blob object in a browser and I want to load it into a WebView in an Android app. I tried redirecting the request to the browser instance, and also using the download manager, but none of them work (even if I open the same page in Chrome, the download works there).

I tried the following code, it throws an error:

Android.content.ActivityNotFoundException: no activity to handle Intent {act = android.intent.action.VIEW dat = blob: https% 3A // 111.111.111.111% 3A8080 / 40b63131-63b1-4fa4-9451-c6297bbd111a "

Edit

Android.content.ActivityNotFoundException: no activity to handle Intent {act = android.intent.action.VIEW dat = blob: http://digitalinsensu.com/0f0d6127-a0f1-44c3-af85-72f648258d6d


code:

mWebView.setDownloadListener(new DownloadListener() { public void onDownloadStart(String url, String userAgent,String contentDisposition, String mimetype,long contentLength) { Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(url)); startActivity(i); } }); 

and this throws java.lang.IllegalArgumentException: can only load HTTP / HTTPS URI error:

 mWebView.setDownloadListener(new DownloadListener() { public void onDownloadStart(String url, String userAgent,String contentDisposition, String mimetype,long contentLength) { DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "download"); DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); dm.enqueue(request); } }); 

How should I download blob? Any help would be greatly appreciated.

+4
source share
4 answers

Yes, it should be possible. In your case, the URL looks like once the blob: prefix is ​​removed, and the rest is decoded by the URL:

  blob: http: //digitalinsensu.com/0f0d6127-a0f1-44c3-af85-72f648258d6d 

Remember that this URL will only work if the user has a web server running on his device that responds to requests , which is unlikely in the case of blob: URL . If you want to do this, you must first remove blob: using Java String.replace(..) or similar. To decode a URL, use something like URLDecoder.decode(url, "UTF-8"); see here for details.

The problem is that DownloadListener really expecting a URI (ex http://server.com/file.pdf ). However, the link that the user clicks on does not skip URIs in this format. The missing URL is a blob that is bound to the browser DOM . As a result, the solution will not work as designed.

You may have another option. It depends on how you generate bytes for blob. You mentioned that you are doing this in Javascript. If so, I would skip the full use of Blob and URL.createObjectURL and write a Javascript/Native interface that will allow you to pass bytes in chunks (for example, the number of arrays is 255 bytes) into Java code. This will reduce memory consumption on the client.

I have an idea on how to create an interface, but first I need to understand how you generate bytes for blob. If you can send an array of bytes, I can try to continue.

Read more about this check here.

+2
source

You need to intercept the callback to handle the urls like this:

 webView.setWebViewClient(new WebViewClient() { @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); shouldOverrideUrlLoading(view, Uri.parse(url)); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { return shouldOverrideUrlLoading(view, request.getUrl()); } // legacy callback @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { return shouldOverrideUrlLoading(view, Uri.parse(url)); } return super.shouldOverrideUrlLoading(view, url); } private boolean shouldOverrideUrlLoading(final WebView view, final Uri request) { if(request.getScheme().equals("blob")) { // do your special handling for blob urls here return true; } } }); 

In shouldOverrideUrlLoading() you can do special processing.

+1
source

I decided to use it with Javascript interfaces. You can do this in accordance with these steps, it works fine in this application with minSdkVersion: 17. First, convert the Blob URL data to Base64 string via JS. Secondly, send this line to the Java class and finally convert it to an accessible format, in this case I converted it to a ".pdf" file. Take a look at this example .

Sourse of information:

fooobar.com/questions/1269959 / ...

fooobar.com/questions/79530 / ...

fooobar.com/questions/805718 / ...

-1
source

I used this in my code:

 ngOnInit() { let webview: WebView = this.webViewRef.nativeElement; if (isAndroid) { webview.on(WebView.loadStartedEvent, function () { webview.android.getSettings().setBuiltInZoomControls(false); webview.android.getSettings().setJavaScriptEnabled(true); webview.android.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); webview.android.getSettings().setAllowFileAccess(true); webview.android.getSettings().setPluginsEnabled(true); webview.android.getSettings().setAllowContentAccess(true); webview.android.getSettings().setAllowFileAccess(true); webview.android.getSettings().setAllowFileAccessFromFileURLs(true); webview.android.getSettings().setAllowUniversalAccessFromFileURLs(true); webview.android.getSettings().setDomStorageEnabled(true); webview.android.getSettings().setDefaultTextEncodingName("utf-8"); webview.android.setDownloadListener(new android.webkit.DownloadListener({ onDownloadStart(url, userAgent, contentDisposition, mimetype, contentLength) { let request = new android.app.DownloadManager.Request(android.net.Uri.parse(url)); request.setMimeType(mimetype); let cookies = android.webkit.CookieManager.getInstance().getCookie(url); request.addRequestHeader("cookie", cookies); request.addRequestHeader("User-Agent", userAgent); request.setDescription("Downloading file..."); request.setTitle(android.webkit.URLUtil.guessFileName(url, contentDisposition, mimetype)); request.allowScanningByMediaScanner(); request.setNotificationVisibility(android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setDestinationInExternalPublicDir(android.os.Environment.DIRECTORY_DOWNLOADS, android.webkit.URLUtil.guessFileName(url, contentDisposition, mimetype)); let dm = utils.ad.getApplicationContext().getSystemService(android.content.Context.DOWNLOAD_SERVICE); dm.enqueue(request); } })); }); } 
-1
source

Source: https://habr.com/ru/post/1269959/


All Articles