Using Web Browsing to View Photo Galleries

Min SDK API 15 

Hello,

I am using webview, on which there is a button that will view the application gallery.

However, when a button is pressed in a web view, nothing happens.

The URL has the format:

 https://www.xxxxxxxxxxx 

I added the following permissions:

 <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera" android:required="false" /> 

I have a fragment that will load the webview in the onCreateView method (fragment only) with javascript enabled.

 if(!message.isEmpty()) { WebView webView = (WebView)view.findViewById(R.id.webview); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true); webView.setWebViewClient(new WebViewClient()); webView.loadUrl(message); } 

I created a simple html page for testing:

 <!doctype html> <html> <head> <meta charset="utf-8"> <title>Test Android Popup</title> </head> <body> <label>Test Alert 1:</label> <button type="button" onClick="alert('Test Alert Box1');">Click Me!</button> <br> <label>Test Browse file</label> <input type="file" name="img"> </body> </html> 

This way the URL will be uploaded to webview. Web browsing displays a button that the user clicks to view photos in his gallery.

Web browsing is as follows: enter image description here

None of the buttons work when I click on them.

Thanks so much for any suggestions,

This piece of code works for <4.3. However, 4.4 and 5.0 it fails.

  webView.setWebChromeClient(new WebChromeClient() { /* Open File */ public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) { mImageFilePath = uploadMsg; Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); startActivityForResult(intent, FILECHOOSER_RESULTCODE); } public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) { mImageFilePath = uploadMsg; Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); startActivityForResult(intent, FILECHOOSER_RESULTCODE); } }); 
+6
source share
4 answers

create this file and put it in the folder with your resources: webdemo.html

 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>title</title> </head> <body> <h1>Web View Demo</h1> <br> <input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" /> <br /> File Uri: <label id="lbluri">no file uri</label> <br /> File Path: <label id="lblpath">no file path</label> <br /> <input type="button" value="Choose Photo" onClick="choosePhoto()" /> <script type="text/javascript"> function showAndroidToast(toast) { Android.showToast(toast); } function setFilePath(file) { document.getElementById('lblpath').innerHTML = file; Android.showToast(file); } function setFileUri(uri) { document.getElementById('lbluri').innerHTML = uri; Android.showToast(uri); } function choosePhoto() { var file = Android.choosePhoto(); window.alert("file = " + file); } </script> </body> </html> 

concentrate on javascript written here.

write your activity as below: WebViewDemo.java

 public class WebViewDemo extends Activity { private WebView webView; final int SELECT_PHOTO = 1; @SuppressLint("SetJavaScriptEnabled") public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.show_web_view); webView = (WebView) findViewById(R.id.webView1); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setLoadWithOverviewMode(true); // Other webview settings webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY); webView.setScrollbarFadingEnabled(false); webView.getSettings().setBuiltInZoomControls(true); webView.getSettings().setPluginState(PluginState.ON); webView.getSettings().setAllowFileAccess(true); webView.getSettings().setSupportZoom(true); webView.addJavascriptInterface(new MyJavascriptInterface(this), "Android"); webView.loadUrl("file:///android_asset/webdemo.html"); } class MyJavascriptInterface { Context mContext; /** Instantiate the interface and set the context */ MyJavascriptInterface(Context c) { mContext = c; } /** Show a toast from the web page */ @JavascriptInterface public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); } @JavascriptInterface public String choosePhoto() { // TODO Auto-generated method stub String file = "test"; Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); photoPickerIntent.setType("image/*"); startActivityForResult(photoPickerIntent, SELECT_PHOTO); return file; } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { switch (requestCode) { case SELECT_PHOTO: if (resultCode == RESULT_OK) { Uri selectedImage = intent.getData(); webView.loadUrl("javascript:setFileUri('" + selectedImage.toString() + "')"); String path = getRealPathFromURI(this, selectedImage); webView.loadUrl("javascript:setFilePath('" + path + "')"); } } } public String getRealPathFromURI(Context context, Uri contentUri) { Cursor cursor = null; try { String[] proj = { MediaStore.Images.Media.DATA }; cursor = context.getContentResolver().query(contentUri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } finally { if (cursor != null) { cursor.close(); } } } } 

use this piece of code and see if it works.

This screenshot is from the Android 4.4 Kitkat device below.

see this screen shot

I do not know if this solution works or not. It may just be a workaround or breakthrough for you. I hope part of it helps.

+7
source

Unfortunately, as a user of Slartibartfast said in one of the comments on your question, the input type “file” will not work on 4.4 devices. There is an issue in the google code that says this is the alleged behavior (Status: WorkingAsIntended).

However, the code you provided works in 4.4.4 (tested on a Nexus 7 tablet) and on <Version 4.4 os.

