강의자료 30페이지의 직접풀어보기 13-2를 참조하여 아래와 같은 앱을 작성하시오.
1. 음악이 종료되면 자동으로 초기상태로 전환하시오.(Hint: mPlayer.isPlaying로 재생중인지를 확인할 수 있음)
2. 시크바로 음악의 해당 부분을 재생할 수 있음
3. 음악 파일은 raw 폴더에 넣어도 되고, SD카드에 넣어도 됨
1. raw폴더에 저장
2. sd카드에 저장
Manifests.xml에 permission 추가
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:requestLegacyExternalStorage="true"
....
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="6"
android:orientation="horizontal"
android:background="@color/green">
<ListView
android:id="@+id/listViewMp3"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btnPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="듣기" />
<Button
android:id="@+id/btnStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="중지" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
MainActivity.kt
package com.cookandroid.kotlinfinalterm13
import android.content.Context
import android.graphics.Color
import android.media.MediaPlayer
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment
import android.os.SystemClock
import android.widget.ArrayAdapter
import android.widget.ListView
import android.widget.SeekBar
import androidx.core.app.ActivityCompat
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File
import java.text.SimpleDateFormat
class MainActivity : AppCompatActivity() {
lateinit var mp3List: ArrayList<String> //mp3파일을 저장할 리스트
lateinit var selectedMp3: String //현재 선택된 mp3파일
lateinit var mPlayer: MediaPlayer //mp3 player 객체 생성
/*3. 음악 파일을 SD카드에서 가져오는 경우*/
/*sd카드 경로 구하기*/
var mp3Path = Environment.getExternalStorageDirectory().path + "/"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "13장 수시고사"
/*처음에 어플 키면 '접근 권한을 허용할까요?' 하는 메시지를 띄움*/
ActivityCompat.requestPermissions(
this,
arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE),
Context.MODE_PRIVATE
)
mp3List = ArrayList() //mp3파일을 저장할 리스트
var listFiles = File(mp3Path).listFiles() //해당 경로에 있는 모든 파일들을 File[] 타입 변수에 저장 (mp3말고 다른 파일이 있을 수 있음)
var fileName: String //파일 전체 이름
var extName: String //확장자 이름
for (file in listFiles!!) {
fileName = file.name
extName = fileName.substring(fileName.length - 3) //확장자 추출하기
if (extName == "mp3") //확장자가 mp3일 경우 List에 추가
mp3List.add(fileName)
}
/*어댑터(내용물 or 컨텐츠의 의미) 생성*/
var ad = ArrayAdapter(this, android.R.layout.simple_list_item_single_choice, mp3List)
/*리스트뷰에 생성한 어댑터 지정*/
listViewMp3.choiceMode = ListView.CHOICE_MODE_SINGLE
listViewMp3.adapter = ad
listViewMp3.setItemChecked(0, true) //초기 선택값 : 인덱스 0번에 위치
/*아이템이 선택되면 selectedMp3에 값을 넣어줌*/
listViewMp3.setOnItemClickListener { parent, view, position, id -> //선택한 아이템의 인덱스 값은 position으로 알 수 있음
selectedMp3 = mp3List[position]
}
selectedMp3 = mp3List[0] //초기값은 0번째 아이템
mPlayer = MediaPlayer()
btnPlay.setOnClickListener {
mPlayer.setDataSource(mp3Path + selectedMp3) //경로+파일명
mPlayer.prepare()
mPlayer.start() //음악 재생
mPlayer.isLooping = false //반복 재생x
btnPlay.setTextColor(Color.WHITE) //실행하면 버튼색이 바뀜
btnStop.setTextColor(Color.RED)
textView.text = "실행중인 음악 : $selectedMp3"
/* 실시간으로 변경되는 진행시간과 시크바를 구현하기 위한 스레드 사용*/
object : Thread() {
var timeFormat = SimpleDateFormat("mm:ss") //"분:초"를 나타낼 수 있도록 포멧팅
override fun run() {
super.run()
if (mPlayer == null)
return
seekBar.max = mPlayer.duration // mPlayer.duration : 음악 총 시간
while (mPlayer.isPlaying) {
runOnUiThread { //화면의 위젯을 변경할 때 사용 (이 메소드 없이 아래 코드를 추가하면 실행x)
seekBar.progress = mPlayer.currentPosition
textView2.text = "진행시간 : " + timeFormat.format(mPlayer.currentPosition)
}
SystemClock.sleep(200)
}
/*1. 음악이 종료되면 자동으로 초기상태로 전환*/
/*btnStop.setOnClickListener()와 동일한 코드*/
if(!mPlayer.isPlaying){
mPlayer.stop() //음악 정지
mPlayer.reset()
btnPlay.setTextColor(Color.RED) //실행하면 버튼색이 바뀜
btnStop.setTextColor(Color.WHITE)
textView.text = "실행중인 음악 : "
seekBar.progress = 0
textView2.text = "진행시간 : "
}
}
}.start()
}
btnStop.setOnClickListener {
mPlayer.stop() //음악 정지
mPlayer.reset()
btnPlay.setTextColor(Color.RED) //실행하면 버튼색이 바뀜
btnStop.setTextColor(Color.WHITE)
textView.text = "실행중인 음악 : "
seekBar.progress = 0
textView2.text = "진행시간 : "
}
/*2. 시크바로 음악의 해당 부분을 재생*/
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
if (fromUser){
mPlayer.seekTo(progress)
}
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {}
override fun onStopTrackingTouch(seekBar: SeekBar?) {}
})
}
}
'Android > Kotlin App' 카테고리의 다른 글
[Kotlin App] 서비스와 브로드캐스트 리시버 (0) | 2021.06.07 |
---|---|
[Kotlin App] 파일 처리 (1) | 2021.05.11 |
[Kotlin App] DatePickerDialog / TimePickerDialog (0) | 2021.05.04 |
[Kotlin App] Action Bar와 Flagment (0) | 2021.05.04 |
[Kotlin App] TabHost (0) | 2021.05.03 |
댓글