From d61b3348cb0925b09f17b3034e9c078dff713ca7 Mon Sep 17 00:00:00 2001 From: TTRR1007 Date: Mon, 23 Jun 2025 04:08:11 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[=EA=B9=80=EC=98=81=EC=88=98=5FAndroid]=209?= =?UTF-8?q?=EC=A3=BC=EC=B0=A8=20=EA=B3=BC=EC=A0=9C=20=EC=A0=9C=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 6 + .../bcsd_android_2025_1/AudioAdapter.kt | 46 ++++++ .../bcsd_android_2025_1/MainActivity.kt | 139 +++++++++++++++++- app/src/main/res/layout/activity_main.xml | 29 +++- app/src/main/res/layout/item.xml | 35 +++++ app/src/main/res/values/strings.xml | 12 +- 6 files changed, 260 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/com/example/bcsd_android_2025_1/AudioAdapter.kt create mode 100644 app/src/main/res/layout/item.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4c80941..e501e8e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,6 +2,12 @@ + + + + + (){ + + + private val items = mutableListOf() + + fun submitList(newList: List) { + items.clear() + items.addAll(newList) + notifyDataSetChanged() + } + + inner class AudioViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + val titleTextView: TextView = itemView.findViewById(R.id.tv_rv_item_title) + val artistTextView: TextView = itemView.findViewById(R.id.tv_rv_item_artist) + val timeTextView: TextView = itemView.findViewById(R.id.tv_rv_item_time) + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AudioViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.item, parent, false) + return AudioViewHolder(view) + } + + override fun onBindViewHolder(holder: AudioViewHolder, position: Int) { + val item = items[position] + holder.titleTextView.text = item.name + holder.artistTextView.text = item.artist + + val minutes = item.duration/1000/60 + val seconds = (item.duration/1000)%60 + holder.timeTextView.text = String.format("%d:%02d", minutes, seconds) + } + + override fun getItemCount(): Int = items.size + + + +} \ No newline at end of file diff --git a/app/src/main/java/com/example/bcsd_android_2025_1/MainActivity.kt b/app/src/main/java/com/example/bcsd_android_2025_1/MainActivity.kt index 3ffa0eb..1d2db19 100644 --- a/app/src/main/java/com/example/bcsd_android_2025_1/MainActivity.kt +++ b/app/src/main/java/com/example/bcsd_android_2025_1/MainActivity.kt @@ -1,14 +1,147 @@ package com.example.bcsd_android_2025_1 +import android.Manifest +import android.content.ContentUris +import android.content.Intent +import android.net.Uri +import android.os.Build import android.os.Bundle -import androidx.activity.enableEdgeToEdge +import android.provider.MediaStore.Audio.Media +import android.provider.Settings +import android.view.View +import android.widget.Button +import android.widget.TextView +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat +import androidx.core.net.toUri +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView class MainActivity : AppCompatActivity() { + + private lateinit var permissionName: String + + private lateinit var audioAdapter: AudioAdapter + + private val requestPermission = + registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> + when (isGranted) { + true -> getAudioFile() + else -> { + when (shouldShowRequestPermissionRationale(permissionName)) { + true -> permissionDialog(true) + else -> permissionDialog(false) + } + } + } + } + + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + + permissionName = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + Manifest.permission.READ_MEDIA_AUDIO + } else { + Manifest.permission.READ_EXTERNAL_STORAGE + } + + audioAdapter =AudioAdapter() + + val recyclerView = findViewById(R.id.rv_main) + recyclerView.adapter = audioAdapter + recyclerView.layoutManager = LinearLayoutManager(this) + + requestPermission.launch(permissionName) + + } + + private fun permissionDialog(isShowRationale: Boolean) { + if (isShowRationale) { + AlertDialog.Builder(this) + .setTitle(R.string.tv_main) + .setPositiveButton(R.string.alert_btn_positive){ + _, _ -> + requestPermission.launch(permissionName) + } + .setNegativeButton(R.string.alert_btn_negative, null) + .show() + return + } + val tvMain = findViewById(R.id.tv_main) + val btnMain = findViewById