In 5.0, they added a documented method . I am using the following code:

 mWebView.setWebChromeClient(new WebChromeClient() { // For Android < 3.0 - undocumented method @SuppressWarnings("unused") public void openFileChooser( ValueCallback<Uri> uploadMsg ) { openFileChooser( uploadMsg, "" ); } // For Android 3.0+ - undocumented method public void openFileChooser( ValueCallback<Uri> uploadMsg, String acceptType ) { mUploadCallback = uploadMsg; openFileChooserActivity(); } // For Android > 4.1 - undocumented method @SuppressWarnings("unused") public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){ openFileChooser( uploadMsg, "" ); } // For Android > 5.0 public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) { mUploadCallbackLollipop = filePathCallback; openFileChooserActivity(); return true; } }); 

Note the changed callback parameter for> 5.0: from ValueCallback<Uri> to ValueCallback<Uri[]> .

So, with> = 4.4 and <4.4.4, you must implement your own file upload mechanism. Some suggestions:

  • check with javascript the version of android os and specify <input type="file"> where it works. In versions 4.4, create an html element with your own URL scheme (as Sishant said, for example, <form action="image://choose"> ). Then you can catch it in shouldOverrideUrlLoading and call the javascript function from java using the file path, but you will not be able to access the contents of your file. For small files, you can pass the contents of the file to base64 as a parameter to the javascript function, but for larger files, you probably get an OutOfMemory exception.
  • you can follow the steps above but handle the file upload in java and provide only the path to the javascript function. The submit button can use what Amrut Bidri said to trigger a download in java.

So, as an output, I see two options for os versions between 4.4 and 4.4.4: either use javascript to load the file (memory problems), or load it into java and implement your own communication mechanism between your application and WebView. For them, you must have access to the webpage that you load in the webview.

I used the javascript download method as we use small files and it was a little faster to implement:

 public boolean shouldOverrideUrlLoading(WebView view, String url) { ... else if (url.startsWith(UPLOAD_FILE_URL_PREFIX)) { openFileChooserActivity(); return true; } return false; } 

As a result of the action, I do something similar for versions 4.4 (the javascript insertFileForUpload function handles the file upload):

 private void invokeJavascriptWithFileContent(Uri fileUri) { String fileContentInBase64 = readAndConvertFileToBase64(fileUri); if (!fileContentInBase64.isEmpty()) { String fileMimeType = getMimeType(activity, fileUri); String fileName = getFileName(activity, fileUri); // invoke javascript String js = String.format("javascript:insertFileForUpload(\"%s\",\"%s\",\"%s\")", fileName, fileMimeType, fileContentInBase64 ); mWebView.loadUrl(js); } } public static String getMimeType(Context context, Uri fileUri) { ContentResolver cR = context.getContentResolver(); MimeTypeMap mime = MimeTypeMap.getSingleton(); String type = mime.getExtensionFromMimeType(cR.getType(fileUri)); return type; } 

Also, with regard to https://github.com/delight-im/Android-AdvancedWebView , it seems that downloading files works, but they say: "Files download automatically (check availability with AdvancedWebView.isFileUploadAvailable ()) 'and' isFileUploadAvailable 'contains the following code:

 /** * Returns whether file uploads can be used on the current device (generally all platform versions except for 4.4) * * @return whether file uploads can be used */ public static boolean isFileUploadAvailable() { return isFileUploadAvailable(false); } /** * Returns whether file uploads can be used on the current device (generally all platform versions except for 4.4) * * On Android 4.4.3/4.4.4, file uploads may be possible but will come with a wrong MIME type * * @param needsCorrectMimeType whether a correct MIME type is required for file uploads or `application/octet-stream` is acceptable * @return whether file uploads can be used */ public static boolean isFileUploadAvailable(final boolean needsCorrectMimeType) { if (Build.VERSION.SDK_INT == 19) { final String platformVersion = (Build.VERSION.RELEASE == null) ? "" : Build.VERSION.RELEASE; return !needsCorrectMimeType && (platformVersion.startsWith("4.4.3") || platformVersion.startsWith("4.4.4")); } else { return true; } } 

This way you may have the same problems with normal web browsing, but I have not tested the library, so I cannot say.

I may have created a mess of response, but hope you find something useful.

+5
source

Ok you can achieve this like this

  webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url.equals("alert://alert")) { Toast.makeText(this, "alert", Toast.LENGTH_LONG).show(); } else if (url.equals("choose://image")) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); startActivityForResult(intent, FILECHOOSER_RESULTCODE); } return true; } }); 

and your html should look like this

 <!doctype html> <html> <head> <meta charset="utf-8"> <title>Test Android Popup</title> </head> <body> <label>Test Alert 1:</label> <form action="alert://alert"> <input type="submit" value="Click me!"> </form> <br> <label>Test Browse file</label> <form action="image://choose"> <input type="submit" value="Choose File"> </form> </body> </html> 
+2
source

You can go through the path to the mobile file through this code, only I can’t upload the file to php. Below is the php code I'm using:

 $arquivo = $_POST['lblpath']; $url = "file:///storage/external_SD/fotos/IMG10022.jpg"; //url da imagem que venha de um textField //PEGA INFORMAÇÕES DA IMAGEM $file_info = getimagesize($url); //VERIFICA EXTENSÃO DA IMAGEM if ($file_info['mime'] == "image/jpeg") $img = imagecreatefromjpeg($url); else if ($file_info['mime'] == "image/gif") $img = imagecreatefromgif($url); else if ($file_info['mime'] == "image/png") $img = imagecreatefrompng($url); $altura = $file_info[1]; //PASSA AS MEDIDAS PARA A IMAGEM $x = imagesx($img); $y = imagesy($img); $largura = ($altura * $x)/$y; //CRIA A IMAGEM $nova = imagecreatetruecolor($largura, $altura); imagealphablending( $nova, false ); imagesavealpha( $nova, true ); imagecopyresampled($nova, $img, 0, 0, 0, 0, $largura, $altura, $x, $y); //NOME DA IMAGEM $imgName = end(explode("/", $url)); //LOCAL PARA SALVAR $pasta = "images/"; // defina sua path $local = $pasta . $imgName; //SALVA NOVA IMAGEM if ($file_info['mime'] == "image/jpeg") imagejpeg($nova, $local, 100); else if ($file_info['mime'] == "image/png") imagepng($nova, $local, 9); //DESTROI ELEMENTOS imagedestroy($img); imagedestroy($nova); 
0
source

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


All Articles