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


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
ÃßõÃßõ : 632 Ãßõ ¸ñ·Ï
¹øÈ£ Á¦¸ñ
1,286
[Android] webview ssl ¹®Á¦
1,285
[Android] Webview url ¼û±â±â
1,284
[Android] AlarmManager ÀÏÁ¤½Ã°£ À̺¥Æ® ½ÇÇà
1,283
¾Èµå·ÎÀÌµå ¿ÀǼҽº ³¡ÆÇ
1,282
android studio DefaultHttpClient, HttpClient import ¿¡·¯
1,281
[Android] Webview ¸Þ¼Òµå
1,280
¾Èµå·ÎÀ̵å: ¼­ºñ½º Service ¿¹Á¦
1,279
[Android] Effect (¿Àµð¿À¸ðµå) º§¸ðµå, Áøµ¿¸ðµå, ¹«À½¸ðµå½Ã µ¿ÀÛó¸®
1,278
Mediaplayer ·Î ÁöÁ¤µÇ¾îÀÖ´Â º§¼Ò¸® Àç»ýÇϱâ
1,277
Android Intent - ¾Èµå·ÎÀ̵å ÀÎÅÙÆ®
1,276
[Android Intent Useage] ¾Èµå·ÎÀ̵å Intent »ç¿ë ¹æ¹ý
1,275
SharedPreferences¶õ?
1,274
ÀÎÅÙÆ®(Intent)·Î µ¥ÀÌÅÍ Àü´Þ(putExtra, getExtras)
1,273
¾Èµå·ÎÀÌµå ±¸±Û ¾Öµå¸÷ Àü¸é±¤°í ³Ö±â
1,272
¾Èµå·ÎÀÌµå µÚ·Î°¡±â ¹öÆ° ´õºíŬ¸¯Çؼ­ ¾Û Á¾·áÇϱâ
1,271
¾Ë¸²Ã¢ ¶ç¿ì±â(Multi Choice, Single Choice)
1,270
Android SharedPreferences »ç¿ë ¿¹Á¦
1,269
¾Èµå·ÎÀ̵å PHP GET ¹æ½Ä Åë½Å¿¡¼­ ÇÑ±Û ±úÁü(?) ÇØ°á
1,268
¾Èµå·ÎÀÌµå ¾Û ÃÖÃÊ ½ÇÇà½Ã ¹ÙÅÁÈ­¸é¿¡ ¾ÆÀÌÄÜ(Shortcut) »ý¼ºÇϱâ
1,267
ÇöÀç½Ã°£(Local Time) °¡Á®¿À±â
1,266
ÆÄÀÏ »ý¼º ¹× ÀúÀå
1,265
µÚ·Î°¡±â(Back ¹öÆ°) µÎ¹ø ´­·¯ ¾Û Á¾·áÇϱâ
1,264
Custom ListView (Ä¿½ºÅÒ ¸®½ºÆ®ºä) Footer¸¦ ÀÌ¿ëÇÑ ´õº¸±â ±¸Çö
1,263
CheckBox(üũ¹Ú½º) À̹ÌÁö º¯°æÇϱâ
1,262
C¼­¹ö¿Í ¼ÒÄÏÅë½Å
1,261
½½¶óÀ̵ù ¸Þ´º - SimpleSideDrawer
1,260
selector·Î ¹öÆ° ¾×¼Ç À̹ÌÁö º¯°æ
1,259
À̹ÌÁö¹öÆ° »çÀÌÁî Á¶Àý
1,258
XmlPullParser °£´ÜÇÑ »ç¿ë¹ý
1,257
¹öÆ°»çÀÌ ¿©¹é ¾ø¾Ö±â
¸ñ·Ï
¹ÂÁ÷Æ®·ÎÆ® ºÎ»ê±¤¿ª½Ã ºÎ»êÁø±¸ °¡¾ßµ¿ ¤Ó °³ÀÎÁ¤º¸Ãë±Þ¹æħ
Copyright ¨Ï musictrot All rights reserved.