input type="file" 인 HTML 폼에 파일 업로드 하는 방법 및 추가적인 UI 설정
1. 파일 업로드
- Activity에 전역으로 ValueCallback<Array<Uri>> 변수 생성
private var uploadMessage: ValueCallback<Array<Uri>>? = null
private val fileChooserCallback = //launch할 callback 설정
registerForActivityResult(ActivityResultContracts.OpenDocument()) {
if (it == null) { // 아무것도 선택하지 않았을때
uploadMessage?.onReceiveValue(null)
uploadMessage = null
return@registerForActivityResult
}
try {
uploadMessage?.onReceiveValue(arrayOf(it))
uploadMessage = null
Toast.makeText(this, "업로드 성공", Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
Toast.makeText(this, "업로드 실패", Toast.LENGTH_SHORT).show()
e.printStackTrace()
}
}
webChromeClient = BodyWebChromeClient(this@WebViewActivity)
class BodyWebChromeClient(activity: WebViewActivity) : WebChromeClient() {
private val activityRef = WeakReference(activity)
override fun onShowFileChooser(
webView: WebView?,
filePathCallback: ValueCallback<Array<Uri>>?,
fileChooserParams: FileChooserParams?
): Boolean {
val activity = activityRef.get() ?: return false
fileChooserParams?.acceptTypes?.get(0)?.toString() ?: return false
activity.checkPermission(filePathCallback) //권한 검사 시작
return true
}
}
//TedPermission 이용
private fun checkPermission(filePathCallback: ValueCallback<Array<Uri>>?) {
TedPermission.Builder()
.setPermissionListener(object : PermissionListener {
override fun onPermissionGranted() {
if (uploadMessage != null) {
uploadMessage?.onReceiveValue(null)
}
uploadMessage = filePathCallback
fileChooserCallback.launch(arrayOf("*/*"))
}
override fun onPermissionDenied(deniedPermissions: MutableList<String>?) {
Toast.makeText(this@WebViewActivity, "권한이 없습니다.", Toast.LENGTH_SHORT).show()
}
})
.setDeniedMessage("이 권한이 없으면 이력서를 업로드할 수 없습니다.")
.setPermissions(
Manifest.permission.READ_EXTERNAL_STORAGE
).check()
}
포인트
it : Uri! 라고 되어있어 널체크가 필요없을것으로 생각했지만 nullable.
아무것도 선택되지 않는 경우 null을 반환,
2. 추가 UI 설정
투박한 자바스크립트 팝업 대신 앱의 AlertDialog 로 override
override fun onJsConfirm(
view: WebView?,
url: String?,
message: String?,
result: JsResult?
): Boolean {
val activity = activityRef.get() ?: return false
BodyAlertDialog.Builder(activity.baseContext)
.setMessage(message ?: "")
.setPositiveButton("확인")
.show()
return true
}
로딩 처리
- 처음 로딩을 true 로 시작한다
onPageCommitVisible : 페이지가 처음 보이면 로딩 off
onPageStarted : 다른 페이지로 이동할때 로딩 on
onPageFinished : 다른 페이지가 로드 되면 로딩 off
override fun onPageCommitVisible(view: WebView?, url: String?) {
super.onPageCommitVisible(view, url)
setLoading(false)
}
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
setLoading(true)
}
override fun onPageFinished(view: WebView?, url: String?) {
setLoading(false)
super.onPageFinished(view, url)
}
private fun setLoading(isLoad: Boolean) {
val activity = activityRef.get() ?: return
activity.viewDataBinding.pgbLoading.isGone = !isLoad
}
'Android' 카테고리의 다른 글
Facebook Login Trouble Shooting (0) | 2022.07.18 |
---|---|
Fragment 공부 (0) | 2022.06.24 |
"좋아요" 동기화 (로컬 싱크 맞추기, Rx 이용) (0) | 2022.03.14 |
액티비티간, fragment간 값 전달 하기 (ViewModel X) (0) | 2022.02.12 |
쿠키로 Auth인증하는 방법 (Interceptor 첨부) (0) | 2022.02.12 |