vue로 작성된 프로젝트에 input type file을 사용해 파일 업로드 기능을 만든 뒤 안드로이드에서 input을 눌러도 아무 반응이 없었다.
찾아보니 웹에서는 정상적으로 작동하지만 안드로이드에서 정상적으로 작동하기 위해선 웹앱 코드를 수정해야된다는 정보를 알게 되었다.
내가 원했던건 input 클릭시 카메라는 선택할수 없고 갤러리만 접근해서 파일을 올리는 로직이였다.
몇시간을 헤맨 끝에..ㅜ 성공 코드!
AndroidManifest.xml 파일
<manifest>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
</manifest>
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val myWebView: WebView = findViewById(R.id.webview)
myWebView.webChromeClient = object :WebChromeClient() {
override fun onShowFileChooser(
webView: WebView,
filePathCallback: ValueCallback<Array<Uri>>,
fileChooserParams: FileChooserParams
): Boolean {
if (mFilePathCallback != null) {
mFilePathCallback?.onReceiveValue(null)
}
mFilePathCallback = filePathCallback
imageChooser()
return true
}
private fun imageChooser() {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
if (takePictureIntent.resolveActivity(packageManager) != null) {
var photoFile: File? = null
try {
photoFile = createImageFile()
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.absolutePath
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile))
}
} catch (ex: IOException) {
Log.e(javaClass.name, "Unable to create Image File", ex)
}
val galleryIntent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
galleryIntent.type = TYPE_IMAGE
val intentArray = if (photoFile != null) {
arrayOf(takePictureIntent)
} else {
arrayOf<Intent>()
}
val chooserIntent = Intent(Intent.ACTION_CHOOSER)
chooserIntent.putExtra(Intent.EXTRA_INTENT, galleryIntent)
chooserIntent.putExtra(Intent.EXTRA_TITLE, "이미지 선택")
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE)
}
}
}
}
@Throws(IOException::class)
private fun createImageFile(): File {
val imageFileName = "JPEG_"
val storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
val imageFile = File.createTempFile(imageFileName, ".jpg", storageDir)
return imageFile
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
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
}
val results = arrayOf(getResultUri(data) as Uri)
mFilePathCallback?.onReceiveValue(results)
mFilePathCallback = null
} else {
if (mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data)
return
}
val result = getResultUri(data)
mUploadMessage?.onReceiveValue(result)
mUploadMessage = null
}
} else {
mFilePathCallback?.onReceiveValue(null)
mUploadMessage?.onReceiveValue(null)
mFilePathCallback = null
mUploadMessage = null
super.onActivityResult(requestCode, resultCode, data)
}
}
private fun getResultUri(data: Intent?): Uri? {
var result: Uri? = null
if (data == null || TextUtils.isEmpty(data.dataString)) {
if (mCameraPhotoPath != null) {
result = Uri.parse(mCameraPhotoPath)
}
} else {
val filePath: String = data.dataString ?: ""
result = Uri.parse(filePath)
}
return result
}
}