asp616848 / AudioSwitch---EqualizedEvo

Open-source as well as ad-free. This project is not completed yet, upon completion it will be a music player with 3D spatial-audio, player-features, equalizer, Innovative widgets, system wide audio-switch & equalizer and a euphoric ui.
7 stars 0 forks source link

Unsupported metadata version. Check that your Kotlin version is >= 1.0: java.lang.IllegalStateException: Unsupported metadata version. Check that your Kotlin version is >= 1.0 #1

Closed asp616848 closed 6 months ago

asp616848 commented 6 months ago

After implementing Hilt for DI, the build fails and seems to have error.

You may use code below for reference, fix it and pull-request or implement hilt independently to improve architecture of the Equalized-Evo repo. The below file can be found in the HiltImp branch and working is on main branch.

Thanks to everyone willing to help :)

`package com.example.audioswitch_equalizedevo.ui.activities

import android.Manifest import android.content.pm.PackageManager import android.os.Build import android.os.Bundle import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.annotation.RequiresApi import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.ui.Modifier import androidx.core.content.ContextCompat import androidx.lifecycle.ViewModelProvider import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.example.audioswitch_equalizedevo.data.Songs import com.example.audioswitch_equalizedevo.ui.screens.HomeScreen import com.example.audioswitch_equalizedevo.ui.screens.PlayerScreen import com.example.audioswitch_equalizedevo.ui.theme.AudioSwitch_EqualizedEvoTheme import com.example.audioswitch_equalizedevo.ui.viewModels.SongsViewModel import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint class MainActivity : ComponentActivity() { @RequiresApi(Build.VERSION_CODES.TIRAMISU) private val readAudioPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) Manifest.permission.READ_MEDIA_AUDIO else Manifest.permission.READ_EXTERNAL_STORAGE private val requestPermissionLauncher: ActivityResultLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> if (isGranted) { Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show() } else { Toast.makeText(this, "Permission is required to access Music Files, Enable it in device settings", Toast.LENGTH_SHORT).show() } }

@RequiresApi(Build.VERSION_CODES.TIRAMISU)
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    checkPermission()
    val viewModel : SongsViewModel by viewModels()
    setContent {
        enableEdgeToEdge()
        val navController = rememberNavController()
        AudioSwitch_EqualizedEvoTheme {
            Surface(
                modifier = Modifier.fillMaxSize(),
                color = MaterialTheme.colorScheme.background
            ) {
                NavHost(navController = navController, startDestination = "home") {
                    composable("home") { HomeScreen(navController, viewModel) }
                    composable("player") { PlayerScreen(navController, viewModel) }
                }
            }
        }
    }
}
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
private fun checkPermission() {
    if (ContextCompat.checkSelfPermission(
            this,
            readAudioPermission
        ) == PackageManager.PERMISSION_DENIED
    ) {
        requestPermissionLauncher.launch(readAudioPermission)
    }
    else{
        Toast.makeText(this, "Welcome", Toast.LENGTH_SHORT).show()
    }
}

}

package com.example.audioswitch_equalizedevo.data

import android.content.Context import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.android.components.ViewModelComponent import dagger.hilt.android.qualifiers.ApplicationContext import javax.inject.Singleton

@Module @InstallIn(Singleton::class) object ExoplayerModule { @Provides @Singleton fun provideExoplayer(@ApplicationContext context: Context?): ExoPlayer1 { // Initialize and configure your ExoPlayer1 instance here return ExoPlayer1(context!!) // Replace null with actual ExoPlayer1 instance } }

@Module @InstallIn(Singleton::class) object FetchMusicModule {

@Provides
@Singleton
fun provideFetchMusic(@ApplicationContext context: Context): FetchMusic {
    // Initialize and configure your FetchMusic instance here
    return FetchMusic(context)
}

}package com.example.audioswitch_equalizedevo.data

import android.content.Context import android.widget.Toast import androidx.media3.common.MediaItem import androidx.media3.exoplayer.ExoPlayer import dagger.hilt.android.qualifiers.ActivityContext import javax.inject.Inject

class ExoPlayer1 @Inject constructor(@ActivityContext val context: Context) { private val exoPlayer = ExoPlayer.Builder(context).build() var MediaList: List = emptyList()

fun getExoPlayer(): ExoPlayer {
    return exoPlayer
}
fun playNext() {
    if (exoPlayer.hasNextMediaItem()){
        exoPlayer.seekToNextMediaItem()
    }else{
        Toast.makeText(context, "No Next Song", Toast.LENGTH_SHORT).show()
    }
}
fun playPrev() {
    if (exoPlayer.hasPreviousMediaItem()){
        exoPlayer.seekToPreviousMediaItem()
    }else{
        Toast.makeText(context, "No Previous Song", Toast.LENGTH_SHORT).show()
    }
}

}package com.example.audioswitch_equalizedevo.ui.viewModels

import android.net.Uri import androidx.lifecycle.ViewModel import androidx.media3.common.MediaItem import com.example.audioswitch_equalizedevo.data.ExoPlayer1 import com.example.audioswitch_equalizedevo.data.FetchMusic import com.example.audioswitch_equalizedevo.data.Songs import com.example.audioswitch_equalizedevo.ui.UIState import com.example.audioswitch_equalizedevo.ui.screenState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import javax.inject.Inject

@HiltViewModel class SongsViewModel @Inject constructor( val fetchMusic: FetchMusic, val exoPlayer: ExoPlayer1 ) : ViewModel() { private val _songs = MutableStateFlow<List>(emptyList()) val songs: StateFlow<List> = _songs init { fetchSongs() }

fun fetchSongs() {
    fetchMusic.getPlayList().let {
        _songs.value = it
    }
}

private val _uiState = MutableStateFlow(UIState())
val uiState: StateFlow<UIState> = _uiState.asStateFlow()

override fun onCleared() {
    super.onCleared()
    exoPlayer.getExoPlayer().release()
}
fun playPause() {
    if(_uiState.value.isPlaying){
        _uiState.value = _uiState.value.copy(isPlaying = false)
        exoPlayer.getExoPlayer().pause()
    }
    else{
        _uiState.value = _uiState.value.copy(isPlaying = true)
        for (song in songs.value){
            exoPlayer.MediaList += MediaItem.fromUri (Uri.parse(song.fileUri))
        }
        exoPlayer.getExoPlayer().setMediaItems(exoPlayer.MediaList)
        exoPlayer.getExoPlayer().prepare()
        exoPlayer.getExoPlayer().play()
    }
}
fun getcurrentSong() : Songs {
    return exoPlayer.getExoPlayer().currentMediaItem?.mediaMetadata?.title?.let { title ->
        songs.value.first { it.title == title }
    } ?: songs.value.first()
}
fun changeScreen(s: screenState) {
    _uiState.value = _uiState.value.copy(screenState = s)
}

}package com.example.audioswitch_equalizedevo.data

import android.content.ContentUris import android.content.Context import android.database.Cursor import android.net.Uri import android.provider.MediaStore import dagger.hilt.android.qualifiers.ActivityContext import javax.inject.Inject

class FetchMusic @Inject constructor(@ActivityContext val context: Context){

private val songList = ArrayList<Songs>()
private val albumArtUri: Uri = Uri.parse("content://media/external/audio/albumart")

fun getPlayList() : ArrayList<Songs> {
    val selection: String? = null
    val selectionArgs: Array<String>? = null

    val proj = arrayOf(
        MediaStore.Audio.Media._ID,
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.ARTIST,
        MediaStore.Audio.Media.DURATION,
        MediaStore.Audio.Media.DATA,
        MediaStore.Audio.Media.ALBUM,
        MediaStore.Audio.Media.ALBUM_ID
    )

    val audioCursor: Cursor? = context.contentResolver.query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        proj,
        selection,
        selectionArgs,
        null
    )

    audioCursor?.use { cursor ->
        if (cursor.moveToFirst()) {
            do {
                val audioTitle = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)
                val audioArtist = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)
                val audioDuration = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)
                val audioData = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)
                val audioAlbum = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM)
                val audioAlbumId = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID)
                val songId = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)

                val info = Songs().apply {
                    fileUri = cursor.getString(audioData)
                    title = cursor.getString(audioTitle)
                    duration = cursor.getString(audioDuration)
                    artist = cursor.getString(audioArtist)
                    album = cursor.getString(audioAlbum)
                    id = cursor.getLong(songId)
                    albumArt = ContentUris.withAppendedId(albumArtUri, cursor.getLong(audioAlbumId)).toString()
                }
                songList.add(info)
            } while (cursor.moveToNext())
        }
    }
    return songList
}

} plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.jetbrainsKotlinAndroid) kotlin("kapt") id("com.google.dagger.hilt.android")

}

android { namespace = "com.example.audioswitch_equalizedevo" compileSdk = 34

defaultConfig {
    applicationId = "com.example.audioswitch_equalizedevo"
    minSdk = 24
    targetSdk = 34
    versionCode = 1
    versionName = "1.0"

    testInstrumentationRunner = "androidx.test.rWhat is the role of voltage source in the experimental set up of photoelectric effect?unner.AndroidJUnitRunner"
    vectorDrawables {
        useSupportLibrary = true
    }
}

buildTypes {
    release {
        isMinifyEnabled = false
        proguardFiles(
            getDefaultProguardFile("proguard-android-optimize.txt"),
            "proguard-rules.pro"
        )
    }
}
compileOptions {
    sourceCompatibility = JavaVersion.VERSION_1_8
    targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
    jvmTarget = "1.8"
}
buildFeatures {
    compose = true
}
composeOptions {
    kotlinCompilerExtensionVersion = "1.9.0"
}
packaging {
    resources {
        excludes += "/META-INF/{AL2.0,LGPL2.1}"
    }
}

}

dependencies { implementation("com.google.dagger:hilt-android:2.44") implementation(libs.material) implementation(libs.androidx.navigation.runtime.ktx) kapt("com.google.dagger:hilt-android-compiler:2.44") implementation(libs.androidx.core.ktx)

implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
implementation ("androidx.activity:activity-ktx:1.8.2")
implementation ("androidx.fragment:fragment-ktx:1.6.2")
// Testing Fragments in Isolation
debugImplementation ("androidx.fragment:fragment-testing:1.6.2")
// Cast dependencies for google services cast framework
implementation ("androidx.appcompat:appcompat:1.6.1")
implementation ("androidx.mediarouter:mediarouter:1.7.0")
implementation ("com.google.android.gms:play-services-cast-framework:21.4.0")
implementation ("androidx.compose.material:material-icons-extended-android:1.6.6")
implementation("androidx.media3:media3-exoplayer:1.3.1")
implementation("androidx.media3:media3-exoplayer-dash:1.3.1")
implementation("androidx.media3:media3-ui:1.3.1")
implementation ("io.coil-kt:coil-compose:2.4.0")
implementation ("androidx.navigation:navigation-compose:2.7.7")
kapt ("com.google.dagger:hilt-compiler:2.51.1")
implementation ("com.google.dagger:hilt-android:2.51.1")

} kapt { correctErrorTypes = true }`

asp616848 commented 6 months ago

Solved after updating kotlin version to 1.9.0