Continuing work on #32 and #33

This commit is contained in:
amazing-username
2019-03-16 17:23:28 -04:00
parent 96cd2ddcc4
commit 9d7019530a
16 changed files with 371 additions and 133 deletions
@@ -1,9 +1,7 @@
package com.example.mear.activities
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Color
import android.media.MediaMetadataRetriever
import android.os.Bundle
import android.os.Handler
@@ -26,6 +24,8 @@ import com.example.mear.models.PlayControls
import com.example.mear.R
import com.example.mear.repositories.RepeatRepository
import com.example.mear.repositories.ShuffleRepository
import com.example.mear.util.ConvertByteArray
import com.example.mear.util.ExtractCover
class MainActivity : BaseServiceActivity() {
@@ -242,12 +242,19 @@ class MainActivity : BaseServiceActivity() {
(trackDuration % 60)
)
var coverExt = ExtractCover(currTrack.songPath)
if (coverExt.hasCover()) {
trackCover = coverExt.retrieveCover()
}
/**
val mmr = MediaMetadataRetriever()
mmr.setDataSource(currTrack.songPath)
if (mmr.embeddedPicture != null) {
trackCover = mmr.embeddedPicture
}
*/
resetControls()
@@ -256,8 +263,8 @@ class MainActivity : BaseServiceActivity() {
AlbumTitle.text = albumTitle
TrackDuration.text = dur
if (trackCover != null) {
val songImage = BitmapFactory
.decodeByteArray(trackCover, 0, trackCover.size)
val convertToBmp = ConvertByteArray(trackCover!!)
var songImage = convertToBmp.convertToBmp()
TrackCover.imageBitmap = songImage
}
}
@@ -1,44 +1,131 @@
package com.example.mear.activities
import android.os.Build
import android.os.Bundle
import android.support.annotation.RequiresApi
import android.support.v7.app.AppCompatActivity
import android.widget.LinearLayout
import android.widget.ListView
import android.support.v7.widget.LinearLayoutManager
import java.lang.Exception
import kotlinx.android.synthetic.main.activity_song_view.*
import kotlinx.android.synthetic.main.content_song_view.*
import com.example.mear.adapters.RecyclerAdapter
import com.example.mear.models.TrackItems
import com.example.mear.R
import com.example.mear.repositories.TrackRepository
import com.example.mear.util.ExtractCover
class SongViewActivity : AppCompatActivity() {
private var trackListItems = arrayListOf<TrackItems>()
private lateinit var adapter: RecyclerAdapter
private lateinit var linearLayoutManager: LinearLayoutManager
private lateinit var listView: ListView
@RequiresApi(Build.VERSION_CODES.N)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_song_view)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
initializeAdapter()
try {
window.statusBarColor = resources.getColor(R.color.track_seek)
initializeAdapter()
}
catch (ex: Exception) {
var exMsg = ex.message
}
}
override fun onStart() {
super.onStart()
if (trackListItems.size == 0) {
val df = ""
}
}
@RequiresApi(Build.VERSION_CODES.N)
private fun initializeAdapter() {
listView = findViewById<ListView>(R.id.recipe_list_view)
// 1
val recipeList = Recipe.getRecipesFromFile("recipes.json", this)
// 2
val listItems = arrayOfNulls<String>(recipeList.size)
// 3
for (i in 0 until recipeList.size) {
val recipe = recipeList[i]
listItems[i] = recipe.title
try {
linearLayoutManager = LinearLayoutManager(this)
trackList.layoutManager = linearLayoutManager
trackListItems = retrieveTrackItems()
adapter = RecyclerAdapter(trackListItems)
trackList.adapter = adapter
trackList.setHasFixedSize(true)
//trackList.setItemViewCacheSize(20);
//trackList.setDrawingCacheEnabled(true);
//trackList.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
}
// 4
val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, listItems)
listView.adapter = adapter
catch (ex: Exception) {
val exMsg = ex.message
}
}
@RequiresApi(Build.VERSION_CODES.N)
private fun retrieveTrackItems(): ArrayList<TrackItems> {
var trackItems: ArrayList<TrackItems>? = null
try {
trackItems = arrayListOf()
val tracks = TrackRepository(this).getAll()
var index = 0
val max = 200
var done = false
/**
tracks.parallelStream().map {track ->
val cover = ExtractCover(track.songPath)
var trackCover = ByteArray(0)
if (cover.hasCover() && !done) {
if (index < max ) {
trackCover = cover.retrieveCover()
}
else {
done = true
}
index++
}
if (done) {
//return trackItems
}
val trackItem = TrackItems(track.id, track.title, track.artist, trackCover!!)
trackItems.add(trackItem)
}
*/
for (track in tracks) {
val cover = ExtractCover(track.songPath)
var trackCover = ByteArray(0)
if (cover.hasCover() && !done) {
if (index < max ) {
trackCover = cover.retrieveCover()
}
else {
done = true
}
index++
}
if (done) {
return trackItems
}
val trackItem = TrackItems(track.id, track.title, track.artist, trackCover!!)
trackItems.add(trackItem)
}
return trackItems
}
catch (ex: Exception) {
val exMsg = ex.message
}
return trackItems!!
}
}
@@ -1,63 +1,81 @@
package com.example.mear.com.example.mear.adapters
package com.example.mear.adapters
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.content.Intent
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.RecyclerView.Adapter
import android.view.LayoutInflater
import android.widget.TextView
import android.widget.ImageView
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import java.lang.Exception
import kotlinx.android.synthetic.main.fragment_song_view.view.*
import com.squareup.picasso.Picasso
import com.example.mear.activities.SongViewActivity
import com.example.mear.constants.Filenames
import com.example.mear.inflate
import com.example.mear.models.TrackItems
import com.example.mear.R
class RecyclerAdapter(private val context: Context,
private val source: ArrayList<TrackItems>): BaseAdapter() {
class RecyclerAdapter( private val trackItemsSourceInit: ArrayList<TrackItems>) :
RecyclerView.Adapter<RecyclerAdapter.TrackItemsHolder>() {
private val inflater: LayoutInflater
= context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
override fun getCount(): Int {
return source.size
override fun getItemCount(): Int {
return trackItemsSourceInit!!.size
}
//2
override fun getItem(position: Int): Any {
return source[position]
override fun onBindViewHolder(holder: TrackItemsHolder, position: Int) {
val itemPhoto = trackItemsSourceInit!![position]
holder.bindTrackItems(itemPhoto)
}
//3
override fun getItemId(position: Int): Long {
return position.toLong()
override fun onCreateViewHolder(parent: ViewGroup, position: Int): TrackItemsHolder {
val inflatedView = parent.inflate(R.layout.fragment_song_view, false)
return TrackItemsHolder(inflatedView)
}
//4
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
// Get view for row item
val rowView = inflater.inflate(R.layout.fragment_song_view, parent, false)
val trackTitleTextView = rowView.findViewById(R.id.trackTitle) as TextView
// Get subtitle element
val trackArtistTextView= rowView.findViewById(R.id.trackArtist) as TextView
// Get detail element
val trackCoverImageView = rowView.findViewById(R.id.trackCover) as ImageView
val track = getItem(position) as TrackItems
// 2
trackTitleTextView.text = track.trackTitle
trackArtistTextView.text = track.artistTitle
trackCoverImageView.setImageBitmap(BitmapFactory.decodeByteArray(track.trackCover, 0, track.trackCover.size))
class TrackItemsHolder(v: View) : RecyclerView.ViewHolder(v), View.OnClickListener {
private var view: View = v
private var trackItem: TrackItems? = null
private val imgWidth = 90
private val imgHeight = 90
return rowView
init {
v.setOnClickListener(this)
}
override fun onClick(v: View) {
try {
val context = itemView.context
val showPhotoIntent = Intent(context, SongViewActivity::class.java)
//showPhotoIntent.putExtra(PHOTO_KEY, trackItem)
context.startActivity(showPhotoIntent)
}
catch (ex: Exception) {
val exMsg = ex.message
}
}
fun bindTrackItems(trackItems: TrackItems) {
try {
var context = view.context
this.trackItem = trackItems
view.trackTitle.text = trackItem!!.trackTitle
view.trackArtist.text = trackItem!!.artistTitle
val id = trackItems.id
var trackCoverPath = "${context.filesDir}/${Filenames.TRACK_COVERS}"
trackCoverPath = "${trackCoverPath}${id}.bmp"
Picasso.get().load(trackCoverPath).into(view.trackCover)
}
catch (ex:Exception) {
val exMsg = ex.message
}
}
companion object {
private val PHOTO_KEY = "PHOTO"
}
}
}
@@ -0,0 +1,5 @@
package com.example.mear.constants
object Filenames {
const val TRACK_COVERS = "TrackCover_"
}
@@ -56,9 +56,11 @@ class MusicFiles (private val demoPath: File) {
println(it.absolutePath)
if (!ignoreThisDirectory(it.absolutePath)) {
if (it.isFile) {
/**
if (it.endsWith(FileTypes.Mp3)) {
pathList.add(it.absolutePath)
}
*/
if (it.extension.toString().equals(FileTypes.Mp3)) {
pathList.add(it.absolutePath)
}
@@ -5,9 +5,11 @@ import android.media.MediaMetadataRetriever
import java.lang.Exception
import com.example.mear.constants.Filenames
import com.example.mear.models.Track
import com.example.mear.repositories.PlayCountRepository
import com.example.mear.repositories.TrackRepository
import com.example.mear.util.ConvertByteArray
class TrackManager(var allSongPath: MutableList<String>) {
@@ -33,19 +35,31 @@ class TrackManager(var allSongPath: MutableList<String>) {
val track = Track(id, trackTitle, trackArtist, trackAlbum, trackLength,
ByteArray(0), musicPath)
dumpToDatabase(ctx, track)
saveTrackCoverToDisk(ctx, id, mmr.embeddedPicture)
id++
}
TrackRepository(ctx).createSongCount((id -1))
}
catch (ex: Exception) {
val exMsg = ex.message
}
TrackRepository(ctx).createSongCount((id -1))
return id.dec()
}
private fun dumpToDatabase(ctx: Context, track: Track) {
TrackRepository(ctx).insertTrack(track)
PlayCountRepository(ctx).insertPlayCount(track)
}
private fun saveTrackCoverToDisk(context: Context, id: Int, trackCover: ByteArray) {
val filename = "${Filenames.TRACK_COVERS}$id.bmp"
val fileContents = trackCover
var img = ConvertByteArray(trackCover).convertToBmp()
context.openFileOutput(filename, Context.MODE_PRIVATE).use {
it.write(fileContents)
}
}
var allTracks: MutableList<Track>? = null
}
@@ -5,7 +5,6 @@ import android.content.Intent
import android.media.MediaPlayer
import android.os.Binder
import android.os.IBinder
import android.support.v4.media.VolumeProviderCompat
import android.widget.Toast
import java.lang.Exception
@@ -19,7 +18,6 @@ import com.example.mear.models.Track
import com.example.mear.repositories.RepeatRepository
import com.example.mear.repositories.ShuffleRepository
import com.example.mear.repositories.TrackRepository
import java.util.*
class MusicService: Service() {
@@ -243,19 +241,24 @@ class MusicService: Service() {
private fun initializeMediaPlayer() {
if (trackPlayer == null) {
trackPlayer = MediaPlayer()
}
if (trackRepositoryEmpty()!!) {
populateTrackRepository()
}
try {
if (trackPlayer == null) {
trackPlayer = MediaPlayer()
}
if (trackRepositoryEmpty()!!) {
populateTrackRepository()
}
currentSongIndex = Random.nextInt(0, TrackRepository(this).getSongCount())
val trackToPlay = TrackRepository(this).getTrack(currentSongIndex!!)
trackPlayer!!.setDataSource(trackToPlay.songPath)
trackPlayer!!.prepareAsync()
trackPlayer!!.setOnCompletionListener {
playNextTrack()
currentSongIndex = Random.nextInt(0, TrackRepository(this).getSongCount())
val trackToPlay = TrackRepository(this).getTrack(currentSongIndex!!)
trackPlayer!!.setDataSource(trackToPlay.songPath)
trackPlayer!!.prepareAsync()
trackPlayer!!.setOnCompletionListener {
playNextTrack()
}
}
catch (ex: Exception) {
val exMsg = ex.message
}
}
private fun populateTrackRepository() {
@@ -345,6 +348,9 @@ class MusicService: Service() {
private fun trackRepositoryEmpty(): Boolean? {
val trackCount = retrieveSongCount()
if (trackCount!! < 1) {
return true
}
when (trackCount) {
null -> {
return true
@@ -361,7 +367,6 @@ class MusicService: Service() {
try {
//var db = DatabaseManager(this)
var trackDb = TrackRepository(this)
val count = TrackRepository(this).getSongCount()
return count
@@ -0,0 +1,19 @@
package com.example.mear.util
import android.graphics.Bitmap
import android.graphics.BitmapFactory
class ConvertByteArray(private val byteArray: ByteArray) {
fun convertToBmp(): Bitmap {
val songImage = BitmapFactory
.decodeByteArray(byteArray, 0, byteArray.size)
return songImage
}
fun convertToBmptScales(width: Int, height: Int): Bitmap {
val b = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size)
return Bitmap.createScaledBitmap(b, width, height, false)
}
}
@@ -0,0 +1,24 @@
package com.example.mear.util
import android.media.MediaMetadataRetriever
class ExtractCover(private val trackPath: String) {
fun retrieveCover(): ByteArray {
var trackData = MediaMetadataRetriever()
trackData.setDataSource(trackPath)
return trackData.embeddedPicture
}
fun hasCover(): Boolean {
var trackData = MediaMetadataRetriever()
trackData.setDataSource(trackPath)
if (trackData.embeddedPicture == null) {
return false
}
return true
}
}
+9 -1
View File
@@ -1,8 +1,16 @@
package com.example.mear
import android.content.Context
import android.support.annotation.LayoutRes
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.mear.management.DatabaseManager
val Context.database: DatabaseManager
get() = DatabaseManager.getInstance(applicationContext)
get() = DatabaseManager.getInstance(applicationContext)
fun ViewGroup.inflate(@LayoutRes layoutRes: Int, attachToRoot: Boolean = false): View {
return LayoutInflater.from(context).inflate(layoutRes, this, attachToRoot)
}
+18 -18
View File
@@ -2,37 +2,37 @@
<android.support.design.widget.CoordinatorLayout 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:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="@color/color_background"
tools:context=".activities.SongViewActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/app_bar_height"
android:fitsSystemWindows="true"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/toolbar_layout"
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@+id/toolbar">
android:layout_height="?attr/actionBarSize"
android:background="@color/color_background"
app:popupTheme="@style/AppTheme.PopupOverlay" />
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_song_view" />
<include
android:id="@+id/include2"
layout="@layout/content_song_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.design.widget.CoordinatorLayout>
+34 -6
View File
@@ -1,17 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.constraint.ConstraintLayout 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"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activities.SongViewActivity"
tools:showIn="@layout/activity_song_view">
android:padding="8dp">
<Space
android:id="@+id/space2"
android:layout_width="12dp"
android:layout_height="55dp"
android:layout_marginStart="120dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.v7.widget.RecyclerView
android:id="@+id/trackList"
marginTop="?android:attr/actionBarSize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android:layout_height="0dp"
android:layout_marginStart="4dp"
android:layout_marginTop="15dp"
android:layout_marginBottom="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/space2"
tools:itemCount="4"
tools:listitem="@layout/recycler_view_item" />
<!--
<android.support.v7.widget.RecyclerView
android:id="@+id/trackList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:layout_marginEnd="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.044"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
-->
</android.support.v4.widget.NestedScrollView>
</android.support.constraint.ConstraintLayout>
+28 -12
View File
@@ -1,15 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
<android.support.constraint.ConstraintLayout 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="wrap_content"
android:padding="8dp">
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/cv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
card_view:cardCornerRadius="5dp">
android:layout_width="wrap_content"
android:layout_height="80dp"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="4dp"
card_view:cardBackgroundColor="@color/colorPrimary"
card_view:cardCornerRadius="5dp"
card_view:layout_constraintBottom_toBottomOf="parent"
card_view:layout_constraintEnd_toEndOf="parent"
card_view:layout_constraintStart_toStartOf="parent"
card_view:layout_constraintTop_toTopOf="parent"
card_view:layout_constraintVertical_bias="1.0">
<LinearLayout
@@ -22,8 +35,7 @@
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginTop="10dp"
android:background="#c0c0c0"/>
android:layout_marginTop="10dp" />
<LinearLayout
android:layout_width="match_parent"
@@ -37,7 +49,7 @@
card_view:srcCompat="@mipmap/ic_launcher_round" />
<LinearLayout
android:layout_width="290dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
@@ -46,12 +58,14 @@
android:id="@+id/trackTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/track_details"
android:textSize="16sp" />
<TextView
android:id="@+id/trackArtist"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
android:textColor="@color/track_details" />
</LinearLayout>
@@ -62,3 +76,5 @@
</android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>
+1 -1
View File
@@ -7,6 +7,6 @@
<color name="color_player_not_initialized">#585858</color>
<!-- Play Controls -->
<color name="track_details">#ffffff</color>
<color name="track_details">#FFFFFF</color>
<color name="track_seek">#333399</color>
</resources>