일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- kotlin
- recyclerview
- 명언모음
- Freesound
- 1인개발자
- 명심보감
- 소울칼리버6
- 공자명언
- jetpack compose
- Linux
- 이모지
- 코틀린
- 장자명언
- Coroutine
- 공부집중
- ASMR
- DART
- androidx
- 이모지메모
- FSM
- 오픈소스
- Streaming
- 좋은글필사하기
- Android
- Firebase
- Flutter
- bash
- 파이썬
- 넷플릭스
- 벤자민플랭클린
Archives
- Today
- Total
Vintage appMaker의 Tech Blog
[Webview] 웹뷰에서 fileupload 구현하기 본문
Source code or Tip/Android(Java, Kotlin)
[Webview] 웹뷰에서 fileupload 구현하기
VintageappMaker 2021. 10. 3. 14:47
App을 만들다보면 생각보다 많은 부분에서 Webview를 사용해야 할 경우가 있다. 주로 서버에서 기존에 사용했던 mobile web이 존재할 경우인데, 이 때 가끔은 Fileupload를 구현해야 할 경우가 발생한다.
Android Webview에서 Fileupload를 구현할 때는 아래와 같은 순서로 구현해야 한다.
1. 파일 읽기/쓰기 퍼미션(이미지일 경우, 카메라도 포함)
AndroidManifest.xml에서 정의하고 동적으로 구현해야 한다.
2. setWebChromeClient()에서 파라메터로 onShowFileChooser()가 오버라이드된
WebChromeClient 객체를 넘긴다.
3. onShowFileChooser()를 오버라이드할 때,
filePathCallback(ValueCallback<Array<Uri>>?)을 보관하고
startActivityForResult로 이미지나 파일정보를 가져온다.
4. onActivityResult()에서 filePathCallback의 onReceiveValue()를 호출하며
가져온 Uri 정보를 넘긴다.
[XML 소스]
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="oftenutilbox.viam.psw.Test.WebViewActivity">
<WebView
android:background="@color/black"
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
[Activity 소스]
package oftenutilbox.viam.psw.Test
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.net.Uri
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.webkit.*
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import com.test.psw.oftenutilbox.R
import com.test.psw.oftenutilbox.databinding.ActivityWebViewBinding
import oftenutilbox.viam.psw.util.toast
class WebViewActivity : AppCompatActivity() {
lateinit var binding: ActivityWebViewBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityWebViewBinding.inflate(layoutInflater)
// 퍼미션 요청
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
val b: Boolean = checkPermission()
if (b == false) {
requestPermission()
} else {
setUpUI()
}
} else {
setUpUI()
}
setContentView(binding.root)
}
private fun setUpUI() {
binding.apply {
webView.apply {
setBackgroundColor(Color.TRANSPARENT)
webViewClient = object : WebViewClient() {
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
}
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
// 주소파싱 후,
// 이동없음 -> true, 이동하기 -> false
return false
}
}
settings.apply {
javaScriptEnabled = true
builtInZoomControls = false
displayZoomControls = false
cacheMode = WebSettings.LOAD_DEFAULT
allowFileAccess = false
allowUniversalAccessFromFileURLs = false
allowFileAccessFromFileURLs = false
domStorageEnabled = true
}
addJavascriptInterface(AndroidJavascriptInterface(), "android")
setWebChromeClient(MyChrome())
val sUrl = "https://www.text-image.com/convert/ascii.html"
loadUrl(sUrl)
}
}
}
final var FILE_CHOOSE : Int = 111
fun takePicture(){
Intent(Intent.ACTION_GET_CONTENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
setType("image/*")
startActivityForResult(Intent.createChooser(this, ""), FILE_CHOOSE)
}
}
var mFileChooserCallback : ValueCallback<Array<Uri>>? =null
inner class MyChrome : WebChromeClient(){
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
override fun onShowFileChooser(
webView: WebView?,
filePathCallback: ValueCallback<Array<Uri>>?,
fileChooserParams: WebChromeClient.FileChooserParams?
): Boolean {
if (mFileChooserCallback !=null){
mFileChooserCallback!!.onReceiveValue(null)
mFileChooserCallback = null
}
mFileChooserCallback = filePathCallback
takePicture()
//return super.onShowFileChooser(webView, filePathCallback, fileChooserParams)
return true
}
}
inner class AndroidJavascriptInterface{
@JavascriptInterface
fun test(s:String){
toast(s)
}
}
// ******이 부분만 수정하면 됨 *********
// 퍼미션 종류를 나열함.
var PERMISSIONS = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA
)
private fun checkPermission(): Boolean {
for (i in PERMISSIONS.indices) {
val result = ActivityCompat.checkSelfPermission(applicationContext, PERMISSIONS[i])
if (result != PackageManager.PERMISSION_GRANTED) return false
}
return true
}
private fun requestPermission() {
ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_CODE)
}
private val REQUEST_CODE = 1112
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
when (requestCode) {
REQUEST_CODE -> if (grantResults.size > 0) {
var bResult = true
grantResults.forEach {
if ( it != PackageManager.PERMISSION_GRANTED){
bResult = false
return@forEach
}}
if ( bResult){
Toast.makeText(this, "모든 기능을 사용가능합니다.", Toast.LENGTH_LONG).show()
// [TODO] 퍼미션을 모두 수락해야만 수행가능하게 하려고 한다면
// 초기화 코드를 이곳에서 진행한다.
setUpUI()
} else{
Toast.makeText(this, "필수기능을 거부하셨습니다. 사용상 제약이 있습니다.", Toast.LENGTH_LONG).show()
finish()
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when(requestCode){
FILE_CHOOSE -> {
mFileChooserCallback!!.onReceiveValue(
if (data == null )
null
else{
if ( data!!.data == null ) null
else arrayOf<Uri>(data!!.data as Uri)
}
)
}
}
}
}
'Source code or Tip > Android(Java, Kotlin)' 카테고리의 다른 글
[Android] 화면캡쳐 방지 (0) | 2022.01.10 |
---|---|
[Android] Logcat 소스와 연동(링크)하기 (0) | 2021.12.29 |
Glide를 TextView에서 사용하기 (0) | 2021.09.21 |
WebView에서 javascript 에러가 발생할 때 (0) | 2021.09.18 |
[TextView] linecount 얻기 - ScrollView에서.. (0) | 2021.08.20 |
Comments