flutter로 안드로이드 사진 파일 첨부 시 파일 첨부가 안되는 오류가 발생하였다.
Chrome 모바일 버전과 iOS에서는 파일 첨부가 잘 되고 있지만 안드로이드만 안된다.
또 ,,, 안드로이드 배포는 targetSdkVersion을 34 이상으로 해야한다고 한다.
**중요 *
2024년 9월 2일 작성
Adnroid 14 이상부터 사진/동영상 일부 접근 권한 (사진/동영상의 일부 접근 권한) 추가
AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" tools:node="remove" />
dart
void imagePicker(String call) async {
final picker = ImagePicker();
final XFile? pickedFile = await picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
final bytes = await File(pickedFile.path).readAsBytes();
final base64String = base64Encode(bytes);
final Map<String, String> result = {
'base64String': base64String,
'fileName': pickedFile.name,
'fileExt': pickedFile.name.split('.').last.toLowerCase()
};
send(call: call, data: jsonEncode(result));
} else {
alert(title: '오류', msg: '이미지를 선택하세요.');
}
}
vuejs
<template>
<div class="py-[1.125rem] relative flex">
<label for="file01">
<div class="break-keep text-[#0E66F2] pr-6 text-base reading-file flex items-center" @click="triggerFileInput('file01')">파일 선택</div>
</label>
<input type="file" id="file01" hidden accept="image/*" @change="onChangeFile($event, 'file01')">
</div>
</template>
<script>
methods: {
triggerFileInput(fileType) {
this.fileType = fileType
const platform = window.$nativeManager.getPlatform();
if (platform === 'android') {
window.$nativeManager.call({
call: 'imagePicker',
data: {},
});
}
},
onImageSelected(imageData) {
const fileName = imageData.fileName;
const base64String = imageData.base64String;
const fileExt = imageData.fileExt;
const mimeTypes = {
'png': 'image/png',
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg'
};
const mimeString = mimeTypes[fileExt] || 'application/octet-stream';
// Base64 문자열을 디코드하여 ArrayBuffer로 변환
const byteString = atob(base64String);
const arrayBuffer = new ArrayBuffer(byteString.length);
const uintArray = new Uint8Array(arrayBuffer);
for (let i = 0; i < byteString.length; i++) {
uintArray[i] = byteString.charCodeAt(i);
}
// Blob을 File로 변환
const file = new File([arrayBuffer], fileName, { type: mimeString });
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file);
const inputElement = document.getElementById(this.fileType);
inputElement.files = dataTransfer.files;
const e = { target: { files: dataTransfer.files } };
this.onChangeFile(e, this.fileType);
},
onChangeFile(e, key) {
const fileList = e.target.files
const addFileList = []
for (const element of fileList) {
const file = element
const fileSize = file.size
const fileExt = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase()
if (fileSize > this.fileMaxSize) {
window.cmimToast('첨부파일의 크기는 최대 10MB로 제한됩니다.')
console.log('10MB 가 넘어서 파일일 추가 할 수 없음')
continue
}
if (this.fileExts.indexOf(fileExt) === -1) {
window.cmimToast(`첨부파일은 ${this.fileExts.join(',')}의 확장자만 등록 가능합니다.`)
console.log(this.fileExts.join(','), '확장자만 가능')
continue
}
addFileList.push(file)
}
this[key] = addFileList
this[key + 'Error'] = false
e.target.value = null;
},
}
</script>
'프로그래밍 언어 > Flutter' 카테고리의 다른 글
[Flutter] iOS 파일 다운로드(파일 앱 저장, 공유하기 팝업창 생성) (0) | 2025.03.01 |
---|---|
[Flutter] 스크린샷 방지(Android) 및 검은색 화면으로 캡쳐(iOS) 방법 (0) | 2025.02.28 |