ȸ¿ø°¡ÀԡžÆÀ̵ð/ºñ¹øã±â
ȨÀ¸·Î

WebView File Upload
7³â Àü
input ű׸¦ ÀÌ¿ëÇÏ¿© ÆÄÀÏ ¾÷·Îµå¸¦ ÇÒ ¶§, Chrome Browser¿¡¼­´Â Àß µÇÁö¸¸,
¾Û WebView¿¡¼­´Â µ¿ÀÛÀ» ÇÏÁö ¾Ê´Â´Ù.

°á±¹ ±¸±Û¸µ°ú Chrome ¼Ò½º¸¦ Âü°í Çؼ­ File Upload¸¦ Å×½ºÆ® ÇØ º¸¾Ò´Ù.



³»°¡ Å×½ºÆ®ÇÑ WebView ¼ÂÆà ¼Ò½º ÀÌ´Ù.
°¡Àå Áß¿äÇÑ ºÎºÐÀÌ setWebChromeClient ÇÔ¼ö ÀÌ´Ù.

private static final String TYPE_IMAGE = "image/*";
private static final int INPUT_FILE_REQUEST_CODE = 1;

private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
WebView webView  = (WebView) findViewById(R.id.webview_);
webView.getSettings().setJavaScriptEnabled(true);

// Enable pinch to zoom without the zoom buttons
webView.getSettings().setBuiltInZoomControls(true);
// Enable pinch to zoom without the zoom buttons
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
    // Hide the zoom controls for HONEYCOMB+
    webView.getSettings().setDisplayZoomControls(false);
}
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    webView.getSettings().setTextZoom(100);
webView.setWebChromeClient(new WebChromeClient(){
    @Override
    public void onCloseWindow(WebView w) {
        super.onCloseWindow(w);
        finish();
    }

    @Override
    public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, Message resultMsg) {
        final WebSettings settings = view.getSettings();
        settings.setDomStorageEnabled(true);
        settings.setJavaScriptEnabled(true);
        settings.setAllowFileAccess(true);
        settings.setAllowContentAccess(true);
        view.setWebChromeClient(this);
        WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
        transport.setWebView(view);
        resultMsg.sendToTarget();
        return false;
    }

    // For Android Version < 3.0
    public void openFileChooser(ValueCallback<Uri> uploadMsg) {
        //System.out.println("WebViewActivity OS Version : " + Build.VERSION.SDK_INT + "\t openFC(VCU), n=1");
        mUploadMessage = uploadMsg;
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType(TYPE_IMAGE);
        startActivityForResult(intent, INPUT_FILE_REQUEST_CODE);
    }

    // For 3.0 <= Android Version < 4.1
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
        //System.out.println("WebViewActivity 3<A<4.1, OS Version : " + Build.VERSION.SDK_INT + "\t openFC(VCU,aT), n=2");
        openFileChooser(uploadMsg, acceptType, "");
    }

    // For 4.1 <= Android Version < 5.0
    public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType, String capture) {
        Log.d(getClass().getName(), "openFileChooser : "+acceptType+"/"+capture);
        mUploadMessage = uploadFile;
        imageChooser();
    }

    // For Android Version 5.0+
    // Ref: https://github.com/GoogleChrome/chromium-webview-samples/blob/master/input-file-example/app/src/main/java/inputfilesample/android/chrome/google/com/inputfilesample/MainFragment.java
    public boolean onShowFileChooser(WebView webView,
                                     ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
        System.out.println("WebViewActivity A>5, OS Version : " + Build.VERSION.SDK_INT + "\t onSFC(WV,VCUB,FCP), n=3");
        if (mFilePathCallback != null) {
            mFilePathCallback.onReceiveValue(null);
        }
        mFilePathCallback = filePathCallback;
        imageChooser();
        return true;
    }

    private void imageChooser() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();
                takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
            } catch (IOException ex) {
                // Error occurred while creating the File
                Log.e(getClass().getName(), "Unable to create Image File", ex);
            }

            // Continue only if the File was successfully created
            if (photoFile != null) {
                mCameraPhotoPath = "file:"+photoFile.getAbsolutePath();
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                        Uri.fromFile(photoFile));
            } else {
                takePictureIntent = null;
            }
        }

        Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
        contentSelectionIntent.setType(TYPE_IMAGE);

        Intent[] intentArray;
        if(takePictureIntent != null) {
            intentArray = new Intent[]{takePictureIntent};
        } else {
            intentArray = new Intent[0];
        }

        Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
        chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
        chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

        startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
    }
});
webView.setWebViewClient(new WebViewClient());

