๋ชฉ๋กAndroid/Android Studio (49)
๐ฑ dreaming DiNO
์ฌ์ฉ์๊ฐ ์ ํํ Local data ๋ฅผ ์ญ์ ํ๋ ๊ณผ์ ๋ฐฉ๋ฒ 1. 1. file name ๋ง ๋ค์ด๊ฐ ์๋ ์๋ก์ด arrayList() ์ ๋ง๋ ๋ค. 2. arrayList.contains ๋ฅผ ํ์ฉํ๋ค. private fun deleteLocalData(selectedList: ArrayList) { BleDebugLog.i(logTag, "deleteLocalData-()") val selectedNameList = ArrayList() selectedList.forEach { selectedNameList.add(it.name) } val directory = File(path) val files = directory.listFiles() files?.forEach { file -> if (file.is..
// Exif Orientation ๊ฐ ํ์ธ val exif = ExifInterface(context?.contentResolver?.openFileDescriptor(resultUri, "rw", null)!!.fileDescriptor) val exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL) VCDebugLog.i(logTag, "before: $exifOrientation") // 0 exif.setAttribute(ExifInterface.TAG_ORIENTATION, (ExifInterface.ORIENTATION_NORMAL).toString()) exif..

build.gradle ์๋์ฒ๋ผ ์ธํ ํด ๋์๋ค๋ฉด dependencies { implementation fileTree(dir: 'libs', include: ['*.aar']) } ์๋ก ๋ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ.aar ๋ง Project ๋ชจ๋๋ก ํด์ ๊ธฐ์กด๊บผ ์ญ์ , ์๋ก์ด๊ฑฐ ์ถ๊ฐ๋ง ํด์ ๋ฐ๊ฟ์ฃผ๋ฉด ๋! *์ ๊น Tip, JAR ์ AAR ์ฐจ์ด Jarํ์ผ์ Java ARchive ์ ์ฝ์๋ก ์๋ฐ๋ก ์์ฑ๋ ํด๋์คํ์ผ๊ณผ ์ด๋ฏธ์ง๋ฑ์ ๋ฆฌ์์ค ํ์ผ๋ค์ ํฌํจ๋๋ค. โ AARํ์ผ์ Android ARchive ์ ์ฝ์๋ก, ์๋๋ก์ด๋์ ํนํ๋ Jarํ์ผ์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค. AARํ์ผ์ ์๋๋ก์ด๋์ layouts, drawables ๋ฑ์ด ํฌํจ๋ ์ ์๋ค.
Uri๋ฅผ String์ผ๋ก ๋ฐ๊พธ๊ธฐ Uri uri; String str = uri.toString(); String์ Uri๋ก ๋ฐ๊พธ๊ธฐ String str = "๋ฌธ์์ด"; Uri uri = Uri.parse(str);

2. data ์์ ๋ญ๋ญ ์๋์ง ํ์ธํ๋ ค๊ณ log๋ฅผ ์ฐ๊ธฐ์ ๋๋ฌด ๋ฒ๊ฑฐ๋ก์... ๊ทธ๋์ ํ ๊ฒ ๋ชจ๋ค? + ๋๋ฌ์ ๋ณ์๋ฅผ ๊ฒ์ํ๋ค. ex) auth.current.email ๊ทธ๋ฌ๋ฉด ์์ ๋ด๊ธด data ๋ฅผ ํ์ธ ํ ์ ์๋ค! WoW! 3. ๋๋ signOut() ํจ์ ์ดํ์ ์ ๋ง ์ ์ ์ ๋ณด๊ฐ ์ฌ๋ผ์ก๋์ง ํ์ธํ๊ธฐ ์ํด Debug๋ฅผ ์ฐ์ด ๋ดค๋ค. ๋ค ๋๊ณ ๋์ auth.currentUser.email ์ด ๊ณ์ ์ด ์์๋ค๊ฐ Null ๋ก ๋ณ๊ฒฝ๋์์์ ํ์ธ!

[๋ฌธ์ ๋ฐ์] ๋ก๊ทธ์ธํ ๊ตฌ๊ธ ๊ณ์ ์ด ์ฌ๋ฌ๊ฐ ๋จ๊ธด ํ๋๋ฐ, ์ ํํ๋ฉด ํ๋ฉด์ ํ์ด ์๋๊ณ ์๋ฌด ๋ฐ์์ด ์์์ [๋ฌธ์ ํด๊ฒฐ] SHA-1 ์ถ๊ฐ 1. SHA-1 ํ์ธํ๊ธฐ Terminal ์๋ ๋ช ๋ น์ด ์คํ ./gradlew signingReport ์๋์ ์ฌ์ง์ฒ๋ผ ๋ค์๊ณผ ๊ฐ์ด ๋์จ๋ค๋ฉด ์ฑ๊ณต์ ๋๋ค. ์ฌ๊ธฐ์ ํ์ํ SHA-1์ ์ ๋ณด๋ฅผ Firebase๋ ๋ ๋ค๋ฅธ๊ณณ์์ ํ์๋กํ๋ ๊ณณ์์ ํ์ํ ์ ๋ณด๋ฅผ ๊ฐ์ ธ๋ค๊ฐ ์ฌ์ฉํ์๋ฉด ๋๊ฒ ์ต๋๋ค. ./gradlew signingReport ๋ช ๋ น์ด ์คํํ ๋ชจ์ต 2. SHA1 ๋ณต์ฌ -> Firebase console ๋์งํธ ์ง๋ฌธ ์ถ๊ฐ

๐ฅบ ์๋ฌ ๋ฐ์ java.lang.RuntimeException: Exception while computing database live data. at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:92) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:764) Caused by: java.lang.NullPointerExc..

