[Android] 웹뷰 input[type="file"] 사진 촬영 & 갤러리 접근

딱이·2021년 4월 21일
0
post-custom-banner
[MainActivity.java]
private void webViewSetting() {
  ...
  mBinding.wvMain.setWebChromeClient(new WebChromeClient() {	
  
      // input 클릭시 바로 실행되는 부분
      @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
      public boolean onShowFileChooser( WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {

          // Callback 초기화
          if (filePathCallbackLollipop != null) {
              filePathCallbackLollipop.onReceiveValue(null);
              filePathCallbackLollipop = null;
          }
          filePathCallbackLollipop = filePathCallback;

          boolean isCapture = fileChooserParams.isCaptureEnabled();

          runCamera(isCapture);
          return true;
      }

  });
  ...
}


public ValueCallback<Uri> filePathCallbackNormal;
public ValueCallback<Uri[]> filePathCallbackLollipop;
public final static int FILECHOOSER_NORMAL_REQ_CODE = 2001;
public final static int FILECHOOSER_LOLLIPOP_REQ_CODE = 2002;
private Uri cameraImageUri = null;


// 카메라 기능 구현
private void runCamera(boolean _isCapture, int selectedType) {
	Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

	File path = Environment.getExternalStorageDirectory();
	File file = new File(path, "temp.png"); // temp.png 는 카메라로 찍었을 때 저장될 파일명이므로 사용자 마음대로

	cameraImageUri = Uri.fromFile(file);
	intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, cameraImageUri);

	if (!_isCapture) { // 선택팝업 카메라, 갤러리 둘다 띄우고 싶을 때
		Intent pickIntent = new Intent(Intent.ACTION_PICK);

		if (selectedType == 1) {
			pickIntent.setType(MediaStore.Images.Media.CONTENT_TYPE);
			pickIntent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
		}
		else if(selectedType == 2) {
			pickIntent.setType(MediaStore.Video.Media.CONTENT_TYPE);
			pickIntent.setData(MediaStore.Video.Media.EXTERNAL_CONTENT_URI);
		}

		String pickTitle = "사진 가져올 방법을 선택하세요.";
		Intent chooserIntent = Intent.createChooser(pickIntent, pickTitle);

		// 카메라 intent 포함시키기..
		chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{intentCamera});
		startActivityForResult(chooserIntent, FILECHOOSER_LOLLIPOP_REQ_CODE);
	}
	else {// 바로 카메라 실행..
		startActivityForResult(intentCamera, FILECHOOSER_LOLLIPOP_REQ_CODE);
	}
}


// 액티비티가 종료될 때 결과를 받고 파일을 전송할 때 사용
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	switch (requestCode) {
		case FILECHOOSER_NORMAL_REQ_CODE:
			if (resultCode == RESULT_OK) {
				if (filePathCallbackNormal == null) return;
				Uri result = (data == null || resultCode != RESULT_OK) ? null : data.getData(); //  onReceiveValue 로 파일을 전송한다.

				filePathCallbackNormal.onReceiveValue(result);
				filePathCallbackNormal = null;
			}
			break;
		case FILECHOOSER_LOLLIPOP_REQ_CODE:
		
			if (resultCode == RESULT_OK) {
				if (filePathCallbackLollipop == null) return;
				if (data == null)
					data = new Intent();
				if (data.getData() == null)
					data.setData(cameraImageUri);

				filePathCallbackLollipop.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data));
				filePathCallbackLollipop = null;

			} else {
				if (filePathCallbackLollipop != null) {   //  resultCode에 RESULT_OK가 들어오지 않으면 null 처리하지 한다.(이렇게 하지 않으면 다음부터 input 태그를 클릭해도 반응하지 않음)
					filePathCallbackLollipop.onReceiveValue(null);
					filePathCallbackLollipop = null;
				}

				if (filePathCallbackNormal != null) {
					filePathCallbackNormal.onReceiveValue(null);
					filePathCallbackNormal = null;
				}
			}
			break;
		default:

			break;
	}

	super.onActivityResult(requestCode, resultCode, data);
}
[html]
<form id="inputForm" method="post" action="" enctype="multipart/form-data">
	<input type="file" style="display: none" name="img1" accept="image/*"/>
	<input type="file" style="display: none" name="img2" accept="image/*"/>
    
    <button type="button">업로드</button>
</form>
		
profile
뚝딱뚝딱 FE
post-custom-banner

0개의 댓글