WebChromeClient Ŭ·¡½º¿¡¼­ º¸³»ÁÖ´Â Äݹé ÇÔ¼ö¸¦ ¾Æ·¡¿Í °°ÀÌ »ý°¢ ÇÏ¸é µÈ´Ù.

KitKat ¹öÀü ÀÌÇÏ´Â openFileChooser ÇÔ¼ö°¡ ÄݹéÀÌ µÈ´Ù.
Lollipop ¹öÀü ÀÌ»óÀº onShowFileChooser ÇÔ¼ö°¡ ÄݹéÀÌ µÈ´Ù.

ÀÌ ¶§ imageChooser ÇÔ¼ö´Â Ä«¸Þ¶ó ±â´É°ú °¶·¯¸®¿¡¼­ À̹ÌÁö¸¦ °¡Á® ¿À´Â ±â´ÉÀ» ÇÑ´Ù.

takePictureIntent ´Â Ä«¸Þ¶ó ±â´É
contentSelectionIntent ´Â °¶·¯¸® ±â´É
chooserIntent ´Â À§ µÎ ±â´ÉÀ» »ç¿ëÀÚ¿¡°Ô ¹­¾î¼­ ¼±ÅÃÇϵµ·Ï À§ÇÑ ±â´É

createImageFileÀº Âü°í ÇϽñ⠹ٶõ´Ù. ÀÌ ÇÔ¼ö´Â ¿øÇÏ´Â ´ë·Î ±¸Çö ÇÏ¸é µÈ´Ù. °á±¹ ÆÄÀÏ Çϳª¸¸ ¸¸µé¾î¼­ ¸®ÅÏ ÇØÁÖ¸é ³¡ÀÌ´Ù.
/**
* More info this method can be found at
* http://developer.android.com/training/camera/photobasics.html
*
* @return
* @throws IOException
*/
private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File imageFile = File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
    return imageFile;
}

ÀÌ·¸°Ô »ç¿ëÀÚ°¡ ¼±ÅÃÇÑ »çÁø À̹ÌÁö´Â ¾Æ·¡ º¸ÀÌ´Â ¼Ò½º °°ÀÌ onActivityResult·Î ¹Þ¾Æ ¿Â´Ù.
¿©±â¼­ WebPage ¼Ò½º°¡ File È®ÀåÀÚ°¡ À̹ÌÁö°¡ ¾Æ´Ï¸é ¾÷·ÎµåÇÏ´Â ºÎºÐÀÌ ¸·Çô À־,
KitKat ¹öÀü¿¡¼­´Â Android¿¡¼­ Á¦°øÇØÁÖ´Â Uri ´ë½Å ÇØ´ç FileÀ» Á÷Á¢ ã¾Æ File °æ·Î¿¡ ´ëÇÑ Uri¸¦ ³Ñ°Ü ÁÖ¾ú´Ù.

¿©±â¼­ Å×½ºÆ® ÇÒ ¶§ ´À³¤ ºÎºÐÀº, filePath¸¦ ³Ñ±æ ¶§ ¾Õ¿¡ 'file:' ÀÌ ¹®ÀÚ¿­À» ²À ³Ö¾îÁà¾ß ÇÑ´Ù.
±×·¸Áö ¾ÊÀ¸¸é file °æ·Î ÀνÄÀÌ Àß µÇÁö ¾Ê¾Ò´Ù. Âü°í ÇÏ±æ ¹Ù¶õ´Ù.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == INPUT_FILE_REQUEST_CODE && resultCode == RESULT_OK) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (mFilePathCallback == null) {
                super.onActivityResult(requestCode, resultCode, data);
                return;
            }
            Uri[] results = new Uri[]{getResultUri(data)};

            mFilePathCallback.onReceiveValue(results);
            mFilePathCallback = null;
        } else {
            if (mUploadMessage == null) {
                super.onActivityResult(requestCode, resultCode, data);
                return;
            }
            Uri result = getResultUri(data);

            Log.d(getClass().getName(), "openFileChooser : "+result);
            mUploadMessage.onReceiveValue(result);
            mUploadMessage = null;
        }
    } else {
        if (mFilePathCallback != null) mFilePathCallback.onReceiveValue(null);
        if (mUploadMessage != null) mUploadMessage.onReceiveValue(null);
        mFilePathCallback = null;
        mUploadMessage = null;
        super.onActivityResult(requestCode, resultCode, data);
    }
}