๐ก Fragment ์์ ๊ฐค๋ฌ๋ฆฌ ์ด๋ฏธ์ง ๋ค์ค ์ ํํ์ฌ Uri Data ์ป์ ํ์์ฑ : ๊ฐค๋ฌ๋ฆฌ๋ฅผ Intent๋ก 1. gradle ์ถ๊ฐ //EventBus implementation 'org.greenrobot:eventbus:3.2.0' 2. ๊ฐค๋ฌ๋ฆฌ ์ฌ์ง ์ ํ ๋์ฐ๊ธฐ // ์ฌ์ง ์ถ๊ฐ ๋ฒํผ binding.addPhotoBtn.setOnClickListener { // CropImage.activity() // .start(requireContext(), this) // ๊ฐค๋ฌ๋ฆฌ ๋ค์ค์ด๋ฏธ์ง ์ ํ ๋์ฐ๊ธฐ val intent = Intent(Intent.ACTION_PICK) intent.type = MediaStore.Images.Media.CONTENT_TYPE intent.putExtra(Intent.EXTR..

ํ ์ด๋ธ์ ์ฌ์ฉ์๊ฐ ์ถ๊ฐํ ์ฌ์ง์ ์ ์ฅํ๊ธฐ ์ํด image column ์ด ์ถ๊ฐ๋ ํ์์ฑ ์๊น 1. Room์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก primitive type๊ณผ ๊ทธ wrapping ํ์ ๋ง ์ง์ ํ์ง๋ง ๋๋ image uri์ path๋ฅผ List๋ก ์ ์ฅ์ ํ๋ ค๊ณ ํ๋ค 2. Gson ์ด์ฉํ์ฌ TypeConverter ํด๋์ค ์์ฑ TypeConverter Room์ primitive type์ด ์๋ ๋ค๋ฅธ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ธฐ ์ํด์ Room์์ ์ ๊ณตํ๋ TypeConverter ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค. class Converters { @TypeConverter fun fromTimestamp(value: Long?): Date? { return value?.let { Date(it) } }..

์ ๊ฐ empty์ blank๊ฐ ๋งค์ผ ํท๊ฐ๋ ค์ ํ์คํ๊ฒ ์ง๊ณ ๋์ด๊ฐ๋ ค๊ณ ํฉ๋๋ค. String Validation ํ์ธ ์ค, ์์ฃผ ์ฌ์ฉํ๋ Null, Empty, Blank์ ์ฐจ์ด๋ฅผ ์์๋ณด๊ฒ ์ต๋๋ค. ์๋์ ์ฝ๋๋ค์ group: org.apache.commons, name: commons-lang3, version: 3.11 ์ ๋๋ค. Null ๋ณ์์ ์๋ฌด๊ฒ๋ ํ ๋น๋์ง(์ฐธ์กฐํ์ง) ์์ ์ํ๋ฅผ ์๋ฏธํฉ๋๋ค. Empty empty(๋น์ด์๋) : ๋ฌธ์์ด์ ๊ธธ์ด๊ฐ 0์์ ์๋ฏธํฉ๋๋ค. ์๋๋ StringUtils.isEmpty ์ฝ๋์ ๋๋ค. ๋์ฌ๊ฒจ ๋ณด์ค ์ ์ ""๊ณผ " "์ ์ฐจ์ด์ ๋๋ค. empty๋ length = 0์ ์๋ฏธํ๊ธฐ ๋๋ฌธ์ " "๊ฐ์ false๋ก ๋ฐํ ๋ฉ๋๋ค. StringUtils.isEmpty // Empty..