diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 64d7de01..71fcd374 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -26,9 +26,14 @@
+
+
+
+
-
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
new file mode 100644
index 00000000..d6cd1525
Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/com/shabinder/musicForEveryone/MainActivity.kt b/app/src/main/java/com/shabinder/musicForEveryone/MainActivity.kt
index 0789fe4b..26d2db73 100644
--- a/app/src/main/java/com/shabinder/musicForEveryone/MainActivity.kt
+++ b/app/src/main/java/com/shabinder/musicForEveryone/MainActivity.kt
@@ -4,26 +4,22 @@ import android.Manifest
import android.app.DownloadManager
import android.content.Context
import android.content.Intent
+import android.content.SharedPreferences
+import android.net.ConnectivityManager
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
-import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.github.kiulian.downloader.YoutubeDownloader
import com.shabinder.musicForEveryone.databinding.MainActivityBinding
import com.shabinder.musicForEveryone.downloadHelper.DownloadHelper
-import com.shabinder.musicForEveryone.utils.SpotifyNewService
+import com.shabinder.musicForEveryone.utils.SpotifyService
+import com.shabinder.musicForEveryone.utils.SpotifyServiceToken
import com.shabinder.musicForEveryone.utils.YoutubeInterface
-import com.spotify.sdk.android.authentication.AuthenticationClient
-import com.spotify.sdk.android.authentication.AuthenticationRequest
-import com.spotify.sdk.android.authentication.AuthenticationResponse
-import com.spotify.sdk.android.authentication.LoginActivity
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
-import kaaes.spotify.webapi.android.SpotifyApi
-import kaaes.spotify.webapi.android.SpotifyService
import kotlinx.coroutines.launch
import okhttp3.Interceptor
import okhttp3.OkHttpClient
@@ -32,30 +28,43 @@ import okhttp3.Response
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
-
+@Suppress("DEPRECATION")
class MainActivity : AppCompatActivity() ,DownloadHelper{
private lateinit var binding: MainActivityBinding
- var ytDownloader : YoutubeDownloader? = null
- var spotifyExtra : SpotifyNewService? = null
- var downloadManager : DownloadManager? = null
- val REDIRECT_URI = "musicforeveryone://callback"
- val CLIENT_ID:String = "694d8bf4f6ec420fa66ea7fb4c68f89d"
- var token :String =""
- var spotify: SpotifyService? = null
- lateinit var sharedViewModel: SharedViewModel
+ private var ytDownloader : YoutubeDownloader? = null
+ private var spotifyService : SpotifyService? = null
+ private var spotifyServiceToken : SpotifyServiceToken? = null
+ private var downloadManager : DownloadManager? = null
+// private val redirectUri = "musicforeveryone://callback"
+ private val clientId:String = "694d8bf4f6ec420fa66ea7fb4c68f89d"
+ private val clientSecret:String = "02ca2d4021a7452dae2328b47a6e8fe8"
+ private var isConnected: Boolean = false
+ private var sharedPref :SharedPreferences? = null
+
+ private var token :String =""
+ private lateinit var sharedViewModel: SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this,R.layout.main_activity)
-
sharedViewModel = ViewModelProvider(this).get(SharedViewModel::class.java)
-// val policy =
-// StrictMode.ThreadPolicy.Builder().permitAll().build()
-// StrictMode.setThreadPolicy(policy)
- //TODO Use Coroutines
- if(spotify==null){
+ sharedPref = this.getPreferences(Context.MODE_PRIVATE)
+
+// if(sharedPref?.contains("token")!! && (sharedPref?.getLong("time",System.currentTimeMillis()/1000/60/60)!! < (System.currentTimeMillis()/1000/60/60)) ){
+// val savedToken = sharedPref?.getString("token","error")!!
+// sharedViewModel.accessToken.value = savedToken
+// Log.i("SharedPrefs Token:",savedToken)
+// token = savedToken
+//
+// implementSpotifyService(savedToken)
+// }else{authenticateSpotify()}
+
+ if(sharedViewModel.spotifyService == null){
authenticateSpotify()
+ }else{
+ implementSpotifyService(sharedViewModel.accessToken.value!!)
}
+
requestPermission()
//Object to download From Youtube {"https://github.com/sealedtx/java-youtube-downloader"}
@@ -68,69 +77,22 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
sharedViewModel.downloadManager = downloadManager
- if (intent?.action == Intent.ACTION_SEND) {
- if ("text/plain" == intent.type) {
- intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
- Log.i("Intent Received",it)
- sharedViewModel.intentString = it
- }
- }
- }
- }
+ isConnected = isOnline()
+ sharedViewModel.isConnected.value = isConnected
+
+ Log.i("Connection Status",isConnected.toString())
- override fun onActivityResult(
- requestCode: Int,
- resultCode: Int,
- intent: Intent?
- ) {
- super.onActivityResult(requestCode, resultCode, intent)
- // Check if result comes from the correct activity
- if (requestCode == LoginActivity.REQUEST_CODE) {
- val response = AuthenticationClient.getResponse(resultCode, intent)
- when (response.type) {
- AuthenticationResponse.Type.TOKEN -> {
- Log.i("Network",response.accessToken.toString())
- token = response.accessToken
- sharedViewModel.accessToken = response.accessToken
-
- //Implementing My Own Spotify Requests
- implementSpotifyExtra()
- val api = SpotifyApi()
- api.setAccessToken(token)
- spotify = api.service
- sharedViewModel.spotify = api.service
- //Initiate Processes In Main Fragment
-
- sharedViewModel.uiScope.launch {
- val me = spotifyExtra?.getMe()?.display_name
- sharedViewModel.userName.value = "Logged in as: $me"
- Log.i("Network","Hello, " + me!!)
- }
-
- sharedViewModel.userName.observe(this, Observer {
- binding.message.text = it
- })
- }
-
-
- AuthenticationResponse.Type.ERROR -> {
- Log.i("Network",response.error.toString())
- }
- else -> {
- }
- }
- }
+ handleIntentFromExternalActivity()
}
/**
* Adding my own new Spotify Web Api Requests!
* */
- private fun implementSpotifyExtra() {
-
+ private fun implementSpotifyService(token:String) {
val httpClient: OkHttpClient.Builder = OkHttpClient.Builder()
-
httpClient.addInterceptor(object : Interceptor {
+
override fun intercept(chain: Interceptor.Chain): Response {
val request: Request =
chain.request().newBuilder().addHeader(
@@ -146,17 +108,89 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
.add(KotlinJsonAdapterFactory())
.build()
- val retrofit: Retrofit =
- Retrofit.Builder()
+ val retrofit = Retrofit.Builder()
.baseUrl("https://api.spotify.com/v1/")
.client(httpClient.build())
.addConverterFactory(MoshiConverterFactory.create(moshi))
.build()
- spotifyExtra = retrofit.create(SpotifyNewService::class.java)
- sharedViewModel.spotifyExtra = spotifyExtra
+ spotifyService = retrofit.create(SpotifyService::class.java)
+ sharedViewModel.spotifyService = spotifyService
}
+ private fun getSpotifyToken(){
+ val httpClient2: OkHttpClient.Builder = OkHttpClient.Builder()
+ httpClient2.addInterceptor(object : Interceptor {
+ override fun intercept(chain: Interceptor.Chain): Response {
+ val request: Request =
+ chain.request().newBuilder().addHeader(
+ "Authorization",
+ "Basic ${android.util.Base64.encodeToString("$clientId:$clientSecret".toByteArray(),android.util.Base64.NO_WRAP)}"
+ ).build()
+ return chain.proceed(request)
+ }
+ })
+
+ val moshi = Moshi.Builder()
+ .add(KotlinJsonAdapterFactory())
+ .build()
+
+ val retrofit2 = Retrofit.Builder()
+ .baseUrl("https://accounts.spotify.com/")
+ .client(httpClient2.build())
+ .addConverterFactory(MoshiConverterFactory.create(moshi))
+ .build()
+
+ spotifyServiceToken = retrofit2.create(SpotifyServiceToken::class.java)
+
+ }
+
+ private fun authenticateSpotify() {
+ if (spotifyServiceToken == null) {
+ getSpotifyToken()
+ }
+ sharedViewModel.uiScope.launch {
+ if (isConnected) {
+ Log.i("Post Request", "Made")
+ token = spotifyServiceToken!!.getToken()!!.access_token
+ implementSpotifyService(token)
+ Log.i("Post Request", token)
+ sharedViewModel.accessToken.value = token
+ saveToken(token)
+ }else{
+ Log.i("network", "unavailable")
+// sharedViewModel.showAlertDialog(resources,this@MainActivity)
+ }
+ }
+ }
+
+ private fun saveToken(token:String) {
+ with (sharedPref?.edit()) {
+ this?.let {
+ putString("token", token)
+ putLong("time",(System.currentTimeMillis()/1000/60/60))
+ commit()
+ }
+ }
+ }
+
+ private fun handleIntentFromExternalActivity() {
+ if (intent?.action == Intent.ACTION_SEND) {
+ if ("text/plain" == intent.type) {
+ intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
+ Log.i("Intent Received",it)
+ sharedViewModel.intentString = it
+ }
+ }
+ }
+ }
+
+ private fun isOnline(): Boolean {
+ val cm =
+ getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ val netInfo = cm.activeNetworkInfo
+ return netInfo != null && netInfo.isConnectedOrConnecting
+ }
private fun requestPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
@@ -167,13 +201,66 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
}
}
+ override fun onSaveInstanceState(savedInstanceState:Bundle) {
+ savedInstanceState.putString("token",token)
+ super.onSaveInstanceState(savedInstanceState)
+ }
+ override fun onRestoreInstanceState(savedInstanceState: Bundle) {
+ if (savedInstanceState.getString("token") ==""){
+ super.onRestoreInstanceState(savedInstanceState)
+ }else{
+ implementSpotifyService(savedInstanceState.getString("token")!!)
+ super.onRestoreInstanceState(savedInstanceState)
+ }
+ }
+
+ /*
private fun authenticateSpotify() {
- val builder = AuthenticationRequest.Builder(CLIENT_ID,AuthenticationResponse.Type.TOKEN,REDIRECT_URI)
- .setShowDialog(false)
- .setScopes(arrayOf("user-read-private","streaming","user-read-email","user-modify-playback-state","user-top-read","user-library-modify","user-read-currently-playing","user-library-read","user-read-recently-played"))
+ val builder = AuthenticationRequest.Builder(clientId,AuthenticationResponse.Type.TOKEN,redirectUri)
+ .setScopes(arrayOf("user-read-private"))
+// .setScopes(arrayOf("user-read-private","streaming","user-read-email","user-modify-playback-state","user-top-read","user-library-modify","user-read-currently-playing","user-library-read","user-read-recently-played"))
val request: AuthenticationRequest = builder.build()
AuthenticationClient.openLoginActivity(this, LoginActivity.REQUEST_CODE, request)
- }
+ }*/
+
+ /*override fun onActivityResult(
+ requestCode: Int,
+ resultCode: Int,
+ intent: Intent?
+ ) {
+ super.onActivityResult(requestCode, resultCode, intent)
+ // Check if result comes from the correct activity
+ if (requestCode == LoginActivity.REQUEST_CODE) {
+ val response = AuthenticationClient.getResponse(resultCode, intent)
+ when (response.type) {
+ AuthenticationResponse.Type.TOKEN -> {
+ Log.i("Network",response.accessToken.toString())
+ token = response.accessToken
+ sharedViewModel.accessToken = response.accessToken
+
+ //Implementing My Own Spotify Requests
+ implementSpotifyService(token)
+
+ sharedViewModel.uiScope.launch {
+ val me = spotifyService?.getMe()?.display_name
+ sharedViewModel.userName.value = "Logged in as: $me"
+ Log.i("Network","Hello, " + me!!)
+ }
+
+ sharedViewModel.userName.observe(this, Observer {
+ binding.message.text = it
+ })
+ }
+ AuthenticationResponse.Type.ERROR -> {
+ Log.i("Network",response.error.toString())
+ }
+ else -> {
+ Log.i("Network","Something Weird Happened While Authenticating")
+ }
+ }
+ }
+ }
+*/
}
\ No newline at end of file
diff --git a/app/src/main/java/com/shabinder/musicForEveryone/SharedViewModel.kt b/app/src/main/java/com/shabinder/musicForEveryone/SharedViewModel.kt
index a25b9dbb..031ed597 100644
--- a/app/src/main/java/com/shabinder/musicForEveryone/SharedViewModel.kt
+++ b/app/src/main/java/com/shabinder/musicForEveryone/SharedViewModel.kt
@@ -1,39 +1,40 @@
package com.shabinder.musicForEveryone
import android.app.DownloadManager
+import android.content.Context
+import android.content.res.Resources
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.github.kiulian.downloader.YoutubeDownloader
-import com.shabinder.musicForEveryone.utils.SpotifyNewService
-import kaaes.spotify.webapi.android.SpotifyService
-import kaaes.spotify.webapi.android.models.Album
-import kaaes.spotify.webapi.android.models.Playlist
-import kaaes.spotify.webapi.android.models.Track
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import com.shabinder.musicForEveryone.models.Album
+import com.shabinder.musicForEveryone.models.Playlist
+import com.shabinder.musicForEveryone.models.Track
+import com.shabinder.musicForEveryone.utils.SpotifyService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
class SharedViewModel : ViewModel() {
var intentString = ""
- var accessToken:String = ""
- var userName = MutableLiveData().apply { value = "Placeholder" }
- var spotify :SpotifyService? = null
- var spotifyExtra : SpotifyNewService? = null
+ var accessToken = MutableLiveData().apply { value = "" }
+ var spotifyService : SpotifyService? = null
var ytDownloader : YoutubeDownloader? = null
var downloadManager : DownloadManager? = null
+ var isConnected = MutableLiveData().apply { value = false }
- var viewModelJob = Job()
+ private var viewModelJob = Job()
val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
suspend fun getTrackDetails(trackLink:String): Track?{
- return spotifyExtra?.getTrack(trackLink)
+ return spotifyService?.getTrack(trackLink)
}
suspend fun getAlbumDetails(albumLink:String): Album?{
- return spotifyExtra?.getAlbum(albumLink)
+ return spotifyService?.getAlbum(albumLink)
}
suspend fun getPlaylistDetails(link:String): Playlist?{
- return spotifyExtra?.getPlaylist(link)
+ return spotifyService?.getPlaylist(link)
}
@@ -41,4 +42,15 @@ class SharedViewModel : ViewModel() {
super.onCleared()
viewModelJob.cancel()
}
+
+ fun showAlertDialog(resources:Resources,context: Context){
+ val dialog = MaterialAlertDialogBuilder(context,R.style.AlertDialogTheme)
+ .setTitle(resources.getString(R.string.title))
+ .setMessage(resources.getString(R.string.supporting_text))
+ .setPositiveButton(resources.getString(R.string.cancel)) { _, _ ->
+ // Respond to neutral button press
+ }
+ .setBackground(resources.getDrawable(R.drawable.gradient))
+ .show()
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/shabinder/musicForEveryone/downloadHelper/DownloadHelper.kt b/app/src/main/java/com/shabinder/musicForEveryone/downloadHelper/DownloadHelper.kt
index 13126423..9fb04cdc 100644
--- a/app/src/main/java/com/shabinder/musicForEveryone/downloadHelper/DownloadHelper.kt
+++ b/app/src/main/java/com/shabinder/musicForEveryone/downloadHelper/DownloadHelper.kt
@@ -8,18 +8,29 @@ import android.util.Log
import com.github.kiulian.downloader.YoutubeDownloader
import com.github.kiulian.downloader.model.formats.Format
import com.github.kiulian.downloader.model.quality.AudioQuality
+import com.shabinder.musicForEveryone.fragments.MainFragment
+import com.shabinder.musicForEveryone.models.Track
import com.shabinder.musicForEveryone.utils.YoutubeInterface
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
interface DownloadHelper {
+
+ /**
+ * Function To Download All Tracks Available in a List
+ **/
+ suspend fun downloadAllTracks(trackList : List