-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature/qr] QR코드 인식 및 사진 불러오기 기능 작업 #314
Changes from 10 commits
5c5c533
95034ae
bd17c3b
3577bda
c1cb67d
8535085
3e0b87b
576944f
b8ccdac
a3c97a0
2222650
e5fddae
154728e
88a8be9
261d516
5928b34
bc2df6a
394a5eb
299ee26
721f5c4
80bb168
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,6 +10,7 @@ plugins { | |
alias(libs.plugins.app.distribution) | ||
alias(libs.plugins.crashlytics) | ||
id("com.google.android.gms.oss-licenses-plugin") | ||
alias(libs.plugins.kotlin.android) | ||
} | ||
|
||
val properties = Properties().apply { | ||
|
@@ -107,6 +108,9 @@ dependencies { | |
implementation(libs.coil.core) | ||
implementation(libs.bundles.retrofit) | ||
implementation(libs.kakao.login) | ||
implementation(libs.zxing.android.embedded) | ||
implementation(libs.appcompat) | ||
implementation(libs.material) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 삭제! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 삭제!! |
||
|
||
debugImplementation(libs.bundles.flipper) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
|
||
<uses-permission android:name="android.permission.INTERNET" /> | ||
<uses-permission android:name="com.google.android.gms.permission.AD_ID" /> | ||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예전에 사용해본 기억으로 당연히 사용하는줄 알았는데 몰랐습니다! 하위버전 대응하는 목적으로 그냥 두고 알고 있겠습니다! |
||
|
||
<application | ||
android:name=".App" | ||
|
@@ -17,6 +18,9 @@ | |
android:theme="@style/Theme.Pophory" | ||
android:usesCleartextTraffic="true" | ||
tools:targetApi="31"> | ||
<activity | ||
android:name=".feature.qr.QRActivity" | ||
android:exported="true" /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. exported false ! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 앗 걸렸다! |
||
<activity | ||
android:name=".feature.share.ShareActivity" | ||
android:exported="false" /> | ||
|
@@ -68,10 +72,12 @@ | |
android:exported="false" /> | ||
<activity | ||
android:name=".feature.home.HomeActivity" | ||
android:exported="true" > | ||
android:exported="true"> | ||
<intent-filter> | ||
<action android:name="android.intent.action.SEND" /> | ||
|
||
<category android:name="android.intent.category.DEFAULT" /> | ||
|
||
<data android:mimeType="image/*" /> | ||
</intent-filter> | ||
</activity> | ||
|
@@ -80,7 +86,7 @@ | |
android:exported="false" | ||
android:windowSoftInputMode="adjustResize" /> | ||
<activity | ||
android:name="com.teampophory.pophory.onboarding.OnBoardingActivity" | ||
android:name=".onboarding.OnBoardingActivity" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 리베이스 해도 이렇게 바뀌나..? 모듈 분리해서 com.teampophory.pophory 있어야 할 것 같은데 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 다시 com.teampophory.pophory로 반영하겠습니다! |
||
android:exported="true" | ||
android:theme="@style/Theme.App.Pophory.Starting"> | ||
<intent-filter> | ||
|
@@ -141,4 +147,4 @@ | |
android:exported="false" /> | ||
</application> | ||
|
||
</manifest> | ||
</manifest> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,8 +3,6 @@ package com.teampophory.pophory.feature.home | |
import android.content.Context | ||
import android.content.Intent | ||
import android.os.Bundle | ||
import androidx.activity.result.PickVisualMediaRequest | ||
import androidx.activity.result.contract.ActivityResultContracts | ||
import androidx.activity.viewModels | ||
import androidx.appcompat.app.AppCompatActivity | ||
import androidx.fragment.app.Fragment | ||
|
@@ -13,8 +11,8 @@ import com.teampophory.pophory.R | |
import com.teampophory.pophory.common.context.stringOf | ||
import com.teampophory.pophory.common.view.viewBinding | ||
import com.teampophory.pophory.databinding.ActivityHomeBinding | ||
import com.teampophory.pophory.feature.home.add.AddPhotoBottomSheet | ||
import com.teampophory.pophory.feature.home.mypage.MyPageFragment | ||
import com.teampophory.pophory.feature.home.photo.AddPhotoActivity | ||
import com.teampophory.pophory.feature.home.store.StoreFragment | ||
import com.teampophory.pophory.util.dialog.DialogUtil | ||
import dagger.hilt.android.AndroidEntryPoint | ||
|
@@ -23,22 +21,6 @@ import dagger.hilt.android.AndroidEntryPoint | |
class HomeActivity : AppCompatActivity() { | ||
private val binding: ActivityHomeBinding by viewBinding(ActivityHomeBinding::inflate) | ||
private val viewModel by viewModels<HomeViewModel>() | ||
private val addPhotoResultLauncher = | ||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { | ||
if (it.resultCode == RESULT_OK) { | ||
viewModel.eventAlbumCountUpdate() | ||
} | ||
} | ||
|
||
private val imagePicker = | ||
registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri -> | ||
val currentAlbumPosition = viewModel.homeState.value.currentAlbumPosition | ||
val albumItem = viewModel.homeState.value.currentAlbums?.getOrNull(currentAlbumPosition) | ||
if (uri != null && albumItem != null) { | ||
val intent = AddPhotoActivity.getIntent(this, uri.toString(), albumItem) | ||
addPhotoResultLauncher.launch(intent) | ||
} | ||
} | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
|
@@ -75,7 +57,8 @@ class HomeActivity : AppCompatActivity() { | |
return@setOnClickListener | ||
} | ||
} | ||
imagePicker.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)) | ||
val modalBottomSheet = AddPhotoBottomSheet() | ||
modalBottomSheet.show(supportFragmentManager, AddPhotoBottomSheet.TAG) | ||
Comment on lines
+60
to
+61
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍🏻 |
||
} | ||
} | ||
|
||
|
@@ -92,7 +75,6 @@ class HomeActivity : AppCompatActivity() { | |
} | ||
} | ||
|
||
|
||
companion object { | ||
@JvmStatic | ||
fun getIntent(context: Context) = Intent(context, HomeActivity::class.java).apply { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package com.teampophory.pophory.feature.home.add | ||
|
||
import android.app.Activity.RESULT_CANCELED | ||
import android.app.Activity.RESULT_OK | ||
import android.content.Context | ||
import android.content.Intent | ||
import android.os.Bundle | ||
import android.view.LayoutInflater | ||
import android.view.View | ||
import android.view.ViewGroup | ||
import androidx.activity.result.ActivityResultLauncher | ||
import androidx.activity.result.PickVisualMediaRequest | ||
import androidx.activity.result.contract.ActivityResultContracts | ||
import androidx.fragment.app.activityViewModels | ||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment | ||
import com.teampophory.pophory.databinding.BottomSheetHomeAddPhotoBinding | ||
import com.teampophory.pophory.feature.home.HomeViewModel | ||
import com.teampophory.pophory.feature.home.photo.AddPhotoActivity | ||
import com.teampophory.pophory.feature.qr.QRActivity | ||
|
||
class AddPhotoBottomSheet : BottomSheetDialogFragment() { | ||
|
||
private var _binding: BottomSheetHomeAddPhotoBinding? = null | ||
private val binding get() = _binding!! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. viewBinding으로 바꾸셔도 될 것 같고 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵! |
||
private val viewModel by activityViewModels<HomeViewModel>() | ||
private lateinit var imagePicker: ActivityResultLauncher<PickVisualMediaRequest> | ||
private lateinit var addPhotoResultLauncher: ActivityResultLauncher<Intent> | ||
private lateinit var qrActivityResultLauncher: ActivityResultLauncher<Intent> | ||
|
||
override fun onCreateView( | ||
inflater: LayoutInflater, | ||
container: ViewGroup?, | ||
savedInstanceState: Bundle? | ||
): View { | ||
_binding = BottomSheetHomeAddPhotoBinding.inflate(inflater, container, false) | ||
return binding.root | ||
} | ||
|
||
override fun onAttach(context: Context) { | ||
super.onAttach(context) | ||
|
||
imagePicker = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri -> | ||
val currentAlbumPosition = viewModel.homeState.value.currentAlbumPosition | ||
val albumItem = viewModel.homeState.value.currentAlbums?.getOrNull(currentAlbumPosition) | ||
if (uri != null && albumItem != null) { | ||
val intent = AddPhotoActivity.getIntent(context, uri.toString(), albumItem) | ||
addPhotoResultLauncher.launch(intent) | ||
Comment on lines
+40
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. onAttach에서 초기화 하는 이유가 따로 있나요?! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
} | ||
Comment on lines
+46
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게 구현되면 사진 추가 화면에서 제출 안하고 바로 뒤로가기 했을때 이 BottomSheet 그대로 보이지 않나? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맞습니다 백버튼 누르면 RESULT_CANCELED을 발생시키고 dismiss시키는 방향으로 수정하겠습니다! |
||
|
||
qrActivityResultLauncher = | ||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { | ||
if (it.resultCode == RESULT_OK) { | ||
val uriString = it.data?.getStringExtra("downloaded_image_uri") | ||
val currentAlbumPosition = viewModel.homeState.value.currentAlbumPosition | ||
val albumItem = | ||
viewModel.homeState.value.currentAlbums?.getOrNull(currentAlbumPosition) | ||
if (uriString != null && albumItem != null) { | ||
val intent = AddPhotoActivity.getIntent(context, uriString, albumItem) | ||
addPhotoResultLauncher.launch(intent) | ||
} | ||
} | ||
if (it.resultCode == RESULT_CANCELED) { | ||
dismiss() | ||
} | ||
} | ||
|
||
addPhotoResultLauncher = | ||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { | ||
if (it.resultCode == RESULT_OK) { | ||
viewModel.eventAlbumCountUpdate() | ||
dismiss() | ||
} | ||
} | ||
} | ||
|
||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { | ||
super.onViewCreated(view, savedInstanceState) | ||
initListMenuViews() | ||
} | ||
|
||
private fun initListMenuViews() { | ||
with(binding) { | ||
layoutQr.setOnClickListener { | ||
val intent = Intent(context, QRActivity::class.java) | ||
qrActivityResultLauncher.launch(intent) | ||
} | ||
layoutGallery.setOnClickListener { | ||
imagePicker.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. setOnSingle 맥여주세요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 맛있다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 바뀌어여라얍! |
||
} | ||
} | ||
|
||
override fun onDestroyView() { | ||
_binding = null | ||
super.onDestroyView() | ||
} | ||
|
||
companion object { | ||
val TAG: String = AddPhotoBottomSheet::class.java.simpleName | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. const 적용가능하지 않을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이게 const를 붙이면 뒤의 값이 constant하지 않다고 오류가 나옵니다! |
||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,70 @@ | ||||||
package com.teampophory.pophory.feature.qr | ||||||
|
||||||
import android.app.DownloadManager | ||||||
import android.content.BroadcastReceiver | ||||||
import android.content.Context | ||||||
import android.content.Intent | ||||||
import android.content.IntentFilter | ||||||
import android.net.Uri | ||||||
import android.os.Environment | ||||||
import android.webkit.CookieManager | ||||||
import android.webkit.URLUtil | ||||||
|
||||||
class ImageDownloader() { | ||||||
fun downloadImageFromUrl(context: Context, url: String, callback: (Uri?) -> Unit) { | ||||||
val request = createDownloadRequest(context, url) | ||||||
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
이렇게 하셔도 됩니다. |
||||||
val downloadID = downloadManager.enqueue(request) | ||||||
setupDownloadCompletionReceiver(context, downloadID, callback) | ||||||
} | ||||||
|
||||||
private fun createDownloadRequest(context: Context, url: String): DownloadManager.Request { | ||||||
return DownloadManager.Request(Uri.parse(url)).apply { | ||||||
setMimeType("image/jpeg") | ||||||
val cookies = CookieManager.getInstance().getCookie(url) | ||||||
addRequestHeader("cookie", cookies) | ||||||
setDescription("Downloading image...") | ||||||
setTitle(URLUtil.guessFileName(url, null, "image/jpeg")) | ||||||
allowScanningByMediaScanner() | ||||||
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) | ||||||
setDestinationInExternalPublicDir( | ||||||
Environment.DIRECTORY_DOWNLOADS, | ||||||
URLUtil.guessFileName(url, null, "image/jpeg") | ||||||
) | ||||||
} | ||||||
} | ||||||
|
||||||
private fun setupDownloadCompletionReceiver( | ||||||
context: Context, | ||||||
downloadID: Long, | ||||||
callback: (Uri?) -> Unit | ||||||
) { | ||||||
val receiver = object : BroadcastReceiver() { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Receiver 다른 곳에다가 만들자. 함수 하나가 가지고 있는 역할 때문에 클래스가 가지고 있는 역할이 너무 많아지게 되는 것 같아 |
||||||
override fun onReceive(context: Context?, intent: Intent?) { | ||||||
val id = intent?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1) | ||||||
if (downloadID == id) { | ||||||
val downloadManager = | ||||||
context?.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager | ||||||
val query = DownloadManager.Query().setFilterById(downloadID) | ||||||
val cursor = downloadManager.query(query) | ||||||
if (cursor.moveToFirst()) { | ||||||
val columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS) | ||||||
if (DownloadManager.STATUS_SUCCESSFUL == cursor.getInt(columnIndex)) { | ||||||
val uriString = | ||||||
cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)) | ||||||
cursor.close() | ||||||
uriString?.let { | ||||||
callback(Uri.parse(it)) | ||||||
return | ||||||
} | ||||||
} | ||||||
} | ||||||
cursor.close() | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. downloadManager.query(query).use {
// safe usage
} query가 closable이어서 이런식으로 활용가능 할 것 같음. 이게 좀 더 안전하게 closable 객체 메모리 할당 해제할 수 있으니까 참고해보면 될 것 같습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 네 확인해보겠습니다! |
||||||
callback(null) | ||||||
} | ||||||
} | ||||||
} | ||||||
|
||||||
context.registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) | ||||||
} | ||||||
} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unRegisterReceiver 는 어디서 하고있는지 확인해주셔야할 것 같아요 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 없다면 추가 부탁드립니다~!! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unRegisterReceiver가 없습니다 추가하겠습니다! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이거 삭제!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
삭제!!