private Uri getResultUri(Intent data) {
    Uri result = null;
    if(data == null || TextUtils.isEmpty(data.getDataString())) {
        // If there is not data, then we may have taken a photo
        if(mCameraPhotoPath != null) {
            result = Uri.parse(mCameraPhotoPath);
        }
    } else {
        String filePath = "";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            filePath = data.getDataString();
        } else {
            filePath = "file:" + RealPathUtil.getRealPath(this, data.getData());
        }
        result = Uri.parse(filePath);
    }

    return result;
}
¼Ò½º¸¦ º¸½Ã¸é ÀÌÇØ ÇϽðÚÁö¸¸, Ä«¸Þ¶ó¸¦ ÅëÇÑ °æ¿ì¿¡´Â data ³Ñ¾î¿ÀÁö ¾Ê°í mCameraPhotoPathÀÇ µ¥ÀÌÅ͸¦ ÀÌ¿ë ÇÑ´Ù.
°¶·¯¸®´Â data·Î ³Ñ¾î¿À±â ¶§¹®¿¡ ±× data¸¦ ÀÌ¿ëÇÏ¿© Àü´ÞÇØ ÁÖ¸é µÈ´Ù.

getRealPath ¼Ò½º´Â ¾Æ·¡ ¿Ã·Á ³õÀº ¼Ò½º¸¦ ÀÌ¿ëÇϼŵµ µË´Ï´Ù. UriÀÇ ½ÇÁ¦ °æ·Î¸¦ ³Ñ°ÜÁÖ´Â ¼Ò½º ÀÔ´Ï´Ù.
http://gogorchg.tistory.com/entry/Android-Get-RealPath-from-Uri

Âü°í¿ëÀ¸·Î AndroidMenifest.xml¿¡ ±ÇÇÑ ¼Ò½º ÀÌ´Ù.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />

ÀÌ ¼Ò½º¸¦ °¡Áö°í 4.4.4, 5.1.1, 6.0.2, ¿¡¼­ ¹«¸® ¾øÀÌ µ¿ÀÛÀÌ Àß µÇ´Â °ÍÀ» È®ÀÎ Çß´Ù.



Âü°í :
        https://github.com/GoogleChrome/chromium-webview-samples/blob/master/input-file-example/app/src/main/java/inputfilesample/android/chrome/google/com/inputfilesample/MainFragment.java
