diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 4862c91..8fb5800 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -32,15 +32,13 @@
-
-
+
-
+
+
-
-
-
+
@@ -97,9 +95,9 @@
@@ -112,18 +110,19 @@
- {
- "keyToString": {
- "RunOnceActivity.OpenProjectViewOnStart": "true",
- "RunOnceActivity.ShowReadmeOnStart": "true",
- "RunOnceActivity.cidr.known.project.marker": "true",
- "cf.first.check.clang-format": "false",
- "cidr.known.project.marker": "true",
- "last_directory_selection": "C:/Users/Public/assignment02/app/src/main/java",
- "last_opened_file_path": "C:/Users/Public/assignment02",
- "settings.editor.selected.configurable": "AndroidSdkUpdater"
+
+}]]>
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 74cb2b6..27c7204 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,6 +4,7 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/example/assignment02/AuthorityFragment.kt b/app/src/main/java/com/example/assignment02/AuthorityFragment.kt
index 58a68e2..1841619 100644
--- a/app/src/main/java/com/example/assignment02/AuthorityFragment.kt
+++ b/app/src/main/java/com/example/assignment02/AuthorityFragment.kt
@@ -55,12 +55,13 @@ class AuthorityFragment : Fragment() {
}
private fun requestPermission() {
- if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
+ if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
+ requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
+ } else if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.FOREGROUND_SERVICE) != PackageManager.PERMISSION_GRANTED) {
+ requestPermissionLauncher.launch(Manifest.permission.FOREGROUND_SERVICE)
+ } else {
// 권한이 이미 있음
openFragment()
- } else {
- // 권한이 없으면 권한 요청
- requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
}
}
diff --git a/app/src/main/java/com/example/assignment02/ListFragment.kt b/app/src/main/java/com/example/assignment02/ListFragment.kt
index 657fdf1..ea54202 100644
--- a/app/src/main/java/com/example/assignment02/ListFragment.kt
+++ b/app/src/main/java/com/example/assignment02/ListFragment.kt
@@ -1,27 +1,35 @@
package com.example.assignment02
import android.Manifest
+import android.annotation.SuppressLint
import android.content.ContentResolver
+import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
-import android.net.Uri
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.os.BatteryManager
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
+import androidx.core.graphics.ColorUtils
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
-import java.io.File
class ListFragment : Fragment() {
private val data = mutableListOf- ()
private lateinit var adapter: Adapter
+ private lateinit var name: TextView
+ private lateinit var time: TextView
+ private lateinit var energy: LinearLayout
companion object {
fun newInstance(): ListFragment {
@@ -29,29 +37,47 @@ class ListFragment : Fragment() {
}
}
+ @SuppressLint("MissingInflatedId")
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_list, container, false)
+ name = view.findViewById(R.id.name)
+ time = view.findViewById(R.id.time)
+ energy = view.findViewById(R.id.energe)
+
+ // 배터리에 따라 배경색 변경하기!
+ val battery = getBatteryData(requireContext()) // 0~100(%)
+ energy.backgroundTintList = ColorStateList.valueOf(ColorUtils.blendARGB(Color.parseColor("#00B0FF"), Color.parseColor("#FFFFFF"), battery / 100f))
+
val recycler_list: RecyclerView = view.findViewById(R.id.recycler_list)
recycler_list.layoutManager = LinearLayoutManager(requireContext())
- adapter = Adapter(data)
+ adapter = Adapter(data, name, time)
recycler_list.adapter = adapter
- if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
+ if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
) {
- // 권한이 있음 -> 음악 파일 추가
- getMusicFilesData()
- } else {
- // 권한이 없음
openFragment()
}
+ else if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.FOREGROUND_SERVICE) != PackageManager.PERMISSION_GRANTED
+ ) {
+ openFragment()
+ }
+ else {
+ // 권한이 있음
+ getMusicFilesData()
+ }
return view
}
+ fun getBatteryData(context: Context): Int {
+ val batteryManager = context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
+ return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
+ }
+
fun getMusicFilesData() {
val contentResolver: ContentResolver = requireContext().contentResolver
val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
@@ -71,9 +97,7 @@ class ListFragment : Fragment() {
val dataIndex = it.getColumnIndex(MediaStore.Audio.Media.DATA)
while (it.moveToNext()) {
- Log.d("File Path", "음악 파일 경로: ${it.getString(dataIndex)}")
-
- val item = Item(it.getString(titleIndex) ?: "Unknown Title", it.getString(artistIndex) ?: "Unknown Artist", it.getLong(durationIndex) ?: 0)
+ val item = Item(it.getString(titleIndex) ?: "Unknown Title", it.getString(artistIndex) ?: "Unknown Artist", it.getLong(durationIndex) ?: 0, it.getString(dataIndex) ?: "")
data.add(item)
}
adapter.notifyDataSetChanged()
@@ -91,7 +115,7 @@ class ListFragment : Fragment() {
.commit()
}
- class Adapter(private val data: MutableList
- ) : RecyclerView.Adapter() {
+ class Adapter(private val data: MutableList
- , private var name_view:TextView, private var time_view:TextView) : RecyclerView.Adapter() {
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val title: TextView = itemView.findViewById(R.id.title)
@@ -111,11 +135,19 @@ class ListFragment : Fragment() {
val m = (item.duration/60000).toString()
val s = (item.duration/1000 %60).toString()
holder.duration.text = "$m:$s"
+
+ holder.itemView.setOnClickListener {
+ name_view.text = item.title
+ time_view.text = holder.duration.text
+ val intent = Intent(holder.itemView.context, PlayMusic::class.java).apply {
+ putExtra("uri", item.uri)
+ }
+ ContextCompat.startForegroundService(holder.itemView.context, intent)
+ }
}
override fun getItemCount(): Int = data.size
}
- data class Item(val title: String, val artist: String, val duration: Long)
-
+ data class Item(val title: String, val artist: String, val duration: Long, val uri: String)
}
diff --git a/app/src/main/java/com/example/assignment02/MainActivity.kt b/app/src/main/java/com/example/assignment02/MainActivity.kt
index 6ffe442..ab89355 100644
--- a/app/src/main/java/com/example/assignment02/MainActivity.kt
+++ b/app/src/main/java/com/example/assignment02/MainActivity.kt
@@ -29,4 +29,8 @@ class MainActivity : AppCompatActivity() {
.replace(R.id.fragment_container, fragment)
.commit()
}
+ override fun onBackPressed() {
+ super.onBackPressed()
+ finish()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/assignment02/PlayMusic.kt b/app/src/main/java/com/example/assignment02/PlayMusic.kt
new file mode 100644
index 0000000..222db4f
--- /dev/null
+++ b/app/src/main/java/com/example/assignment02/PlayMusic.kt
@@ -0,0 +1,77 @@
+package com.example.assignment02
+
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.app.Service
+import android.content.Intent
+import android.media.MediaPlayer
+import android.os.Build
+import android.os.IBinder
+import androidx.core.app.NotificationCompat
+import android.net.Uri
+import android.util.Log
+
+class PlayMusic : Service() {
+
+ private var mediaPlayer: MediaPlayer? = null
+ private val channel1 = "channel1"
+
+ override fun onCreate() {
+ super.onCreate()
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val channel = NotificationChannel(
+ channel1,
+ "music",
+ NotificationManager.IMPORTANCE_LOW
+ )
+ val notificationManager = getSystemService(NotificationManager::class.java)
+ notificationManager.createNotificationChannel(channel)
+ }
+
+ val intent = Intent(this, MainActivity::class.java)
+ val pending_intent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
+
+ // 알림 생성
+ val notification: Notification = NotificationCompat.Builder(this, channel1)
+ .setContentTitle("음악 재생 중...")
+ .setContentText("백그라운드에서 음악이 재생되고 있습니다.")
+ .setSmallIcon(androidx.core.R.drawable.ic_call_answer)
+ .setContentIntent(pending_intent)
+ .setAutoCancel(true)
+ .build()
+
+ startForeground(1, notification)
+ }
+
+ override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
+ val uri_string = intent.getStringExtra("uri")
+ Log.d("PlayMusic", "URI: $uri_string")
+ uri_string?.let {
+ val uri = Uri.parse(it)
+ musicPlay(uri)
+ }
+ return START_STICKY
+ }
+
+ private fun musicPlay(uri: Uri) {
+ mediaPlayer = MediaPlayer().apply {
+ setDataSource(applicationContext, uri)
+ setOnPreparedListener {
+ it.start()
+ }
+ prepareAsync()
+ }
+ }
+
+ override fun onBind(intent: Intent?): IBinder? {
+ return null
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mediaPlayer?.release()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_list.xml b/app/src/main/res/layout/fragment_list.xml
index 999bfca..1e4ceb3 100644
--- a/app/src/main/res/layout/fragment_list.xml
+++ b/app/src/main/res/layout/fragment_list.xml
@@ -10,6 +10,45 @@
+ android:layout_height="wrap_content"
+ android:layout_weight="1" >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file