티스토리 뷰

반응형

Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.

Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.

 

아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.

File Upload in WebView

WebView에서 파일 업로드하기

 문제 내용 

I have been struggling to upload files from WebView since last few days and there is no progress. I googled and implemented all suggested solutions but none works, like: solutions suggested here, and so on.

최근 몇 년 동안 WebView에서 파일을 업로드하는 데 어려움을 겪고 있습니다. 며칠이고 진전이 없습니다. 제안된 모든 솔루션을 검색하고 구현했지만 여기에 제안된 솔루션 등도 작동하지 않습니다.

 

Problem: I have a HTML page with the following code to upload a file. It works fine in a desktop browser like Firefox and built-in browser of emulator / AVD i.e., when I click "Browse..." button rendered by element, browser opens a Dialog box where I can choose a file to upload.

문제: 나는 파일을 업로드하기 위해 다음 코드가 있는 HTML 페이지를 가지고 있습니다. 파이어폭스와 같은 데스크톱 브라우저와 내장된 브라우저에서 잘 작동합니다. 요소별로 렌더링된 "찾아보기..." 버튼을 클릭하면 업로드할 파일을 선택할 수 있는 대화 상자가 브라우저에서 열립니다.

 

However, in the android 3.0 emulator / AVD, when I click on "Choose file", nothing happens, no file dialog is opened!!!

그러나 Android 3.0 에뮬레이터 / AVD에서 "선택"을 클릭하면 file", 아무 일도 일어나지 않고, 파일 대화상자가 열리지 않습니다!!!
<form method="POST" enctype="multipart/form-data">
File to upload: <input type="file" name="uploadfile">&nbsp;&nbsp;
<input type="submit" value="Press to Upload..."> to upload the file!
</form>

 

Could anyone please suggest a possible solution at the earliest.

가능한 한 빨리 해결책을 제시해 줄 사람이 있나요?

 

 

 

 높은 점수를 받은 Solution 

This is a full solution for all android versions, I had a hard time with this too.

이것은 모든 안드로이드 버전에 대한 완전한 솔루션입니다, 저도 이것 때문에 어려움을 겪었습니다.
public class MyWb extends Activity {
/** Called when the activity is first created. */

WebView web;
ProgressBar progressBar;

private ValueCallback<Uri> mUploadMessage;  
 private final static int FILECHOOSER_RESULTCODE=1;  

 @Override  
 protected void onActivityResult(int requestCode, int resultCode,  
                                    Intent intent) {  
  if(requestCode==FILECHOOSER_RESULTCODE)  
  {  
   if (null == mUploadMessage) return;  
            Uri result = intent == null || resultCode != RESULT_OK ? null  
                    : intent.getData();  
            mUploadMessage.onReceiveValue(result);  
            mUploadMessage = null;  
  }
  }  

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    web = (WebView) findViewById(R.id.webview01);
    progressBar = (ProgressBar) findViewById(R.id.progressBar1);

    web = new WebView(this);  
    web.getSettings().setJavaScriptEnabled(true);
    web.loadUrl("http://www.script-tutorials.com/demos/199/index.html");
    web.setWebViewClient(new myWebClient());
    web.setWebChromeClient(new WebChromeClient()  
    {  
           //The undocumented magic method override  
           //Eclipse will swear at you if you try to put @Override here  
        // For Android 3.0+
        public void openFileChooser(ValueCallback<Uri> uploadMsg) {  

            mUploadMessage = uploadMsg;  
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);  
            i.addCategory(Intent.CATEGORY_OPENABLE);  
            i.setType("image/*");  
            MyWb.this.startActivityForResult(Intent.createChooser(i,"File Chooser"), FILECHOOSER_RESULTCODE);  

           }

        // For Android 3.0+
           public void openFileChooser( ValueCallback uploadMsg, String acceptType ) {
           mUploadMessage = uploadMsg;
           Intent i = new Intent(Intent.ACTION_GET_CONTENT);
           i.addCategory(Intent.CATEGORY_OPENABLE);
           i.setType("*/*");
           MyWb.this.startActivityForResult(
           Intent.createChooser(i, "File Browser"),
           FILECHOOSER_RESULTCODE);
           }

        //For Android 4.1
           public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
               mUploadMessage = uploadMsg;  
               Intent i = new Intent(Intent.ACTION_GET_CONTENT);  
               i.addCategory(Intent.CATEGORY_OPENABLE);  
               i.setType("image/*");  
               MyWb.this.startActivityForResult( Intent.createChooser( i, "File Chooser" ), MyWb.FILECHOOSER_RESULTCODE );

           }

    });  


    setContentView(web);  


}