ÃßõÃßõ : 631 Ãßõ ¸ñ·Ï
¹øÈ£ Á¦¸ñ
1,346
À©µµ¿ì ¼­¹ö 2019 Ãë¾àÁ¡ Á¡°Ë º¸¾È
1,345
À©µµ¿ì ¼­¹ö 2019 Ãë¾àÁ¡ Á¡°Ë º¸¾È (windows server 2019)
1,344
Windows Ãë¾àÁ¡Áø´Ü º¸¾È°¡À̵å¶óÀÎ
1,343
Windows Admin Center¸¦ ÅëÇÑ ¼­¹ö °ü¸®
1,342
À©µµ¿ì ¼­¹ö¿¡¼­ ½ÇÇàµÇ´Â ¼­ºñ½º È®ÀÎ
1,341
Chrome NET::ERR CERT REVOKED ÇØ°á¹æ¹ý
1,340
cmd ¸í·É¾î (¸í·É ÇÁ·ÒÇÁÆ® ¸í·É¾î) ¸ðÀ½
1,339
Windows10 ƯÁ¤ ÇÁ·Î±×·¥(OCS 2007 R2)¿¡¼­ ÷ºÎÆÄÀÏ µå·¡±×¾Øµå·ÓÀÌ ¾È µÇ´Â Çö»ó
1,338
À©µµ¿ì ·Î±×, °ü¸® À̺¥Æ® »èÁ¦
1,337
Ŭ¸° ºÎÆÃ
1,336
Windows ±¸¼º ¿ä¼Ò ÀúÀå¼Ò¿¡¼­ ÆÄÀÏ ¼Õ»ó °Ë»ç
1,335
Windows Defender °Ë»ç ±â·Ï »èÁ¦Çϱâ
1,334
°£´ÜÇÑ À©µµ¿ì 10 Á¤Ç° ÀÎÁõ (Å©·¢ÇÁ·Î±×·¥ ÇÊ¿ä¾øÀ½)
1,333
¿À·ù³­ Æú´õ °­Á¦»èÁ¦ ¹æ¹ý
1,332
Å©·Ò¿¡¼­ Ç÷¡½Ã Ç×»ó Çã¿ëÇϵµ·Ï ¼³Á¤Çϱâ (·¹Áö½ºÆ®¸®) reg ÆÄÀÏ ¸¸µé±â
1,331
GPT µð½ºÅ©¸¦ MBR µð½ºÅ©·Î º¯È¯
1,330
MBR µð½ºÅ©¸¦ GPT µð½ºÅ©·Î º¯È¯
1,329
±¸±Û °Ë»öÀ» 200% È°¿ëÇÏ°Ô ÇØÁÖ´Â °Ë»ö ¸í·É¾î ÃÑÁ¤¸®
1,328
[Jquery] jQuery·Î ¿ìŬ¸¯ ¹æÁö, µå·¡±× ¹æÁö, ¼±Åà ¹æÁö (IE10, ÆÄÀ̾îÆø½º, Å©·Ò È®ÀÎ)
1,327
php »ç¿ëÀÚ Á¢¼ÓIP, ºê¶ó¿ìÀúÁ¤º¸, osÁ¤º¸, http, https Á¢¼ÓÇÁ·ÎÅäÄÝ ¾Ë¾Æ¿À±â
1,326
[PHP] IE ºê¶ó¿ìÀú Á¢¼Ó °ËÃâÇϱâ
1,325
À©µµ¿ì10 ½Ã½ºÅÛ ¿¹¾à ÆÄƼ¼Ç È®ÀÎ ¹× »èÁ¦
1,324
À©µµ¿ì10 º¹±¸ ÆÄƼ¼Ç »èÁ¦ ¹æ¹ý
1,323
À©µµ¿ì10 ºÎÆÃÁö¿¬ °ËÀºÈ­¸é¿¡¼­ ¸îºÐ°£ ¸Ó¹«´Â Çö»ó ÇØ°á¹æ¹ý
1,322
»ï¼º³ëÆ®ºÏ ¹ÙÀÌ¿À½º ÁøÀÔÀÌ ºÒ°¡´ÉÇÑ °æ¿ì ¹ÙÀÌ¿À½º À缳ġ¿Í NVRAM ÃʱâÈ­
1,321
ÀͽºÇ÷η¯(IE)ÀÇ ±¸±Û °Ë»ö°ø±ÞÀÚ Çѱ۷Πº¯°æ ¹æ¹ý
1,320
À©µµ¿ì 10 ±âº» ¾Û »èÁ¦ ¹× º¹±¸
1,319
meta ÅÂ±× http-equiv ¼³Á¤¹æ¹ý°ú Â÷ÀÌÁ¡
1,318
±¸±Û(Google)°Ë»ö¿¡¼­ °í±Þ¿¬»êÀÚ¸¦ ÀÌ¿ëÇÏ¿© ¸¹Àº Á¤º¸¸¦ ¾ò´Â ¹æ¹ý
1,317
ÇÁ·Î±×·¥ ¾øÀÌ Çϵåµð½ºÅ© º¹»ç ¹× ¹é¾÷Çϱâ
¸ñ·Ï
¹ÂÁ÷Æ®·ÎÆ® ºÎ»ê±¤¿ª½Ã ºÎ»êÁø±¸ °¡¾ßµ¿ ¤Ó °³ÀÎÁ¤º¸Ãë±Þ¹æħ
Copyright ¨Ï musictrot All rights reserved.