webView를 이용해서 android 네이티브 앱 개발시에, webView 안에 html 안에 <input type="file">은 네이티브 쪽에서 아무 처리도 해주지 않으면, 아무런 반응도 일어나지 않습니다. 이것을 구현하는 방법을 소개 하겠습니다.
1. WebView 객체 만들기
먼저, WebView 객체를 만들어 줍니다.
WebView myWebView = (WebView) findViewById(R.id.webview);
2. onShowFileChooser 함수 구현
<input type="file"> 이것을 android 네이티브에서도 처리해 주기 위해서는 WebChromeClient.onShowFileChooser()을Override 해주어야 합니다.
public static final int IMAGE_SELECTOR_REQ = 1;
private ValueCallback mFilePathCallback;
myWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) {
mFilePathCallback = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
//여러장의 사진을 선택하는 경우 필요 <input type="file" multiple>
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent,"Select Picture"), IMAGE_SELECTOR_REQ);
return true;
}
});
1. webChromeClient는 전체 화면 지원 사용 설정. WebView가 창을 만들거나 닫고 자바스크립트 대화상자를 사용자에게 전송하는 등 호스트 앱의 UI를 변경하기 위한 권한을 필요로 할 때도 호출 됩니다.
2. mFilePathCallback은 추후 file의 uri를 webView로 전달해 주기 위한 전역 변수 필요.
3. intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)은 <input type="file" multiple>의 경우 필요.
2. onActivityResult 함수 구현
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == IMAGE_SELECTOR_REQ) {
if (resultCode == Activity.RESULT_OK) {
if (data.getClipData() != null) {
int count = data.getClipData().getItemCount();
Uri[] uris = new Uri[count];
for (int i = 0; i < count; i++)
uris[i] = data.getClipData().getItemAt(i).getUri();
mFilePathCallback.onReceiveValue(uris);
} else if (data.getData() != null) {
mFilePathCallback.onReceiveValue(new Uri[]{data.getData()});
}
}
}
}
1. <input type="file" multiple>의 경우 data.getClipData()의 file 정보를 확인 할수 있습니다.
2. <input type="file">의 경우 또는 1장의 image를 업로드 하는 경우에 data.getData()를 통해 file 정보를 확인 할수 있습니다.
3. mFilePathCallback.onReceiveValue()로 webView의 file uri 정보를 보낼수 있습니다.
전체 소스
public class TestActivity extends AppCompatActivity {
....
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myWebView = (WebView) findViewById(R.id.webview);
myWebView.setWebChromeClient(new MyWebChromeClient());
myWebView.loadUrl(SERVER_IP);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK){
switch (requestCode) {
case IMAGE_SELECTOR_REQ:
if (data.getClipData() != null) {
int count = data.getClipData().getItemCount();
Uri[] uris = new Uri[count];
for (int i = 0; i < count; i++)
uris[i] = data.getClipData().getItemAt(i).getUri();
mFilePathCallback.onReceiveValue(uris);
} else if (data.getData() != null) {
mFilePathCallback.onReceiveValue(new Uri[]{data.getData()});
}
break;
}
}
}
private class MyWebChromeClient extends WebChromeClient {
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
mFilePathCallback = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent,"Select Picture"), IMAGE_SELECTOR_REQ);
return true;
}
}
}
갤러리앱 다중 선택 지원
네이티브앱에서 이미지 다중 선택을 위해서는, 사용자에게 갤러리앱 or 구글 포토앱 으로 연결 할수 있도록, 사용자에게 권할수 있습니다. 구글 포토앱 으로 연결 시, 이미지 다중 선택을 할수 있고, 갤러리앱 으로 연결 시, 이미지 다중 선택을 현재는 지원하지는 않습니다. 만약, 갤러리앱 에서도 이미지 다중 선택을 지원하게 하려면, 커스텀 갤러리앱을 따로 개발을 해야 합니다. 갤러리앱 or 구글 포토앱으로 연결 유도를 위해서는 onShowFileChooser 함수가 아래와 같이 변경되어야 합니다.
@Override
// 갤러리 다중 선택 갤러리앱 or 구글 포토 연결 선택으로 변경
public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
mFilePathCallback = filePathCallback;
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
startActivityForResult(Intent.createChooser(intent,"Select Picture"), IMAGE_SELECTOR_REQ);
return true;
}
'Android' 카테고리의 다른 글
WebView 기반 안드로이드 네이티브 앱 개발4(스플래쉬 화면) (0) | 2020.06.08 |
---|---|
WebView 기반의 안드로이드 네이티브 앱 개발 3 (뒤로가기) (0) | 2020.05.27 |
WebView 기반의 안드로이드 네이티브 앱 개발 2 (JavaScript 설정) (0) | 2020.05.22 |
WebView 기반의 안드로이드 네이티브 앱 개발1(WebView load) (0) | 2020.05.20 |
ERR_CLEARTEXT_NOT_PERMITTED (0) | 2020.05.18 |