diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 93e4a239..1064ca25 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -102,6 +102,7 @@ dependencies { //implementation ("ru.github.igla:ferriswheel:1.2") implementation("com.squareup.okhttp3:logging-interceptor:4.9.3") + implementation("io.github.ParkSangGwon:tedpermission-normal:3.4.2") } \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index d0450579..193a0e82 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,10 +1,11 @@ + xmlns:tools="http://schemas.android.com/tools" + package="com.coop.sharenote"> - + = Build.VERSION_CODES.TIRAMISU) { + if (ContextCompat.checkSelfPermission( + this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) { + + // 권한을 처음 요청하는 경우나, 거부한 경우 처리 + ActivityCompat.requestPermissions( + this, + arrayOf(Manifest.permission.POST_NOTIFICATIONS), + 1001 + ) + } else { + Log.e("MainActivity", "Permission is already granted") + } + } + auth = FirebaseAuth.getInstance() @@ -63,4 +92,62 @@ class MainActivity : AppCompatActivity() { val intent = Intent(this, PageActivity::class.java) startActivity(intent) } + + // 권한 요청 후 결과 처리 + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + if (requestCode == 1001) { + if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // 권한이 허용된 경우 + Log.d("Permission", "알림 권한이 허용되었습니다.") + } else { + // 권한이 거부된 경우, 설명 다이얼로그 표시 + if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.POST_NOTIFICATIONS)) { + Log.e("MainActivity", "이전에 거부됨") + } else { + // "다시 묻지 않음"이 선택된 경우 설정 다이얼로그 표시 + Log.e("MainActivity", "다시 묻지 않음 누름") + showSettingsDialog() + } + } + } + } + // 설정으로 이동하는 다이얼로그 + private fun showSettingsDialog() { + AlertDialog.Builder(this) + .setTitle("알림 권한 필요") + .setMessage("알림 기능을 사용하려면 설정에서 권한을 허용해야 합니다.") + .setPositiveButton("설정으로 이동") { _, _ -> + val intent = Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + val uri = Uri.fromParts("package", packageName, null) + intent.data = uri + startActivity(intent) + } + .setNegativeButton("취소", null) + .show() + } + + private fun createNotificationChannel() { + // Android 8.0 이상에서만 알림 채널을 설정 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + val channelId = "default" + val channelName = "Default Channel" + val channelDescription = "알림을 위한 기본 채널입니다." + val importance = NotificationManager.IMPORTANCE_HIGH + + val channel = NotificationChannel(channelId, channelName, importance).apply { + description = channelDescription + } + + // 알림 매니저를 통해 채널을 등록 + val notificationManager: NotificationManager = + getSystemService(NotificationManager::class.java) + notificationManager.createNotificationChannel(channel) + } + } + } diff --git a/android/app/src/main/java/com/coop/sharenote/MyFirebaseMessagingService.kt b/android/app/src/main/java/com/coop/sharenote/MyFirebaseMessagingService.kt index cc7b73c8..cca7fc03 100644 --- a/android/app/src/main/java/com/coop/sharenote/MyFirebaseMessagingService.kt +++ b/android/app/src/main/java/com/coop/sharenote/MyFirebaseMessagingService.kt @@ -6,6 +6,7 @@ import android.app.PendingIntent import android.content.Context import android.content.Intent import android.os.Build +import android.util.Log import androidx.core.app.NotificationCompat import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage @@ -16,11 +17,14 @@ class MyFirebaseMessagingService : FirebaseMessagingService() { super.onMessageReceived(remoteMessage) // 메시지 데이터 추출 - val title = remoteMessage.notification?.title - val body = remoteMessage.notification?.body + val title = remoteMessage.notification?.title ?: "알림" + val body = remoteMessage.notification?.body ?: "알림이 도착했습니다." - // 알림 표시 + // 알림 표시, body가 null인데(백엔드에서 그렇게 줌) 이러면 알림이 안생길 가능성이 높대 showNotification(title, body) + + Log.d("FCM", "Message received: $title") + Log.d("FCM", "Message received: $body") } private fun showNotification(title: String?, body: String?) { @@ -28,7 +32,8 @@ class MyFirebaseMessagingService : FirebaseMessagingService() { // 채널 생성 (Android O 이상 필요) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - val channel = NotificationChannel("default", "Default Channel", NotificationManager.IMPORTANCE_DEFAULT) + //default보다 High로 설정 시도 + val channel = NotificationChannel("default", "Default Channel", NotificationManager.IMPORTANCE_HIGH) notificationManager.createNotificationChannel(channel) } diff --git a/android/app/src/main/java/com/coop/sharenote/PaintActivity.kt b/android/app/src/main/java/com/coop/sharenote/PaintActivity.kt index b34c1b5e..b9aa0908 100644 --- a/android/app/src/main/java/com/coop/sharenote/PaintActivity.kt +++ b/android/app/src/main/java/com/coop/sharenote/PaintActivity.kt @@ -26,6 +26,8 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.graphics.drawable.toBitmap import androidx.lifecycle.lifecycleScope import com.bumptech.glide.Glide +import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool +import com.bumptech.glide.load.resource.bitmap.BitmapTransformation import com.coop.sharenote.RetrofitClient.apiService import com.coop.sharenote.RetrofitClient.apiService2 import com.github.dhaval2404.colorpicker.ColorPickerDialog @@ -43,6 +45,8 @@ import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody import java.io.ByteArrayOutputStream import java.io.File +import java.io.FileOutputStream +import java.security.MessageDigest import java.util.UUID @@ -535,11 +539,38 @@ class PaintActivity : AppCompatActivity() { // Glide를 사용하여 이미지 로드 Glide.with(this) .load(selectedUrl) + .transform(com.coop.sharenote.TransparentBackgroundTransformation()) .into(imageView) } } + } + + class TransparentBackgroundTransformation : BitmapTransformation() { + + override fun updateDiskCacheKey(messageDigest: MessageDigest) { + messageDigest.update("transparent_background".toByteArray()) + } + override fun transform( + pool: BitmapPool, + toTransform: Bitmap, + outWidth: Int, + outHeight: Int + ): Bitmap { + val bitmap = toTransform.copy(Bitmap.Config.ARGB_8888, true) + + for (x in 0 until bitmap.width) { + for (y in 0 until bitmap.height) { + val pixel = bitmap.getPixel(x, y) + // 흰색을 투명하게 바꿈 + if (pixel == Color.WHITE) { + bitmap.setPixel(x, y, Color.TRANSPARENT) + } + } + } + return bitmap + } } diff --git a/android/app/src/main/java/com/coop/sharenote/QuizActivity.kt b/android/app/src/main/java/com/coop/sharenote/QuizActivity.kt index 2d38c24b..af94310f 100644 --- a/android/app/src/main/java/com/coop/sharenote/QuizActivity.kt +++ b/android/app/src/main/java/com/coop/sharenote/QuizActivity.kt @@ -5,6 +5,7 @@ import SearchNoteListAdapter import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle +import android.util.Log import android.view.LayoutInflater import android.widget.Button import android.widget.TextView @@ -15,6 +16,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import kotlin.math.log class QuizActivity : AppCompatActivity(), QuizAdapter.OnItemClickListener { diff --git a/android/app/src/main/java/com/coop/sharenote/RetrofitClient.kt b/android/app/src/main/java/com/coop/sharenote/RetrofitClient.kt index 2ba6253b..08614c4c 100644 --- a/android/app/src/main/java/com/coop/sharenote/RetrofitClient.kt +++ b/android/app/src/main/java/com/coop/sharenote/RetrofitClient.kt @@ -10,9 +10,9 @@ import java.util.concurrent.TimeUnit object RetrofitClient { - private const val BASE_URL = "http://10.0.2.2:8080/api/" // 엔드포인트 주소 외에는 baseUrl에 포함되어야 함 - private const val AI_BASE_URL = "http://54.85.65.14:8000/" // AI 서버 주소 - //private const val BASE_URL = "https://sharenote.shop/api/" // 배포용 + //private const val BASE_URL = "http://10.0.2.2:8080/api/" // 엔드포인트 주소 외에는 baseUrl에 포함되어야 함 + private const val AI_BASE_URL = "https://autodraw.shop/" // AI 서버 주소 + private const val BASE_URL = "https://sharenote.shop/api/" // 배포용 private val retrofit: Retrofit by lazy { Retrofit.Builder() .baseUrl(BASE_URL)