2015-02-24 2 views
6
Min SDK API 15 

Здравствуйте,Использования WebView для просмотра фотогалереи

Я с помощью WebView, который имеет кнопку на нем, который будет просматривать приложения фотогалереи.

Однако, когда кнопка нажата в веб-просмотре, ничего не происходит.

URL-адрес в формате:

https://www.xxxxxxxxxxx 

я добавил следующие разрешения:

<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" /> 

У меня есть фрагмент, который будет загружать WebView в методе onCreateView (фрагмент кода только) с javascript включен.

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); 
} 

Я создал простую HTML-страницу для проверки:

<!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> 

Так URL будет загружен в WebView. В веб-просмотре отображается кнопка, которую пользователь нажмет, чтобы просмотреть фотографии в своей галерее.

WebView выглядит следующим образом: enter image description here

Ни одна из кнопок не работает, когда я нажимаю их.

Большое спасибо за любые предложения,

Этот фрагмент кода работает для < 4.3. Однако, 4.4 и 5.0 он терпит неудачу.

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); 
      } 

     }); 
+0

Ваше сообщение Строка? У вас есть https: // там? Только www. не работает ... Ups sorry misread question –

+0

Я только что обновил свой ответ в формате uri. – ant2009

+0

Я думаю, что вы обновили свой вопрос ... –

ответ

7

создать этот файл и поместить его в папку ваших активов: 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> 

концентрат на JavaScript здесь написано.

написать вашу деятельность, как показано ниже: 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(); 
      } 
     } 
    } 

} 

использовать этот фрагмент кода и посмотреть, если он работает.

этот снимок экрана, приведенный ниже, взят с устройства Android 4.4 Kitkat.

see this screen shot

Я не знаю, если это решение работает вам или нет. Это может быть просто обходной путь или прорыв для вас. Надеюсь, какая-то часть этого поможет.

+0

Спасибо, Амрут. Я попробую. Однако я заметил, что вы используете интерфейс для javascript. Можно ли это сделать без этого? – ant2009

+1

Основываясь на вашей проблеме/требовании, невозможно решить проблему без использования интерфейса в соответствии с моими знаниями. –

+0

Спасибо, что решил мою полную проблему. – ant2009

2

Ну вы можете достичь его, как этот

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; 
     } 
    }); 

и ваш HTML должен быть, как этот

<!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> 
5

К сожалению, как сказал пользователь Слартибартфаст в одном из комментариев к вашему вопросу, тип входа " файл "не будет работать на 4.4 устройствах. В коде google есть issue, в котором говорится, что это предполагаемое поведение (Status: WorkingAsIntended).

Тем не менее, код, который вы предоставили, работает в 4.4.4 (протестирован на планшете Nexus 7) и на < версии 4.4 os.

В 5.0, они добавили документально подтвержденный method, чтобы сделать это. Я использую следующий код:

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; 
    } 
}); 

принять к сведению на измененном параметра обратного вызова> 5.0: от ValueCallback<Uri> до ValueCallback<Uri[]>.

Итак, для> = 4.4 и < 4.4.4 вы должны реализовать свой собственный механизм загрузки файлов. Некоторые предложения:

  • проверить с помощью javascript версию android os и предоставить <input type="file">, где это работает. В версиях 4.4 создайте элемент html со своей собственной схемой URL (как сказал Сишант, например <form action="image://choose">). Затем вы можете поймать его в shouldOverrideUrlLoading и вызвать функцию javascript из java с файловым путем, но вы не сможете получить доступ к содержимому вашего файла. Для небольших файлов вы можете передать содержимое файла в base64 в качестве параметра функции javascript, но для более крупных файлов вы наверняка получите исключение OutOfMemory.
  • вы можете выполнить описанные выше шаги, но обработать загрузку файла в java и предоставить только путь к функции javascript. Кнопка с submit может использовать то, что сказал Амрут Бидри, чтобы вызвать загрузку в java.

Итак, в качестве вывода, я вижу два варианта для версий os между 4.4 и 4.4.4: либо использовать javascript для загрузки файла (проблемы с памятью), либо загрузить его в java и реализовать собственный механизм связи между вашим приложение и веб-просмотр. Для них вы должны иметь доступ к веб-странице, которую вы загружаете в веб-просмотре.

Я использовал метод яваскрипта загрузки, так как мы используем небольшие файлы, и это было немного быстрее реализовать:

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

    return false; 
} 

В результате деятельности, я сделать что-то подобное для 4.4 версии (Код JavaScript функции insertFileForUpload обрабатывает загрузки файла):

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; 
} 

кроме того, в отношении https://github.com/delight-im/Android-AdvancedWebView, кажется, что загрузка файлов работает, но они говорят: «Загрузка файлов обрабатываются автоматически (проверить наличие с AdvancedWebView.isFileUploadAvailable())» и «IsFileUploadAvailable» содержит следующий код:

/** 
* 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; 
    } 
} 

Таким образом, вы могли бы просто иметь те же проблемы с нормальным WebView, но я не проверял библиотеку, так что я не могу сказать.

Возможно, я создал беспорядок ответа, но надеюсь, вы найдете что-то полезное.

+0

Спасибо за ваш ответ. – ant2009

0

С помощью этого кода можно перейти по пути к мобильному файлу, только я не могу загрузить файл в php. Ниже приведен код php, который я использую:

$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); 
Смежные вопросы