fixed getValue null bug and gradle cleanups
This commit is contained in:
parent
8225b6a9bd
commit
0b75b4c542
|
@ -39,6 +39,7 @@ contributers.py
|
|||
# View hierarchy captures
|
||||
captures
|
||||
# other
|
||||
.directory
|
||||
*.odg#
|
||||
proguard
|
||||
libs
|
||||
|
|
227
app/build.gradle
227
app/build.gradle
|
@ -2,14 +2,13 @@ plugins {
|
|||
id('com.android.application')
|
||||
id 'kotlin-android'
|
||||
id 'kotlin-kapt'
|
||||
id 'com.google.devtools.ksp'
|
||||
id('com.github.triplet.play') version '3.8.3' apply false
|
||||
}
|
||||
apply from: "../common.gradle"
|
||||
apply from: "../playFlavor.gradle"
|
||||
|
||||
android {
|
||||
namespace "ac.mdiq.podcini"
|
||||
lint {
|
||||
lintOptions {
|
||||
disable 'ObsoleteLintCustomCheck', 'CheckResult', 'UnusedAttribute', 'BatteryLife', 'InflateParams',
|
||||
'RestrictedApi', 'TrustAllX509TrustManager', 'ExportedReceiver', 'AllowBackup', 'VectorDrawableCompat',
|
||||
'StaticFieldLeak', 'UseCompoundDrawables', 'NestedWeights', 'Overdraw', 'UselessParent', 'TextFields',
|
||||
|
@ -22,11 +21,25 @@ android {
|
|||
buildConfig true
|
||||
}
|
||||
defaultConfig {
|
||||
// Version code schema:
|
||||
minSdk 21
|
||||
compileSdk 34
|
||||
targetSdk 34
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '17'
|
||||
}
|
||||
|
||||
vectorDrawables.useSupportLibrary false
|
||||
vectorDrawables.generatedDensities = []
|
||||
|
||||
testApplicationId "ac.mdiq.podcini.tests"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
// Version code schema (not used):
|
||||
// "1.2.3-beta4" -> 1020304
|
||||
// "1.2.3" -> 1020395
|
||||
versionCode 3020106
|
||||
versionName "4.2.3"
|
||||
versionCode 3020107
|
||||
versionName "4.2.4"
|
||||
|
||||
def commit = ""
|
||||
try {
|
||||
|
@ -65,33 +78,129 @@ android {
|
|||
keyPassword project.getProperties().getOrDefault("releaseKeyPassword", "password")
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
resValue "string", "app_name", "Podcini Debug"
|
||||
resValue "string", "provider_authority", "ac.mdiq.podcini.debug.provider"
|
||||
}
|
||||
release {
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard.cfg"
|
||||
resValue "string", "app_name", "Podcini"
|
||||
resValue "string", "provider_authority", "ac.mdiq.podcini.provider"
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
signingConfig signingConfigs.releaseConfig
|
||||
}
|
||||
}
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.all { output ->
|
||||
|
||||
flavorDimensions += ["market"]
|
||||
productFlavors {
|
||||
free {
|
||||
dimension "market"
|
||||
}
|
||||
play {
|
||||
dimension "market"
|
||||
}
|
||||
}
|
||||
|
||||
applicationVariants.configureEach { variant ->
|
||||
variant.outputs.configureEach { output ->
|
||||
def applicationName = "Podcini"
|
||||
outputFileName = "${applicationName}_${variant.buildType.name}_${defaultConfig.versionName}.apk"
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
resources {
|
||||
excludes += ["META-INF/LICENSE.txt",
|
||||
"META-INF/NOTICE.txt",
|
||||
"META-INF/CHANGES",
|
||||
"META-INF/README.md"]
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
testOptions {
|
||||
animationsDisabled = true
|
||||
unitTests {
|
||||
includeAndroidResources = true
|
||||
}
|
||||
}
|
||||
|
||||
lint {
|
||||
disable "GradleDependency"
|
||||
checkDependencies true
|
||||
warningsAsErrors true
|
||||
abortOnError true
|
||||
checkGeneratedSources = true
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
|
||||
androidResources {
|
||||
additionalParameters "--no-version-vectors"
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
testLogging {
|
||||
exceptionFormat "full"
|
||||
events "skipped", "passed", "failed"
|
||||
showStandardStreams true
|
||||
displayGranularity 2
|
||||
}
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
tasks.withType(JavaCompile).tap {
|
||||
configureEach {
|
||||
options.compilerArgs << "-Xlint"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.github.spotbugs'
|
||||
|
||||
spotbugs {
|
||||
effort = 'max'
|
||||
reportLevel = 'medium'
|
||||
excludeFilter = rootProject.file('config/spotbugs/exclude.xml')
|
||||
ignoreFailures = true // Handled by printing task
|
||||
}
|
||||
|
||||
gradle.taskGraph.beforeTask { task ->
|
||||
if (task.name.toLowerCase().contains('spotbugs')) {
|
||||
task.doLast {
|
||||
def reportFile = task.project.file("build/reports/spotbugs/playDebug.xml")
|
||||
if (!reportFile.exists()) return
|
||||
def slurped = new groovy.xml.XmlSlurper().parse(reportFile)
|
||||
|
||||
def foundErrors = false
|
||||
slurped['BugInstance'].each { bug ->
|
||||
logger.error "[SpotBugs] ${bug['LongMessage']} [${bug.@'type'}]"
|
||||
bug['SourceLine'].each { line ->
|
||||
logger.error "[SpotBugs] ${line['Message']}"
|
||||
foundErrors = true
|
||||
}
|
||||
}
|
||||
if (foundErrors) {
|
||||
throw new TaskExecutionException(task,
|
||||
new Exception("SpotBugs violations were found. See output above for details."))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "androidx.core:core-ktx:$coreVersion"
|
||||
implementation "androidx.core:core-ktx:1.12.0"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
|
||||
constraints {
|
||||
|
@ -103,83 +212,87 @@ dependencies {
|
|||
}
|
||||
}
|
||||
|
||||
kapt "androidx.annotation:annotation:$annotationVersion"
|
||||
ksp "androidx.annotation:annotation:1.7.1"
|
||||
|
||||
implementation "androidx.appcompat:appcompat:$appcompatVersion"
|
||||
implementation "androidx.appcompat:appcompat:1.6.1"
|
||||
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
|
||||
implementation "androidx.fragment:fragment-ktx:$fragmentVersion"
|
||||
implementation "androidx.fragment:fragment-ktx:1.6.2"
|
||||
implementation 'androidx.gridlayout:gridlayout:1.0.0'
|
||||
implementation "androidx.media:media:$mediaVersion"
|
||||
implementation "androidx.media3:media3-exoplayer:$media3Version"
|
||||
implementation "androidx.media3:media3-ui:$media3Version"
|
||||
implementation "androidx.media3:media3-datasource-okhttp:$media3Version"
|
||||
implementation "androidx.media3:media3-common:$media3Version"
|
||||
implementation "androidx.palette:palette-ktx:$paletteVersion"
|
||||
implementation "androidx.preference:preference-ktx:$preferenceVersion"
|
||||
implementation "androidx.recyclerview:recyclerview:$recyclerViewVersion"
|
||||
implementation "androidx.viewpager2:viewpager2:$viewPager2Version"
|
||||
implementation "androidx.work:work-runtime:$workManagerVersion"
|
||||
implementation "androidx.media:media:1.7.0"
|
||||
implementation "androidx.media3:media3-exoplayer:1.2.1"
|
||||
implementation "androidx.media3:media3-ui:1.2.1"
|
||||
implementation "androidx.media3:media3-datasource-okhttp:1.2.1"
|
||||
implementation "androidx.media3:media3-common:1.2.1"
|
||||
implementation "androidx.palette:palette-ktx:1.0.0"
|
||||
implementation "androidx.preference:preference-ktx:1.2.1"
|
||||
implementation "androidx.recyclerview:recyclerview:1.3.2"
|
||||
implementation "androidx.viewpager2:viewpager2:1.1.0-beta02"
|
||||
implementation "androidx.work:work-runtime:2.9.0"
|
||||
implementation "androidx.core:core-splashscreen:1.0.1"
|
||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||
|
||||
implementation "com.google.android.material:material:$googleMaterialVersion"
|
||||
implementation "com.google.android.material:material:1.11.0"
|
||||
|
||||
implementation "org.apache.commons:commons-lang3:$commonslangVersion"
|
||||
implementation "commons-io:commons-io:$commonsioVersion"
|
||||
implementation "org.jsoup:jsoup:$jsoupVersion"
|
||||
implementation "org.apache.commons:commons-lang3:3.14.0"
|
||||
implementation "commons-io:commons-io:2.15.1"
|
||||
implementation "org.jsoup:jsoup:1.17.2"
|
||||
|
||||
implementation "com.github.bumptech.glide:glide:$glideVersion"
|
||||
implementation "com.github.bumptech.glide:okhttp3-integration:$glideVersion@aar"
|
||||
kapt "com.github.bumptech.glide:compiler:$glideVersion"
|
||||
implementation "com.github.bumptech.glide:glide:4.16.0"
|
||||
implementation "com.github.bumptech.glide:okhttp3-integration:4.16.0@aar"
|
||||
ksp "com.github.bumptech.glide:ksp:4.16.0"
|
||||
|
||||
implementation "com.squareup.okhttp3:okhttp:$okhttpVersion"
|
||||
implementation "com.squareup.okhttp3:okhttp-urlconnection:$okhttpVersion"
|
||||
implementation "com.squareup.okio:okio:$okioVersion"
|
||||
implementation "org.greenrobot:eventbus:$eventbusVersion"
|
||||
kapt "org.greenrobot:eventbus-annotation-processor:$eventbusVersion"
|
||||
implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
|
||||
implementation "io.reactivex.rxjava2:rxjava:$rxJavaVersion"
|
||||
implementation "com.squareup.okhttp3:okhttp:4.12.0"
|
||||
implementation "com.squareup.okhttp3:okhttp-urlconnection:4.12.0"
|
||||
|
||||
implementation "com.joanzapata.iconify:android-iconify-fontawesome:$iconifyVersion"
|
||||
implementation "com.joanzapata.iconify:android-iconify-material:$iconifyVersion"
|
||||
implementation 'com.leinardi.android:speed-dial:3.2.0'
|
||||
implementation "com.squareup.okio:okio:3.7.0"
|
||||
|
||||
implementation "org.greenrobot:eventbus:3.3.1"
|
||||
kapt "org.greenrobot:eventbus-annotation-processor:3.3.1"
|
||||
|
||||
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
|
||||
implementation "io.reactivex.rxjava2:rxjava:2.2.21"
|
||||
|
||||
implementation "com.joanzapata.iconify:android-iconify-fontawesome:2.2.2"
|
||||
implementation "com.joanzapata.iconify:android-iconify-material:2.2.2"
|
||||
implementation 'com.leinardi.android:speed-dial:3.3.0'
|
||||
implementation 'com.github.ByteHamster:SearchPreference:v2.5.0'
|
||||
implementation 'com.github.skydoves:balloon:1.5.3'
|
||||
implementation 'com.github.skydoves:balloon:1.6.4'
|
||||
implementation 'com.github.xabaras:RecyclerViewSwipeDecorator:1.3'
|
||||
implementation "com.annimon:stream:$annimonStreamVersion"
|
||||
implementation "com.annimon:stream:1.2.2"
|
||||
|
||||
// Non-free dependencies:
|
||||
playImplementation 'com.google.android.play:core-ktx:1.8.0'
|
||||
compileOnly "com.google.android.wearable:wearable:$wearableSupportVersion"
|
||||
playImplementation 'com.google.android.play:core-ktx:1.8.1'
|
||||
compileOnly "com.google.android.wearable:wearable:2.9.0"
|
||||
|
||||
// this one can not be updated?
|
||||
androidTestImplementation 'com.nanohttpd:nanohttpd:2.1.1'
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:$espressoVersion"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-contrib:$espressoVersion"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-intents:$espressoVersion"
|
||||
androidTestImplementation "androidx.test:runner:$runnerVersion"
|
||||
androidTestImplementation "androidx.test:rules:$rulesVersion"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-core:3.5.1"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-contrib:3.5.1"
|
||||
androidTestImplementation "androidx.test.espresso:espresso-intents:3.5.1"
|
||||
androidTestImplementation "androidx.test:runner:1.5.2"
|
||||
androidTestImplementation "androidx.test:rules:1.5.0"
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation "org.awaitility:awaitility:$awaitilityVersion"
|
||||
androidTestImplementation "org.awaitility:awaitility:4.2.0"
|
||||
|
||||
implementation "com.annimon:stream:$annimonStreamVersion"
|
||||
implementation "com.annimon:stream:1.2.2"
|
||||
implementation 'com.github.mfietz:fyydlin:v0.5.0'
|
||||
|
||||
// Non-free dependencies:
|
||||
|
||||
testImplementation "androidx.test:core:$testCoreVersion"
|
||||
testImplementation "org.awaitility:awaitility:$awaitilityVersion"
|
||||
testImplementation "junit:junit:$junitVersion"
|
||||
testImplementation "androidx.test:core:1.5.0"
|
||||
testImplementation "org.awaitility:awaitility:4.2.0"
|
||||
testImplementation "junit:junit:4.13.2"
|
||||
testImplementation 'org.mockito:mockito-inline:5.2.0'
|
||||
testImplementation "org.robolectric:robolectric:$robolectricVersion"
|
||||
testImplementation "org.robolectric:robolectric:4.11.1"
|
||||
testImplementation 'javax.inject:javax.inject:1'
|
||||
|
||||
|
||||
playImplementation 'com.google.android.gms:play-services-base:17.5.0'
|
||||
playImplementation 'com.google.android.gms:play-services-base:18.3.0'
|
||||
freeImplementation 'org.conscrypt:conscrypt-android:2.5.2'
|
||||
|
||||
playApi 'androidx.mediarouter:mediarouter:1.6.0'
|
||||
playApi "com.google.android.support:wearable:$wearableSupportVersion"
|
||||
playApi 'com.google.android.gms:play-services-cast-framework:21.2.0'
|
||||
playApi "com.google.android.support:wearable:2.9.0"
|
||||
playApi 'com.google.android.gms:play-services-cast-framework:21.4.0'
|
||||
}
|
||||
|
||||
kapt {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package de.test.podcini.util.service.download
|
||||
|
||||
import ac.mdiq.podcini.BuildConfig
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
import ac.mdiq.podcini.BuildConfig
|
||||
import fi.iki.elonen.NanoHTTPD
|
||||
import fi.iki.elonen.NanoHTTPD.Response.IStatus
|
||||
import org.apache.commons.io.IOUtils
|
||||
|
|
|
@ -19,17 +19,17 @@ class Atom : Namespace() {
|
|||
state.items.add(state.currentItem!!)
|
||||
state.currentItem!!.feed = state.feed
|
||||
} else if (localName.matches(isText.toRegex())) {
|
||||
val type = attributes.getValue(TEXT_TYPE)
|
||||
val type: String? = attributes.getValue(TEXT_TYPE)
|
||||
return AtomText(localName, this, type)
|
||||
} else if (LINK == localName) {
|
||||
val href = attributes.getValue(LINK_HREF)
|
||||
val rel = attributes.getValue(LINK_REL)
|
||||
val href: String? = attributes.getValue(LINK_HREF)
|
||||
val rel: String? = attributes.getValue(LINK_REL)
|
||||
val parent = state.tagstack.peek()
|
||||
if (parent.name.matches(isFeedItem.toRegex())) {
|
||||
if (rel == null || LINK_REL_ALTERNATE == rel) {
|
||||
state.currentItem!!.link = href
|
||||
} else if (LINK_REL_ENCLOSURE == rel) {
|
||||
val strSize = attributes.getValue(LINK_LENGTH)
|
||||
val strSize: String? = attributes.getValue(LINK_LENGTH)
|
||||
var size: Long = 0
|
||||
try {
|
||||
if (strSize != null) {
|
||||
|
@ -38,7 +38,7 @@ class Atom : Namespace() {
|
|||
} catch (e: NumberFormatException) {
|
||||
Log.d(TAG, "Length attribute could not be parsed.")
|
||||
}
|
||||
val mimeType = getMimeType(attributes.getValue(LINK_TYPE), href)
|
||||
val mimeType: String? = getMimeType(attributes.getValue(LINK_TYPE), href)
|
||||
|
||||
val currItem = state.currentItem
|
||||
if (isMediaFile(mimeType) && currItem != null && !currItem.hasMedia()) {
|
||||
|
@ -49,7 +49,7 @@ class Atom : Namespace() {
|
|||
}
|
||||
} else if (parent.name.matches(isFeed.toRegex())) {
|
||||
if (rel == null || LINK_REL_ALTERNATE == rel) {
|
||||
val type = attributes.getValue(LINK_TYPE)
|
||||
val type: String? = attributes.getValue(LINK_TYPE)
|
||||
/*
|
||||
* Use as link if a) no type-attribute is given and
|
||||
* feed-object has no link yet b) type of link is
|
||||
|
@ -60,20 +60,20 @@ class Atom : Namespace() {
|
|||
state.feed.link = href
|
||||
} else if (LINK_TYPE_ATOM == type || LINK_TYPE_RSS == type) {
|
||||
// treat as podlove alternate feed
|
||||
var title = attributes.getValue(LINK_TITLE)
|
||||
if (title.isEmpty()) {
|
||||
title = href
|
||||
var title: String? = attributes.getValue(LINK_TITLE)
|
||||
if (title.isNullOrEmpty()) {
|
||||
title = href?:""
|
||||
}
|
||||
state.addAlternateFeedUrl(title!!, href)
|
||||
if (!href.isNullOrEmpty()) state.addAlternateFeedUrl(title, href)
|
||||
}
|
||||
} else if (LINK_REL_ARCHIVES == rel) {
|
||||
val type = attributes.getValue(LINK_TYPE)
|
||||
val type: String? = attributes.getValue(LINK_TYPE)
|
||||
if (LINK_TYPE_ATOM == type || LINK_TYPE_RSS == type) {
|
||||
var title = attributes.getValue(LINK_TITLE)
|
||||
if (title.isEmpty()) {
|
||||
title = href
|
||||
var title: String? = attributes.getValue(LINK_TITLE)
|
||||
if (title.isNullOrEmpty()) {
|
||||
title = href?:""
|
||||
}
|
||||
state.addAlternateFeedUrl(title!!, href)
|
||||
if (!href.isNullOrEmpty()) state.addAlternateFeedUrl(title, href)
|
||||
} else if (LINK_TYPE_HTML == type || LINK_TYPE_XHTML == type) {
|
||||
//A Link such as to a directory such as iTunes
|
||||
}
|
||||
|
@ -205,7 +205,7 @@ class Atom : Namespace() {
|
|||
*/
|
||||
private const val isText = ("$TITLE|$CONTENT|$SUBTITLE|$SUMMARY")
|
||||
|
||||
private const val isFeed = FEED + "|" + ac.mdiq.podcini.feed.parser.namespace.Rss20.CHANNEL
|
||||
private const val isFeedItem = ENTRY + "|" + ac.mdiq.podcini.feed.parser.namespace.Rss20.ITEM
|
||||
private const val isFeed = FEED + "|" + Rss20.CHANNEL
|
||||
private const val isFeedItem = ENTRY + "|" + Rss20.ITEM
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@ class Itunes : Namespace() {
|
|||
override fun handleElementStart(localName: String, state: ac.mdiq.podcini.feed.parser.HandlerState,
|
||||
attributes: Attributes): SyndElement {
|
||||
if (IMAGE == localName) {
|
||||
val url = attributes.getValue(IMAGE_HREF)
|
||||
val url: String? = attributes.getValue(IMAGE_HREF)
|
||||
|
||||
if (state.currentItem != null) {
|
||||
state.currentItem!!.imageUrl = url
|
||||
} else {
|
||||
// this is the feed image
|
||||
// prefer to all other images
|
||||
if (url.isNotEmpty()) {
|
||||
if (!url.isNullOrEmpty()) {
|
||||
state.feed.imageUrl = url
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ import java.util.concurrent.TimeUnit
|
|||
class Media : Namespace() {
|
||||
override fun handleElementStart(localName: String, state: HandlerState, attributes: Attributes): SyndElement {
|
||||
if (CONTENT == localName) {
|
||||
val url = attributes.getValue(DOWNLOAD_URL)
|
||||
val defaultStr = attributes.getValue(DEFAULT)
|
||||
val medium = attributes.getValue(MEDIUM)
|
||||
val url: String? = attributes.getValue(DOWNLOAD_URL)
|
||||
val defaultStr: String? = attributes.getValue(DEFAULT)
|
||||
val medium: String? = attributes.getValue(MEDIUM)
|
||||
var validTypeMedia = false
|
||||
var validTypeImage = false
|
||||
val isDefault = "true" == defaultStr
|
||||
|
@ -44,7 +44,7 @@ class Media : Namespace() {
|
|||
|
||||
if (state.currentItem != null && (state.currentItem!!.media == null || isDefault) && url != null && validTypeMedia) {
|
||||
var size: Long = 0
|
||||
val sizeStr = attributes.getValue(SIZE)
|
||||
val sizeStr: String? = attributes.getValue(SIZE)
|
||||
if (!sizeStr.isNullOrEmpty()) {
|
||||
try {
|
||||
size = sizeStr.toLong()
|
||||
|
@ -53,7 +53,7 @@ class Media : Namespace() {
|
|||
}
|
||||
}
|
||||
var durationMs = 0
|
||||
val durationStr = attributes.getValue(DURATION)
|
||||
val durationStr: String? = attributes.getValue(DURATION)
|
||||
if (!durationStr.isNullOrEmpty()) {
|
||||
try {
|
||||
val duration = durationStr.toLong()
|
||||
|
@ -71,7 +71,7 @@ class Media : Namespace() {
|
|||
state.currentItem!!.imageUrl = url
|
||||
}
|
||||
} else if (IMAGE == localName) {
|
||||
val url = attributes.getValue(IMAGE_URL)
|
||||
val url: String? = attributes.getValue(IMAGE_URL)
|
||||
if (url != null) {
|
||||
if (state.currentItem != null) {
|
||||
state.currentItem!!.imageUrl = url
|
||||
|
@ -82,7 +82,7 @@ class Media : Namespace() {
|
|||
}
|
||||
}
|
||||
} else if (DESCRIPTION == localName) {
|
||||
val type = attributes.getValue(DESCRIPTION_TYPE)
|
||||
val type: String? = attributes.getValue(DESCRIPTION_TYPE)
|
||||
return AtomText(localName, this, type)
|
||||
}
|
||||
return SyndElement(localName, this)
|
||||
|
|
|
@ -9,13 +9,13 @@ class PodcastIndex : Namespace() {
|
|||
override fun handleElementStart(localName: String, state: HandlerState,
|
||||
attributes: Attributes): SyndElement {
|
||||
if (FUNDING == localName) {
|
||||
val href = attributes.getValue(URL)
|
||||
val href: String? = attributes.getValue(URL)
|
||||
val funding = FeedFunding(href, "")
|
||||
state.currentFunding = funding
|
||||
state.feed.addPayment(state.currentFunding!!)
|
||||
} else if (CHAPTERS == localName) {
|
||||
val href = attributes.getValue(URL)
|
||||
if (href.isNotEmpty()) {
|
||||
val href: String? = attributes.getValue(URL)
|
||||
if (!href.isNullOrEmpty()) {
|
||||
state.currentItem!!.podcastIndexChapterUrl = href
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,14 +22,14 @@ class Rss20 : Namespace() {
|
|||
state.items.add(state.currentItem!!)
|
||||
state.currentItem!!.feed = state.feed
|
||||
} else if (ENCLOSURE == localName && ITEM == state.tagstack.peek()?.name) {
|
||||
val url = attributes.getValue(ENC_URL)
|
||||
val mimeType = getMimeType(attributes.getValue(ENC_TYPE), url)
|
||||
val url: String? = attributes.getValue(ENC_URL)
|
||||
val mimeType: String? = getMimeType(attributes.getValue(ENC_TYPE), url)
|
||||
|
||||
val validUrl = url.isNotEmpty()
|
||||
val validUrl = !url.isNullOrBlank()
|
||||
if (state.currentItem?.media == null && isMediaFile(mimeType) && validUrl) {
|
||||
var size: Long = 0
|
||||
try {
|
||||
size = attributes.getValue(ENC_LEN).toLong()
|
||||
size = attributes.getValue(ENC_LEN)?.toLong() ?: 0
|
||||
if (size < 16384) {
|
||||
// less than 16kb is suspicious, check manually
|
||||
size = 0
|
||||
|
|
|
@ -12,13 +12,13 @@ class SimpleChapters : Namespace() {
|
|||
if (currentItem != null) {
|
||||
if (localName == CHAPTERS) {
|
||||
currentItem.chapters = mutableListOf()
|
||||
} else if (localName == CHAPTER && attributes.getValue(START).isNotEmpty()) {
|
||||
} else if (localName == CHAPTER && !attributes.getValue(START).isNullOrEmpty()) {
|
||||
// if the chapter's START is empty, we don't need to do anything
|
||||
try {
|
||||
val start= parseTimeString(attributes.getValue(START))
|
||||
val title = attributes.getValue(TITLE)
|
||||
val link = attributes.getValue(HREF)
|
||||
val imageUrl = attributes.getValue(IMAGE)
|
||||
val title: String? = attributes.getValue(TITLE)
|
||||
val link: String? = attributes.getValue(HREF)
|
||||
val imageUrl: String? = attributes.getValue(IMAGE)
|
||||
val chapter = Chapter(start, title, link, imageUrl)
|
||||
currentItem.chapters?.add(chapter)
|
||||
} catch (e: NumberFormatException) {
|
||||
|
|
46
build.gradle
46
build.gradle
|
@ -13,6 +13,10 @@ buildscript {
|
|||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.google.devtools.ksp' version '1.9.22-1.0.17' apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
|
@ -21,48 +25,6 @@ allprojects {
|
|||
}
|
||||
}
|
||||
|
||||
project.ext {
|
||||
// AndroidX
|
||||
annotationVersion = "1.7.1"
|
||||
appcompatVersion = "1.6.1"
|
||||
coreVersion = "1.12.0"
|
||||
fragmentVersion = "1.6.2"
|
||||
mediaVersion = "1.7.0"
|
||||
paletteVersion = "1.0.0"
|
||||
preferenceVersion = "1.2.1"
|
||||
recyclerViewVersion = "1.3.2"
|
||||
viewPager2Version = "1.1.0-beta02"
|
||||
workManagerVersion = "2.9.0"
|
||||
googleMaterialVersion = "1.11.0"
|
||||
|
||||
// Third-party
|
||||
commonslangVersion = "3.14.0"
|
||||
commonsioVersion = "2.15.1"
|
||||
jsoupVersion = "1.17.2"
|
||||
glideVersion = "4.16.0"
|
||||
okhttpVersion = "4.12.0"
|
||||
okioVersion = "3.7.0"
|
||||
eventbusVersion = "3.3.1"
|
||||
rxAndroidVersion = "2.1.1"
|
||||
rxJavaVersion = "2.2.21"
|
||||
iconifyVersion = "2.2.2"
|
||||
annimonStreamVersion = "1.2.2"
|
||||
media3Version = "1.2.1"
|
||||
|
||||
// Google Play build
|
||||
wearableSupportVersion = "2.6.0"
|
||||
|
||||
//Tests
|
||||
awaitilityVersion = "4.2.0"
|
||||
junitVersion = "4.13.2"
|
||||
junit5Version = "5.10.1"
|
||||
robolectricVersion = "4.11.1"
|
||||
espressoVersion = "3.5.0"
|
||||
runnerVersion = "1.5.2"
|
||||
rulesVersion = "1.5.0"
|
||||
testCoreVersion = "1.5.0"
|
||||
}
|
||||
|
||||
apply plugin: "checkstyle"
|
||||
checkstyle {
|
||||
toolVersion '10.3.1'
|
||||
|
|
|
@ -63,3 +63,9 @@
|
|||
* added items count in FeedItemList header
|
||||
* fixed bug in FeedItemList when filtered list has no items
|
||||
* buildConfig is set in build.gradle instead of gradle.properties
|
||||
|
||||
## 4.2.4
|
||||
|
||||
* fixed the "getValue() can not be null" bug
|
||||
* enabled ksp for Kotlin builds
|
||||
* cleaned up build.gradle files
|
109
common.gradle
109
common.gradle
|
@ -1,109 +0,0 @@
|
|||
android {
|
||||
defaultConfig {
|
||||
minSdk 21
|
||||
compileSdk 34
|
||||
targetSdk 34
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '17'
|
||||
}
|
||||
|
||||
vectorDrawables.useSupportLibrary false
|
||||
vectorDrawables.generatedDensities = []
|
||||
|
||||
testApplicationId "ac.mdiq.podcini.tests"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard.cfg"
|
||||
resValue "string", "app_name", "Podcini"
|
||||
}
|
||||
debug {
|
||||
resValue "string", "app_name", "Podcini Debug"
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
resources {
|
||||
excludes += ["META-INF/LICENSE.txt",
|
||||
"META-INF/NOTICE.txt",
|
||||
"META-INF/CHANGES",
|
||||
"META-INF/README.md"]
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
testOptions {
|
||||
animationsDisabled = true
|
||||
unitTests {
|
||||
includeAndroidResources = true
|
||||
}
|
||||
}
|
||||
|
||||
lint {
|
||||
disable "GradleDependency"
|
||||
checkDependencies true
|
||||
warningsAsErrors true
|
||||
abortOnError true
|
||||
checkGeneratedSources = true
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType(Test).configureEach {
|
||||
testLogging {
|
||||
exceptionFormat "full"
|
||||
events "skipped", "passed", "failed"
|
||||
showStandardStreams true
|
||||
displayGranularity 2
|
||||
}
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
tasks.withType(JavaCompile).tap {
|
||||
configureEach {
|
||||
options.compilerArgs << "-Xlint"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.github.spotbugs'
|
||||
|
||||
spotbugs {
|
||||
effort = 'max'
|
||||
reportLevel = 'medium'
|
||||
excludeFilter = rootProject.file('config/spotbugs/exclude.xml')
|
||||
ignoreFailures = true // Handled by printing task
|
||||
}
|
||||
|
||||
gradle.taskGraph.beforeTask { task ->
|
||||
if (task.name.toLowerCase().contains('spotbugs')) {
|
||||
task.doLast {
|
||||
def reportFile = task.project.file("build/reports/spotbugs/playDebug.xml")
|
||||
if (!reportFile.exists()) return
|
||||
def slurped = new groovy.xml.XmlSlurper().parse(reportFile)
|
||||
|
||||
def foundErrors = false
|
||||
slurped['BugInstance'].each { bug ->
|
||||
logger.error "[SpotBugs] ${bug['LongMessage']} [${bug.@'type'}]"
|
||||
bug['SourceLine'].each { line ->
|
||||
logger.error "[SpotBugs] ${line['Message']}"
|
||||
foundErrors = true
|
||||
}
|
||||
}
|
||||
if (foundErrors) {
|
||||
throw new TaskExecutionException(task,
|
||||
new Exception("SpotBugs violations were found. See output above for details."))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
Version 4.2.4 brings several changes:
|
||||
|
||||
* fixed the "getValue() can not be null" bug
|
||||
* enabled ksp for Kotlin builds
|
||||
* cleaned up build.gradle files
|
|
@ -1,11 +0,0 @@
|
|||
android {
|
||||
flavorDimensions += ["market"]
|
||||
productFlavors {
|
||||
free {
|
||||
dimension "market"
|
||||
}
|
||||
play {
|
||||
dimension "market"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue