diff --git a/.idea/dictionaries/shabinder.xml b/.idea/dictionaries/shabinder.xml
index 16f2713a..599ffd82 100644
--- a/.idea/dictionaries/shabinder.xml
+++ b/.idea/dictionaries/shabinder.xml
@@ -1,7 +1,10 @@
+ ffmpeg
flyer
+ insta
+ instagram
moshi
musicforeveryone
musicplaceholder
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
index 4dcbce12..bd3984c7 100644
--- a/.idea/jarRepositories.xml
+++ b/.idea/jarRepositories.xml
@@ -31,5 +31,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 8940d6bc..d71765eb 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -20,7 +20,7 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs.kotlin"
-
+apply plugin: 'kotlinx-serialization'
android {
compileSdkVersion 29
@@ -28,16 +28,14 @@ android {
buildFeatures{
dataBinding = true
- viewBinding = true
}
defaultConfig {
applicationId 'com.shabinder.spotiflyer'
minSdkVersion 22
targetSdkVersion 29
- versionCode 1
- versionName "1.0"
-
+ versionCode 2
+ versionName "1.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -51,15 +49,20 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
sourceCompatibility JavaVersion.VERSION_1_8
}
+ lintOptions {
+ abortOnError false
+ }
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
}
+
+
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
- implementation 'androidx.core:core-ktx:1.3.0'
+ implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.browser:browser:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
@@ -72,17 +75,21 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7"
-// implementation "androidx.room:room-runtime:2.2.5"
-// kapt "androidx.room:room-compiler:2.2.5"
-// implementation "androidx.room:room-ktx:2.2.5"
- implementation "com.github.bumptech.glide:glide:4.11.0"
- kapt "com.github.bumptech.glide:compiler:4.11.0"
+ implementation "androidx.room:room-runtime:2.2.5"
+ kapt "androidx.room:room-compiler:2.2.5"
+ implementation "androidx.room:room-ktx:2.2.5"
+ implementation ("com.github.bumptech.glide:recyclerview-integration:4.11.0") {
+ transitive = true
+ }
+ kapt ("com.github.bumptech.glide:recyclerview-integration:4.11.0") {
+ transitive = true
+ }
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.apis:google-api-services-youtube:v3-rev180-1.22.0'
implementation 'com.google.oauth-client:google-oauth-client:1.22.0'
- implementation 'com.spotify.android:auth:1.1.0'
+// implementation 'com.spotify.android:auth:1.1.0'
implementation 'com.squareup.okhttp3:okhttp:4.8.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
@@ -90,8 +97,16 @@ dependencies {
implementation "com.squareup.moshi:moshi-kotlin:1.9.3"
implementation "com.squareup.retrofit2:converter-moshi:2.9.0"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" // or "kotlin-stdlib-jdk8"
+ implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0" // JVM dependency
+
+ implementation 'com.mpatric:mp3agic:0.9.1'
+ implementation 'com.arthenica:mobile-ffmpeg-audio:4.4.LTS'
+
implementation 'com.shreyaspatil:EasyUpiPayment:2.2'
- implementation 'com.github.sealedtx:java-youtube-downloader:2.2.2'
+ implementation 'com.github.sealedtx:java-youtube-downloader:2.2.3'
+ implementation "androidx.tonyodev.fetch2:xfetch2:3.1.4"
+ implementation 'com.github.javiersantos:AppUpdater:2.7'
implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
testImplementation 'junit:junit:4.13'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 011f3294..37f088d9 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -26,9 +26,12 @@
-
+
+
+
-
-
-
+-->
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/shabinder/spotiflyer/App.kt b/app/src/main/java/com/shabinder/spotiflyer/App.kt
new file mode 100644
index 00000000..82a589b0
--- /dev/null
+++ b/app/src/main/java/com/shabinder/spotiflyer/App.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 Shabinder Singh
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.shabinder.spotiflyer
+
+import android.app.Application
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Context
+import android.os.Build
+
+/*
+ * Copyright (C) 2020 Shabinder Singh
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+class App:Application() {
+ private val channelId = "ForegroundServiceChannel"
+
+ override fun onCreate() {
+ super.onCreate()
+ createNotificationChannel()
+ }
+
+ private fun createNotificationChannel() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val serviceChannel = NotificationChannel(
+ channelId,
+ "ForeGround Service Channel",
+ NotificationManager.IMPORTANCE_DEFAULT
+ )
+ val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
+ manager.createNotificationChannel(serviceChannel)
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt b/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt
index 9c675e07..5d1434cf 100644
--- a/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt
+++ b/app/src/main/java/com/shabinder/spotiflyer/MainActivity.kt
@@ -18,23 +18,26 @@
package com.shabinder.spotiflyer
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.net.Uri
import android.os.Build
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
+import com.github.javiersantos.appupdater.AppUpdater
+import com.github.javiersantos.appupdater.enums.UpdateFrom
import com.github.kiulian.downloader.YoutubeDownloader
import com.shabinder.spotiflyer.databinding.MainActivityBinding
import com.shabinder.spotiflyer.downloadHelper.DownloadHelper
import com.shabinder.spotiflyer.utils.SpotifyService
import com.shabinder.spotiflyer.utils.SpotifyServiceToken
import com.shabinder.spotiflyer.utils.YoutubeInterface
+import com.shabinder.spotiflyer.utils.createDirectory
import com.shreyaspatil.EasyUpiPayment.EasyUpiPayment
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
@@ -48,12 +51,11 @@ import retrofit2.converter.moshi.MoshiConverterFactory
@Suppress("DEPRECATION")
-class MainActivity : AppCompatActivity() ,DownloadHelper{
+class MainActivity : AppCompatActivity(){
private lateinit var binding: MainActivityBinding
private var ytDownloader : YoutubeDownloader? = null
private var spotifyService : SpotifyService? = null
private var spotifyServiceToken : SpotifyServiceToken? = null
- private var downloadManager : DownloadManager? = null
// private val redirectUri = "spotiflyer://callback"
private val clientId:String = "694d8bf4f6ec420fa66ea7fb4c68f89d"
private val clientSecret:String = "02ca2d4021a7452dae2328b47a6e8fe8"
@@ -63,20 +65,21 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
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)
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(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()
@@ -85,6 +88,12 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
}
requestPermission()
+ checkIfLatestVersion()
+ createDir()
+ setUpi()
+ isConnected = isOnline()
+ sharedViewModel.isConnected.value = isConnected
+ Log.i("Connection Status",isConnected.toString())
//Object to download From Youtube {"https://github.com/sealedtx/java-youtube-downloader"}
ytDownloader = YoutubeDownloader()
@@ -92,32 +101,9 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
//Initialing Communication with Youtube
YoutubeInterface.youtubeConnector()
- //Getting System Download Manager
- downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
- sharedViewModel.downloadManager = downloadManager
-
- isConnected = isOnline()
- sharedViewModel.isConnected.value = isConnected
-
- Log.i("Connection Status",isConnected.toString())
-
-
- easyUpiPayment = EasyUpiPayment.Builder()
- .with(this)
- .setPayeeVpa("technoshab@paytm")
- .setPayeeName("Shabinder Singh")
- .setTransactionId("UNIQUE_TRANSACTION_ID")
- .setTransactionRefId("UNIQUE_TRANSACTION_REF_ID")
- .setDescription("Thanks for donating")
- .setAmount("39.00")
- .build()
-
- sharedViewModel.easyUpiPayment = easyUpiPayment
-
handleIntentFromExternalActivity()
}
-
/**
* Adding my own new Spotify Web Api Requests!
* */
@@ -246,6 +232,48 @@ class MainActivity : AppCompatActivity() ,DownloadHelper{
}
}
+ private fun setUpi() {
+ easyUpiPayment = EasyUpiPayment.Builder()
+ .with(this)
+ .setPayeeVpa("technoshab@paytm")
+ .setPayeeName("Shabinder Singh")
+ .setTransactionId("UNIQUE_TRANSACTION_ID")
+ .setTransactionRefId("UNIQUE_TRANSACTION_REF_ID")
+ .setDescription("Thanks for donating")
+ .setAmount("39.00")
+ .build()
+
+ sharedViewModel.easyUpiPayment = easyUpiPayment
+
+ }
+
+ private fun createDir() {
+ createDirectory(DownloadHelper.defaultDir)
+ createDirectory(DownloadHelper.defaultDir+".Images/")
+ createDirectory(DownloadHelper.defaultDir+"Tracks/")
+ createDirectory(DownloadHelper.defaultDir+"Albums/")
+ createDirectory(DownloadHelper.defaultDir+"Playlists/")
+ }
+
+ private fun checkIfLatestVersion() {
+ val appUpdater = AppUpdater(this)
+ .showAppUpdated(false)//true:Show App is Update Dialog
+ .setUpdateFrom(UpdateFrom.XML)
+ .setUpdateXML("https://raw.githubusercontent.com/Shabinder/SpotiFlyer/master/app/src/main/res/xml/app_update.xml")
+ .setCancelable(false)
+ .setButtonUpdateClickListener { _, _ ->
+ val uri: Uri =
+ Uri.parse("http://github.com/Shabinder/SpotiFlyer/releases")
+ val intent = Intent(Intent.ACTION_VIEW, uri)
+ startActivity(intent)
+ }
+ .setButtonDismissClickListener { dialog, _ ->
+ dialog.dismiss()
+ }
+ appUpdater.start()
+ }
+
+
/*
private fun authenticateSpotify() {
val builder = AuthenticationRequest.Builder(clientId,AuthenticationResponse.Type.TOKEN,redirectUri)
diff --git a/app/src/main/java/com/shabinder/spotiflyer/SharedViewModel.kt b/app/src/main/java/com/shabinder/spotiflyer/SharedViewModel.kt
index 350f72ca..86a3d69d 100644
--- a/app/src/main/java/com/shabinder/spotiflyer/SharedViewModel.kt
+++ b/app/src/main/java/com/shabinder/spotiflyer/SharedViewModel.kt
@@ -17,9 +17,9 @@
package com.shabinder.spotiflyer
-import android.app.DownloadManager
import android.content.Context
import android.content.res.Resources
+import android.os.Environment
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.github.kiulian.downloader.YoutubeDownloader
@@ -32,15 +32,16 @@ import com.shreyaspatil.EasyUpiPayment.EasyUpiPayment
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
+import java.io.File
class SharedViewModel : ViewModel() {
var intentString = ""
var accessToken = MutableLiveData().apply { value = "" }
var spotifyService : SpotifyService? = null
var ytDownloader : YoutubeDownloader? = null
- var downloadManager : DownloadManager? = null
var isConnected = MutableLiveData().apply { value = false }
var easyUpiPayment: EasyUpiPayment? = null
+ val defaultDir = Environment.DIRECTORY_MUSIC + File.separator + "SpotiFlyer" + File.separator + ".Images" + File.separator
private var viewModelJob = Job()
@@ -64,13 +65,12 @@ class SharedViewModel : ViewModel() {
}
fun showAlertDialog(resources:Resources,context: Context){
- val dialog = MaterialAlertDialogBuilder(context,R.style.AlertDialogTheme)
+ 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/spotiflyer/downloadHelper/DownloadHelper.kt b/app/src/main/java/com/shabinder/spotiflyer/downloadHelper/DownloadHelper.kt
index 01e8fa0e..762e8fbf 100644
--- a/app/src/main/java/com/shabinder/spotiflyer/downloadHelper/DownloadHelper.kt
+++ b/app/src/main/java/com/shabinder/spotiflyer/downloadHelper/DownloadHelper.kt
@@ -17,22 +17,28 @@
package com.shabinder.spotiflyer.downloadHelper
-import android.app.DownloadManager
-import android.app.DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED
-import android.net.Uri
+import android.content.Context
+import android.content.Intent
import android.os.Environment
import android.util.Log
+import androidx.core.content.ContextCompat
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.spotiflyer.fragments.MainFragment
+import com.shabinder.spotiflyer.models.DownloadObject
import com.shabinder.spotiflyer.models.Track
import com.shabinder.spotiflyer.utils.YoutubeInterface
+import com.shabinder.spotiflyer.worker.ForegroundService
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
-interface DownloadHelper {
+object DownloadHelper {
+
+ var context : Context? = null
+ val defaultDir = Environment.DIRECTORY_MUSIC + File.separator + "SpotiFlyer" + File.separator
+ private var downloadList = arrayListOf()
/**
* Function To Download All Tracks Available in a List
@@ -40,111 +46,106 @@ interface DownloadHelper {
suspend fun downloadAllTracks(
type:String,
subFolder: String?,
- trackList: List