Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ android {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

androidExtensions {
experimental = true
}

buildTypes {
release {
minifyEnabled false
Expand All @@ -34,4 +38,5 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
implementation 'com.google.android.material:material:1.2.1'
}
6 changes: 5 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service
android:name=".service.SongService"
android:process=":remote" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Expand Down
26 changes: 26 additions & 0 deletions app/src/main/aidl/ISongAidlInterface.aidl
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// ISongAidlInterface.aidl
package com.example.myapplication;

// Declare any non-default types here with import statements

interface ISongAidlInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
void play();
void pause();
boolean isPlaying();
boolean isMPReleased();
int getDuration();
int getCurrentPosition();
void changeTime(int time);
void playNext();
void playPrev();

Song getSong();
void setCurrentSong(int position);
void setCurrentSongFromBundle(in Bundle bundle);
}

parcelable Song;
42 changes: 42 additions & 0 deletions app/src/main/java/com/example/myapplication/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,54 @@
package com.example.myapplication

import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat
import com.example.myapplication.screens.songsList.SongsListFragment
import com.example.myapplication.service.SongService

class MainActivity : AppCompatActivity() {
var songService: ISongAidlInterface? = null
lateinit var builder: NotificationCompat.Builder
val CHANNEL_ID = "playerChannel"

private val aidlConnection = object : ServiceConnection {

override fun onServiceConnected(className: ComponentName, service: IBinder) {
songService = ISongAidlInterface.Stub.asInterface(service)
supportFragmentManager.beginTransaction().
replace(R.id.frameLayout, SongsListFragment()).commit()
}

override fun onServiceDisconnected(className: ComponentName) {
songService = null
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}

override fun onStart() {
super.onStart()
val intent =
Intent(this, SongService::class.java)
bindService(intent, aidlConnection, Context.BIND_AUTO_CREATE)
}

override fun onDestroy() {
super.onDestroy()
Log.e("LOG_TAG", "MainActivity onServiceDisconnected")
songService?.let {
unbindService(aidlConnection)
songService = null
}

}
}
44 changes: 44 additions & 0 deletions app/src/main/java/com/example/myapplication/Song.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.example.myapplication

import android.os.Parcel
import android.os.Parcelable
import androidx.annotation.DrawableRes
import androidx.annotation.RawRes

data class Song(
var author: String = "",
var name: String = "",
@DrawableRes var photoId: Int = 0,
@RawRes var songId: Int = 0
) : Parcelable {

companion object CREATOR : Parcelable.Creator<Song> {
override fun createFromParcel(parcel: Parcel): Song {
return Song(parcel)
}

override fun newArray(size: Int): Array<Song> {
return Array(size) { Song() }
}
}

private constructor(inParcel: Parcel) : this() {
readFromParcel(inParcel)
}

private fun readFromParcel(inParcel: Parcel) {
author = inParcel.readString() ?: ""
name = inParcel.readString() ?: ""
songId = inParcel.readInt() ?: 0
photoId = inParcel.readInt() ?: 0
}

override fun writeToParcel(outParcel: Parcel, flags: Int) {
outParcel.writeString(author)
outParcel.writeString(name)
outParcel.writeInt(songId)
outParcel.writeInt(photoId)
}

override fun describeContents(): Int = 0
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.example.myapplication.adapters


import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.myapplication.Song
import com.example.myapplication.R
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.item_song.*


class SongAdapter (
private var list: ArrayList<Song>,
private val fragmentLambda: (View, Int) -> Unit
) : RecyclerView.Adapter<SongAdapter.SongViewHolder>() {

inner class SongViewHolder(
override val containerView: View
): RecyclerView.ViewHolder(containerView), LayoutContainer {

fun bind(song: Song, position: Int) {
with(song) {
tv_sm_title.text = name
tv_sm_author.text = author
iv_sm_album.setImageResource(song.photoId)
}

itemView.setOnClickListener{fragmentLambda(itemView,position)}
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SongViewHolder {
return SongViewHolder(LayoutInflater.from(parent.context).
inflate(R.layout.item_song, parent, false))
}

override fun onBindViewHolder(holder: SongViewHolder, position: Int) {
holder.bind(list[position], position)
}

override fun getItemCount(): Int = list.size
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.myapplication.repository

import com.example.myapplication.Song
import com.example.myapplication.R

object SongRepository {
val songsList: List<Song> = arrayListOf(
Song("SLAVA","Снова я напиваюсь", R.drawable.straus, R.raw.again_drink),
Song("Dora","Втюрилась", R.drawable.straus, R.raw.dora),
Song("Нурминчик","Валим валим на гелике", R.drawable.straus, R.raw.valim),
Song("Нурминчик","Ауф", R.drawable.straus, R.raw.auf),
Song("Кто-то","Арабская", R.drawable.straus, R.raw.arabskay)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.example.myapplication.screens.song

import android.os.Bundle
import android.os.Handler
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.SeekBar
import com.example.myapplication.ISongAidlInterface
import com.example.myapplication.MainActivity
import com.example.myapplication.R
import com.example.myapplication.Song
import kotlinx.android.synthetic.main.fragment_song.*

class SongFragment : Fragment() {
var service: ISongAidlInterface? = null

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_song, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val activity = (activity as MainActivity?)
service = activity?.songService
changeUI(service?.song)
initialiseSeekBar()


iv_play.setOnClickListener {
if (service?.isPlaying == true) {
iv_play.setImageResource(R.drawable.ic_play)
service?.pause()
} else if (service?.isPlaying == false) {
iv_play.setImageResource(R.drawable.ic_pause)
service?.play()
}
}
iv_next.setOnClickListener {
service?.playNext()
changeUI(service?.song)
}
iv_prev.setOnClickListener {
service?.playPrev()
changeUI(service?.song)
}
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
if (p2) {
service?.changeTime(p1)
}
}

override fun onStartTrackingTouch(p0: SeekBar?) {
}

override fun onStopTrackingTouch(p0: SeekBar?) {
}
})
}

private fun changeUI(song: Song?) {
song?.photoId?.let { iv_album.setImageResource(it) }
tv_author.text = song?.author
tv_name.text = song?.name

}

private fun initialiseSeekBar() {
seekBar.max = service!!.duration
var handler: Handler = Handler()
handler.postDelayed(object : Runnable {
override fun run() {
seekBar.progress = service?.currentPosition!!
handler.postDelayed(this, 1000)
}
}, 0)
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.example.myapplication.screens.songsList

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.myapplication.ISongAidlInterface
import com.example.myapplication.MainActivity
import com.example.myapplication.Song
import com.example.myapplication.adapters.SongAdapter
import com.example.myapplication.repository.SongRepository
import com.example.myapplication.screens.song.SongFragment
import com.example.myapplication.R
import kotlinx.android.synthetic.main.fragment_songs_list.*

class SongsListFragment : Fragment() {

private var adapter: SongAdapter? = null
var service: ISongAidlInterface? = null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_songs_list, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

val activity = (activity as MainActivity?)
service = activity?.songService
adapter = SongAdapter(SongRepository.songsList as ArrayList<Song>) { item, position ->
val transaction = activity?.supportFragmentManager?.beginTransaction()

transaction?.addToBackStack(null)
item.setOnClickListener {
if (service?.isMPReleased == true
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

обычно перенос строки идет после || , а не перед

|| service?.song != SongRepository.songsList[position]
) {
service?.setCurrentSong(position)
}

transaction?.replace(
R.id.frameLayout,
SongFragment()
)?.commit()

}
}
rv_song.adapter = adapter
}
}
Loading