public class myWebClient extends WebViewClient
{
    @Override
    public void onPageStarted(WebView view, String url, Bitmap favicon) {
        // TODO Auto-generated method stub
        super.onPageStarted(view, url, favicon);
    }

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // TODO Auto-generated method stub

        view.loadUrl(url);
        return true;

    }

    @Override
    public void onPageFinished(WebView view, String url) {
        // TODO Auto-generated method stub
        super.onPageFinished(view, url);

        progressBar.setVisibility(View.GONE);
    }
}

//flipscreen not loading again
@Override
public void onConfigurationChanged(Configuration newConfig){        
    super.onConfigurationChanged(newConfig);
}

// To handle "Back" key press event for WebView to go back to previous screen.
/*@Override
public boolean onKeyDown(int keyCode, KeyEvent event) 
{
    if ((keyCode == KeyEvent.KEYCODE_BACK) && web.canGoBack()) {
        web.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}*/
}

 

Also I want to add that the "upload page" like the one in this example, wont work on < 4 versions, since it has an image preview feature, if you want to make it work use a simple php upload without preview.

또한 이 예시의 페이지와 같은 "업로드 페이지"는 이미지 미리보기 기능이 있기 때문에 < 4 버전에서 작동하지 않는다는 것을 추가하고 싶다. 만약 당신이 미리보기 없이 간단한 php 업로드를 사용한다면.

 

Update:

업데이트:

 

Please find the solution for lollipop devices here and thanks for gauntface

여기에서 롤리팝 장치에 대한 솔루션을 찾으십시오. gauntface에 감사드립니다.

 

Update 2:

업데이트 2:

 

Complete solution for all android devices till oreo here and this is more advanced version, you should look into it, maybe it can help.

여기서 오레오까지 모든 안드로이드 기기를 위한 완전한 솔루션이며, 이것은 더 고급 버전입니다. 당신은 그것을 조사해야 합니다, 아마도 도움이 될 수 있습니다.

 

 

 

 가장 최근 달린 Solution 

2019: This code worked for me (Tested on Androids 5 - 9).

2019: 이 코드는 나에게 효과가 있었다(안드로이드 5 - 9에서 테스트).
package com.example.filechooser;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.net.http.SslError;
import android.os.Bundle;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;


public class MainActivity extends Activity {

    // variables para manejar la subida de archivos
    private final static int FILECHOOSER_RESULTCODE = 1;
    private ValueCallback<Uri[]> mUploadMessage;

    // variable para manejar el navegador empotrado
    WebView mainWebView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        // instanciamos el webview
        mainWebView = findViewById(R.id.main_web_view);

        // establecemos el cliente interno para que la navegacion no se salga de la aplicacion
        mainWebView.setWebViewClient(new MyWebViewClient());

        // establecemos el cliente chrome para seleccionar archivos
        mainWebView.setWebChromeClient(new MyWebChromeClient());

        // configuracion del webview
        mainWebView.getSettings().setJavaScriptEnabled(true);

        // cargamos la pagina
        mainWebView.loadUrl("https://example.com");
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {

        // manejo de seleccion de archivo
        if (requestCode == FILECHOOSER_RESULTCODE) {

            if (null == mUploadMessage || intent == null || resultCode != RESULT_OK) {
                return;
            }

            Uri[] result = null;
            String dataString = intent.getDataString();

            if (dataString != null) {
                result = new Uri[]{ Uri.parse(dataString) };
            }

            mUploadMessage.onReceiveValue(result);
            mUploadMessage = null;
        }
    }


    // ====================
    // Web clients classes
    // ====================

    /**
     * Clase para configurar el webview
     */
    private class MyWebViewClient extends WebViewClient {

        // permite la navegacion dentro del webview
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }
    }


    /**
     * Clase para configurar el chrome client para que nos permita seleccionar archivos
     */
    private class MyWebChromeClient extends WebChromeClient {

        // maneja la accion de seleccionar archivos
        @Override
        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {

            // asegurar que no existan callbacks
            if (mUploadMessage != null) {
                mUploadMessage.onReceiveValue(null);
            }

            mUploadMessage = filePathCallback;

            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("*/*"); // set MIME type to filter

            MainActivity.this.startActivityForResult(Intent.createChooser(i, "File Chooser"), MainActivity.FILECHOOSER_RESULTCODE );

            return true;
        }
    }

}

 

Hope can help you.

희망이 널 도울 수 있어.

 

 

 

출처 : https://stackoverflow.com/questions/5907369/file-upload-in-webview

반응형
댓글
공지사항
최근에 올라온 글