Эх сурвалжийг харах

Drop support for Android 4.x (#2440)

* Bump minSdkVersion

* Remove Android 4.x specific logic

* Consolidate res assets

* Add note about minimum Android version to README

* Restore incorrectly removed method, remove unneeded Lollipop TargetApi annotations
arkon 5 жил өмнө
parent
commit
0d5099f230
33 өөрчлөгдсөн 200 нэмэгдсэн , 530 устгасан
  1. 1 1
      README.md
  2. 1 1
      app/build.gradle
  3. 3 27
      app/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt
  4. 1 5
      app/src/main/java/eu/kanade/tachiyomi/network/CloudflareInterceptor.kt
  5. 3 95
      app/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt
  6. 1 6
      app/src/main/java/eu/kanade/tachiyomi/ui/base/holder/SlicedHolder.kt
  7. 3 13
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt
  8. 2 5
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonRecyclerView.kt
  9. 18 46
      app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt
  10. 7 21
      app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt
  11. 1 13
      app/src/main/java/eu/kanade/tachiyomi/util/DiskUtil.kt
  12. 0 1
      app/src/main/java/eu/kanade/tachiyomi/util/WebViewClientCompat.kt
  13. 11 17
      app/src/main/java/eu/kanade/tachiyomi/widget/ElevationAppBarLayout.kt
  14. 25 36
      app/src/main/java/eu/kanade/tachiyomi/widget/RevealAnimationView.kt
  15. 0 21
      app/src/main/res/drawable-v21/library_item_selector_amoled.xml
  16. 0 21
      app/src/main/res/drawable-v21/library_item_selector_dark.xml
  17. 0 21
      app/src/main/res/drawable-v21/library_item_selector_light.xml
  18. 0 19
      app/src/main/res/drawable-v21/list_item_selector_amoled.xml
  19. 0 19
      app/src/main/res/drawable-v21/list_item_selector_dark.xml
  20. 0 19
      app/src/main/res/drawable-v21/list_item_selector_light.xml
  21. 16 7
      app/src/main/res/drawable/library_item_selector_amoled.xml
  22. 16 7
      app/src/main/res/drawable/library_item_selector_dark.xml
  23. 16 7
      app/src/main/res/drawable/library_item_selector_light.xml
  24. 16 7
      app/src/main/res/drawable/list_item_selector_amoled.xml
  25. 16 7
      app/src/main/res/drawable/list_item_selector_dark.xml
  26. 16 7
      app/src/main/res/drawable/list_item_selector_light.xml
  27. 0 5
      app/src/main/res/values-v21/dimens.xml
  28. 0 6
      app/src/main/res/values-v21/keys.xml
  29. 0 58
      app/src/main/res/values-v21/themes.xml
  30. 1 2
      app/src/main/res/values/dimens.xml
  31. 0 7
      app/src/main/res/values/keys.xml
  32. 2 2
      app/src/main/res/values/styles.xml
  33. 24 1
      app/src/main/res/values/themes.xml

+ 1 - 1
README.md

@@ -4,7 +4,7 @@
 
 
 # ![app icon](./.github/readme-images/app-icon.png)Tachiyomi
-Tachiyomi is a free and open source manga reader for Android.
+Tachiyomi is a free and open source manga reader for Android 5.0 and above.
 
 ![screenshots of app](./.github/readme-images/screens.png)
 

+ 1 - 1
app/build.gradle

@@ -35,7 +35,7 @@ android {
 
     defaultConfig {
         applicationId "eu.kanade.tachiyomi"
-        minSdkVersion 16
+        minSdkVersion 21
         targetSdkVersion 28
         testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
         versionCode 41

+ 3 - 27
app/src/main/java/eu/kanade/tachiyomi/network/AndroidCookieJar.kt

@@ -1,35 +1,20 @@
 package eu.kanade.tachiyomi.network
 
-import android.content.Context
-import android.os.Build
 import android.webkit.CookieManager
-import android.webkit.CookieSyncManager
 import okhttp3.Cookie
 import okhttp3.CookieJar
 import okhttp3.HttpUrl
 
-class AndroidCookieJar(context: Context) : CookieJar {
+class AndroidCookieJar : CookieJar {
 
     private val manager = CookieManager.getInstance()
 
-    private val syncManager by lazy { CookieSyncManager.createInstance(context) }
-
-    init {
-        // Init sync manager when using anything below L
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-            syncManager
-        }
-    }
-
     override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
         val urlString = url.toString()
 
         for (cookie in cookies) {
             manager.setCookie(urlString, cookie.toString())
         }
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-            syncManager.sync()
-        }
     }
 
     override fun loadForRequest(url: HttpUrl): List<Cookie> {
@@ -39,7 +24,7 @@ class AndroidCookieJar(context: Context) : CookieJar {
     fun get(url: HttpUrl): List<Cookie> {
         val cookies = manager.getCookie(url.toString())
 
-        return if (cookies != null && !cookies.isEmpty()) {
+        return if (cookies != null && cookies.isNotEmpty()) {
             cookies.split(";").mapNotNull { Cookie.parse(url, it) }
         } else {
             emptyList()
@@ -53,19 +38,10 @@ class AndroidCookieJar(context: Context) : CookieJar {
         cookies.split(";")
             .map { it.substringBefore("=") }
             .onEach { manager.setCookie(urlString, "$it=;Max-Age=-1") }
-
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-            syncManager.sync()
-        }
     }
 
     fun removeAll() {
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            manager.removeAllCookies {}
-        } else {
-            manager.removeAllCookie()
-            syncManager.sync()
-        }
+        manager.removeAllCookies {}
     }
 
 }

+ 1 - 5
app/src/main/java/eu/kanade/tachiyomi/network/CloudflareInterceptor.kt

@@ -28,11 +28,7 @@ class CloudflareInterceptor(private val context: Context) : Interceptor {
      * Application class.
      */
     private val initWebView by lazy {
-        if (Build.VERSION.SDK_INT >= 17) {
-            WebSettings.getDefaultUserAgent(context)
-        } else {
-            null
-        }
+        WebSettings.getDefaultUserAgent(context)
     }
 
     @Synchronized

+ 3 - 95
app/src/main/java/eu/kanade/tachiyomi/network/NetworkHelper.kt

@@ -1,17 +1,9 @@
 package eu.kanade.tachiyomi.network
 
 import android.content.Context
-import android.os.Build
-import okhttp3.*
+import okhttp3.Cache
+import okhttp3.OkHttpClient
 import java.io.File
-import java.io.IOException
-import java.net.InetAddress
-import java.net.Socket
-import java.net.UnknownHostException
-import java.security.KeyManagementException
-import java.security.KeyStore
-import java.security.NoSuchAlgorithmException
-import javax.net.ssl.*
 
 class NetworkHelper(context: Context) {
 
@@ -19,99 +11,15 @@ class NetworkHelper(context: Context) {
 
     private val cacheSize = 5L * 1024 * 1024 // 5 MiB
 
-    val cookieManager = AndroidCookieJar(context)
+    val cookieManager = AndroidCookieJar()
 
     val client = OkHttpClient.Builder()
             .cookieJar(cookieManager)
             .cache(Cache(cacheDir, cacheSize))
-            .enableTLS12()
             .build()
 
     val cloudflareClient = client.newBuilder()
             .addInterceptor(CloudflareInterceptor(context))
             .build()
 
-    private fun OkHttpClient.Builder.enableTLS12(): OkHttpClient.Builder {
-        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
-            return this
-        }
-
-        val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm())
-        trustManagerFactory.init(null as KeyStore?)
-        val trustManagers = trustManagerFactory.trustManagers
-        if (trustManagers.size == 1 && trustManagers[0] is X509TrustManager) {
-            class TLSSocketFactory @Throws(KeyManagementException::class, NoSuchAlgorithmException::class)
-            constructor() : SSLSocketFactory() {
-
-                private val internalSSLSocketFactory: SSLSocketFactory
-
-                init {
-                    val context = SSLContext.getInstance("TLS")
-                    context.init(null, null, null)
-                    internalSSLSocketFactory = context.socketFactory
-                }
-
-                override fun getDefaultCipherSuites(): Array<String> {
-                    return internalSSLSocketFactory.defaultCipherSuites
-                }
-
-                override fun getSupportedCipherSuites(): Array<String> {
-                    return internalSSLSocketFactory.supportedCipherSuites
-                }
-
-                @Throws(IOException::class)
-                override fun createSocket(): Socket? {
-                    return enableTLSOnSocket(internalSSLSocketFactory.createSocket())
-                }
-
-                @Throws(IOException::class)
-                override fun createSocket(s: Socket, host: String, port: Int, autoClose: Boolean): Socket? {
-                    return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose))
-                }
-
-                @Throws(IOException::class, UnknownHostException::class)
-                override fun createSocket(host: String, port: Int): Socket? {
-                    return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port))
-                }
-
-                @Throws(IOException::class, UnknownHostException::class)
-                override fun createSocket(host: String, port: Int, localHost: InetAddress, localPort: Int): Socket? {
-                    return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort))
-                }
-
-                @Throws(IOException::class)
-                override fun createSocket(host: InetAddress, port: Int): Socket? {
-                    return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port))
-                }
-
-                @Throws(IOException::class)
-                override fun createSocket(address: InetAddress, port: Int, localAddress: InetAddress, localPort: Int): Socket? {
-                    return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort))
-                }
-
-                private fun enableTLSOnSocket(socket: Socket?): Socket? {
-                    if (socket != null && socket is SSLSocket) {
-                        socket.enabledProtocols = socket.supportedProtocols
-                    }
-                    return socket
-                }
-            }
-
-            sslSocketFactory(TLSSocketFactory(), trustManagers[0] as X509TrustManager)
-        }
-
-        val specCompat = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
-            .tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_1, TlsVersion.TLS_1_0)
-            .cipherSuites(
-                    *ConnectionSpec.MODERN_TLS.cipherSuites.orEmpty().toTypedArray(),
-                    CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
-                    CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
-            )
-            .build()
-
-        val specs = listOf(specCompat, ConnectionSpec.CLEARTEXT)
-        connectionSpecs(specs)
-
-        return this
-    }
 }

+ 1 - 6
app/src/main/java/eu/kanade/tachiyomi/ui/base/holder/SlicedHolder.kt

@@ -1,6 +1,5 @@
 package eu.kanade.tachiyomi.ui.base.holder
 
-import android.os.Build
 import android.view.View
 import android.view.ViewGroup
 import eu.davidea.flexibleadapter.FlexibleAdapter
@@ -51,10 +50,6 @@ interface SlicedHolder {
         slice.showRightTopRect(topRect)
         slice.showLeftBottomRect(bottomRect)
         slice.showRightBottomRect(bottomRect)
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-            slice.showTopEdgeShadow(topShadow)
-            slice.showBottomEdgeShadow(bottomShadow)
-        }
         setMargins(margin, if (topShadow) margin else 0, margin, if (bottomShadow) margin else 0)
     }
 
@@ -68,4 +63,4 @@ interface SlicedHolder {
     val margin
         get() = 8.dpToPx
 
-}
+}

+ 3 - 13
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt

@@ -8,7 +8,6 @@ import android.content.pm.ActivityInfo
 import android.content.res.Configuration
 import android.graphics.Bitmap
 import android.graphics.Color
-import android.os.Build
 import android.os.Bundle
 import android.view.*
 import android.view.animation.Animation
@@ -21,9 +20,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.data.preference.getOrDefault
 import eu.kanade.tachiyomi.ui.base.activity.BaseRxActivity
-import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.AddToLibraryFirst
-import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Error
-import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.Success
+import eu.kanade.tachiyomi.ui.reader.ReaderPresenter.SetAsCoverResult.*
 import eu.kanade.tachiyomi.ui.reader.model.ReaderChapter
 import eu.kanade.tachiyomi.ui.reader.model.ReaderPage
 import eu.kanade.tachiyomi.ui.reader.model.ViewerChapters
@@ -276,10 +273,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
                 toolbarAnimation.setAnimationListener(object : SimpleAnimationListener() {
                     override fun onAnimationStart(animation: Animation) {
                         // Fix status bar being translucent the first time it's opened.
-                        if (Build.VERSION.SDK_INT >= 21) {
-                            window.addFlags(
-                                    WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
-                        }
+                        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS)
                     }
                 })
                 toolbar.startAnimation(toolbarAnimation)
@@ -637,11 +631,7 @@ class ReaderActivity : BaseRxActivity<ReaderPresenter>() {
          */
         private fun setFullscreen(enabled: Boolean) {
             systemUi = if (enabled) {
-                val level = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-                    SystemUiHelper.LEVEL_IMMERSIVE
-                } else {
-                    SystemUiHelper.LEVEL_HIDE_STATUS_BAR
-                }
+                val level = SystemUiHelper.LEVEL_IMMERSIVE
                 val flags = SystemUiHelper.FLAG_IMMERSIVE_STICKY or
                         SystemUiHelper.FLAG_LAYOUT_IN_SCREEN_OLDER_DEVICES
 

+ 2 - 5
app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/webtoon/WebtoonRecyclerView.kt

@@ -3,16 +3,14 @@ package eu.kanade.tachiyomi.ui.reader.viewer.webtoon
 import android.animation.Animator
 import android.animation.AnimatorSet
 import android.animation.ValueAnimator
-import android.annotation.TargetApi
 import android.content.Context
-import android.os.Build
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
 import android.util.AttributeSet
 import android.view.HapticFeedbackConstants
 import android.view.MotionEvent
 import android.view.ViewConfiguration
 import android.view.animation.DecelerateInterpolator
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
 import eu.kanade.tachiyomi.ui.reader.viewer.GestureDetectorWithLongTap
 
 /**
@@ -58,7 +56,6 @@ open class WebtoonRecyclerView @JvmOverloads constructor(
         firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
     }
 
-    @TargetApi(Build.VERSION_CODES.KITKAT)
     override fun onScrollStateChanged(state: Int) {
         super.onScrollStateChanged(state)
         val layoutManager = layoutManager

+ 18 - 46
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsBackupController.kt

@@ -5,10 +5,9 @@ import android.app.Activity
 import android.app.Dialog
 import android.content.*
 import android.net.Uri
-import android.os.Build
 import android.os.Bundle
-import androidx.preference.PreferenceScreen
 import android.view.View
+import androidx.preference.PreferenceScreen
 import com.afollestad.materialdialogs.MaterialDialog
 import com.hippo.unifile.UniFile
 import eu.kanade.tachiyomi.R
@@ -106,21 +105,12 @@ class SettingsBackupController : SettingsController() {
                 onClick {
                     val currentDir = preferences.backupsDirectory().getOrDefault()
                     try{
-                        val intent = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-                        // Custom dir selected, open directory selector
-                        preferences.context.getFilePicker(currentDir)
-                        } else {
-                          Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
-                        }
-
+                        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
                         startActivityForResult(intent, CODE_BACKUP_DIR)
                     } catch (e: ActivityNotFoundException){
-                        //Fall back to custom picker on error
-                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
-                            startActivityForResult(preferences.context.getFilePicker(currentDir), CODE_BACKUP_DIR)
-                        }
+                        // Fall back to custom picker on error
+                        startActivityForResult(preferences.context.getFilePicker(currentDir), CODE_BACKUP_DIR)
                     }
-
                 }
 
                 preferences.backupsDirectory().asObservable()
@@ -154,37 +144,27 @@ class SettingsBackupController : SettingsController() {
                 // Get uri of backup folder.
                 val uri = data.data
 
-                // Get UriPermission so it's possible to write files post kitkat.
-                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {
-                    val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
-                            Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+                // Get UriPermission so it's possible to write files
+                val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
+                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION
 
-                    activity.contentResolver.takePersistableUriPermission(uri, flags)
-                }
+                activity.contentResolver.takePersistableUriPermission(uri, flags)
 
-                // Set backup Uri.
+                // Set backup Uri
                 preferences.backupsDirectory().set(uri.toString())
             }
             CODE_BACKUP_CREATE -> if (data != null && resultCode == Activity.RESULT_OK) {
                 val activity = activity ?: return
-                val uri = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-                    val dir = data.data.path
-                    val file = File(dir, Backup.getDefaultFilename())
-
-                    Uri.fromFile(file)
-                } else {
-                    val uri = data.data
-                    val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
-                            Intent.FLAG_GRANT_WRITE_URI_PERMISSION
 
-                    activity.contentResolver.takePersistableUriPermission(uri, flags)
-                    val file = UniFile.fromUri(activity, uri)
+                val uri = data.data
+                val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
+                        Intent.FLAG_GRANT_WRITE_URI_PERMISSION
 
-                    file.uri
-                }
+                activity.contentResolver.takePersistableUriPermission(uri, flags)
+                val file = UniFile.fromUri(activity, uri)
 
                 CreatingBackupDialog().showDialog(router, TAG_CREATING_BACKUP_DIALOG)
-                BackupCreateService.makeBackup(activity, uri, backupFlags)
+                BackupCreateService.makeBackup(activity, file.uri, backupFlags)
             }
             CODE_BACKUP_RESTORE -> if (data != null && resultCode == Activity.RESULT_OK) {
                 val uri = data.data
@@ -201,25 +181,17 @@ class SettingsBackupController : SettingsController() {
         val currentDir = preferences.backupsDirectory().getOrDefault()
 
         try {
-            // If API is lower than Lollipop use custom picker
-            val intent = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-                preferences.context.getFilePicker(currentDir)
-            } else {
-                // Use Androids build in file creator
-                Intent(Intent.ACTION_CREATE_DOCUMENT)
+            // Use Android's built-in file creator
+            val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
                     .addCategory(Intent.CATEGORY_OPENABLE)
                     .setType("application/*")
                     .putExtra(Intent.EXTRA_TITLE, Backup.getDefaultFilename())
-            }
 
             startActivityForResult(intent, CODE_BACKUP_CREATE)
         } catch (e: ActivityNotFoundException) {
             // Handle errors where the android ROM doesn't support the built in picker
-            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
-                startActivityForResult(preferences.context.getFilePicker(currentDir), CODE_BACKUP_CREATE)
-            }
+            startActivityForResult(preferences.context.getFilePicker(currentDir), CODE_BACKUP_CREATE)
         }
-
     }
 
     class CreateBackupDialog : DialogController() {

+ 7 - 21
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsDownloadController.kt

@@ -5,7 +5,6 @@ import android.app.Dialog
 import android.content.ActivityNotFoundException
 import android.content.Intent
 import android.net.Uri
-import android.os.Build
 import android.os.Bundle
 import android.os.Environment
 import androidx.core.content.ContextCompat
@@ -107,11 +106,7 @@ class SettingsDownloadController : SettingsController() {
 
     override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
         when (requestCode) {
-            DOWNLOAD_DIR_PRE_L -> if (data != null && resultCode == Activity.RESULT_OK) {
-                val uri = Uri.fromFile(File(data.data.path))
-                preferences.downloadsDirectory().set(uri.toString())
-            }
-            DOWNLOAD_DIR_L -> if (data != null && resultCode == Activity.RESULT_OK) {
+            DOWNLOAD_DIR -> if (data != null && resultCode == Activity.RESULT_OK) {
                 val context = applicationContext ?: return
                 val uri = data.data
                 val flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or
@@ -132,19 +127,11 @@ class SettingsDownloadController : SettingsController() {
     }
 
     fun customDirectorySelected(currentDir: String) {
-
-        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
-            startActivityForResult(preferences.context.getFilePicker(currentDir), DOWNLOAD_DIR_PRE_L)
-        } else {
-            val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
-            try {
-                startActivityForResult(intent, DOWNLOAD_DIR_L)
-            } catch (e: ActivityNotFoundException) {
-                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-                    startActivityForResult(preferences.context.getFilePicker(currentDir), DOWNLOAD_DIR_L)
-                }
-            }
-
+        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
+        try {
+            startActivityForResult(intent, DOWNLOAD_DIR)
+        } catch (e: ActivityNotFoundException) {
+            startActivityForResult(preferences.context.getFilePicker(currentDir), DOWNLOAD_DIR)
         }
     }
 
@@ -183,7 +170,6 @@ class SettingsDownloadController : SettingsController() {
     }
 
     private companion object {
-        const val DOWNLOAD_DIR_PRE_L = 103
-        const val DOWNLOAD_DIR_L = 104
+        const val DOWNLOAD_DIR = 104
     }
 }

+ 1 - 13
app/src/main/java/eu/kanade/tachiyomi/util/DiskUtil.kt

@@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.util
 import android.content.Context
 import android.content.Intent
 import android.net.Uri
-import android.os.Build
 import android.os.Environment
 import androidx.core.content.ContextCompat
 import androidx.core.os.EnvironmentCompat
@@ -45,13 +44,6 @@ object DiskUtil {
                     }
                 }
 
-        if (Build.VERSION.SDK_INT < 21) {
-            val extStorages = System.getenv("SECONDARY_STORAGE")
-            if (extStorages != null) {
-                directories += extStorages.split(":").map(::File)
-            }
-        }
-
         return directories
     }
 
@@ -79,11 +71,7 @@ object DiskUtil {
      * Scans the given file so that it can be shown in gallery apps, for example.
      */
     fun scanMedia(context: Context, uri: Uri) {
-        val action = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
-            Intent.ACTION_MEDIA_MOUNTED
-        } else {
-            Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
-        }
+        val action = Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
         val mediaScanIntent = Intent(action)
         mediaScanIntent.data = uri
         context.sendBroadcast(mediaScanIntent)

+ 0 - 1
app/src/main/java/eu/kanade/tachiyomi/util/WebViewClientCompat.kt

@@ -36,7 +36,6 @@ abstract class WebViewClientCompat : WebViewClient() {
         return shouldOverrideUrlCompat(view, url)
     }
 
-    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
     final override fun shouldInterceptRequest(
             view: WebView,
             request: WebResourceRequest

+ 11 - 17
app/src/main/java/eu/kanade/tachiyomi/widget/ElevationAppBarLayout.kt

@@ -16,32 +16,26 @@ class ElevationAppBarLayout @JvmOverloads constructor(
     private var origStateAnimator: StateListAnimator? = null
 
     init {
-        if (Build.VERSION.SDK_INT >= 21) {
-            origStateAnimator = stateListAnimator
-        }
+        origStateAnimator = stateListAnimator
     }
 
     fun enableElevation() {
-        if (Build.VERSION.SDK_INT >= 21) {
-            stateListAnimator = origStateAnimator
-        }
+        stateListAnimator = origStateAnimator
     }
 
     fun disableElevation() {
-        if (Build.VERSION.SDK_INT >= 21) {
-            stateListAnimator = StateListAnimator().apply {
-                val objAnimator = ObjectAnimator.ofFloat(this, "elevation", 0f)
+        stateListAnimator = StateListAnimator().apply {
+            val objAnimator = ObjectAnimator.ofFloat(this, "elevation", 0f)
 
-                // Enabled and collapsible, but not collapsed means not elevated
-                addState(intArrayOf(android.R.attr.enabled, R.attr.state_collapsible, -R.attr.state_collapsed),
-                        objAnimator)
+            // Enabled and collapsible, but not collapsed means not elevated
+            addState(intArrayOf(android.R.attr.enabled, R.attr.state_collapsible, -R.attr.state_collapsed),
+                    objAnimator)
 
-                // Default enabled state
-                addState(intArrayOf(android.R.attr.enabled), objAnimator)
+            // Default enabled state
+            addState(intArrayOf(android.R.attr.enabled), objAnimator)
 
-                // Disabled state
-                addState(IntArray(0), objAnimator)
-            }
+            // Disabled state
+            addState(IntArray(0), objAnimator)
         }
     }
 

+ 25 - 36
app/src/main/java/eu/kanade/tachiyomi/widget/RevealAnimationView.kt

@@ -2,14 +2,11 @@ package eu.kanade.tachiyomi.widget
 
 import android.animation.Animator
 import android.animation.AnimatorListenerAdapter
-import android.annotation.TargetApi
 import android.content.Context
-import android.os.Build
 import android.util.AttributeSet
 import android.view.View
 import android.view.ViewAnimationUtils
 
-@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 class RevealAnimationView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
         View(context, attrs) {
 
@@ -21,28 +18,25 @@ class RevealAnimationView @JvmOverloads constructor(context: Context, attrs: Att
      * @param initialRadius size of radius of animation
      */
     fun hideRevealEffect(centerX: Int, centerY: Int, initialRadius: Int) {
-        if (Build.VERSION.SDK_INT >= 21) {
+        // Make the view visible.
+        this.visibility = View.VISIBLE
 
-            // Make the view visible.
-            this.visibility = View.VISIBLE
+        // Create the animation (the final radius is zero).
+        val anim = ViewAnimationUtils.createCircularReveal(
+                this, centerX, centerY, initialRadius.toFloat(), 0f)
 
-            // Create the animation (the final radius is zero).
-            val anim = ViewAnimationUtils.createCircularReveal(
-                    this, centerX, centerY, initialRadius.toFloat(), 0f)
+        // Set duration of animation.
+        anim.duration = 500
 
-            // Set duration of animation.
-            anim.duration = 500
+        // make the view invisible when the animation is done
+        anim.addListener(object : AnimatorListenerAdapter() {
+            override fun onAnimationEnd(animation: Animator) {
+                super.onAnimationEnd(animation)
+                [email protected] = View.INVISIBLE
+            }
+        })
 
-            // make the view invisible when the animation is done
-            anim.addListener(object : AnimatorListenerAdapter() {
-                override fun onAnimationEnd(animation: Animator) {
-                    super.onAnimationEnd(animation)
-                    [email protected] = View.INVISIBLE
-                }
-            })
-
-            anim.start()
-        }
+        anim.start()
     }
 
     /**
@@ -55,25 +49,20 @@ class RevealAnimationView @JvmOverloads constructor(context: Context, attrs: Att
      * @return sdk version lower then 21
      */
     fun showRevealEffect(centerX: Int, centerY: Int, listener: Animator.AnimatorListener): Boolean {
-        if (Build.VERSION.SDK_INT >= 21) {
-
-            this.visibility = View.VISIBLE
+        this.visibility = View.VISIBLE
 
-            val height = this.height
+        val height = this.height
 
-            // Create animation
-            val anim = ViewAnimationUtils.createCircularReveal(
-                    this, centerX, centerY, 0f, height.toFloat())
+        // Create animation
+        val anim = ViewAnimationUtils.createCircularReveal(
+                this, centerX, centerY, 0f, height.toFloat())
 
-            // Set duration of animation
-            anim.duration = 350
+        // Set duration of animation
+        anim.duration = 350
 
-            anim.addListener(listener)
-            anim.start()
-            return true
-        }
-        return false
+        anim.addListener(listener)
+        anim.start()
+        return true
     }
 
-
 }

+ 0 - 21
app/src/main/res/drawable-v21/library_item_selector_amoled.xml

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ripple
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/selectorColorDark"
-    >
-    <item>
-        <selector>
-            <item android:state_selected="true">
-                <color android:color="@color/selectorColorDark"/>
-            </item>
-
-            <item android:state_activated="true">
-                <color android:color="@color/selectorColorDark"/>
-            </item>
-
-            <item>
-                <color android:color="@color/md_black_1000"/>
-            </item>
-        </selector>
-    </item>
-</ripple>

+ 0 - 21
app/src/main/res/drawable-v21/library_item_selector_dark.xml

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ripple
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/colorAccentDark"
-    >
-    <item>
-        <selector>
-            <item android:state_selected="true">
-                <color android:color="@color/selectorColorDark"/>
-            </item>
-
-            <item android:state_activated="true">
-                <color android:color="@color/selectorColorDark"/>
-            </item>
-
-            <item>
-                <color android:color="@color/backgroundDark"/>
-            </item>
-        </selector>
-    </item>
-</ripple>

+ 0 - 21
app/src/main/res/drawable-v21/library_item_selector_light.xml

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ripple
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/colorAccentLight"
-    >
-    <item>
-        <selector>
-            <item android:state_selected="true">
-                <color android:color="@color/selectorColorLight"/>
-            </item>
-
-            <item android:state_activated="true">
-                <color android:color="@color/selectorColorLight"/>
-            </item>
-
-            <item>
-                <color android:color="@color/backgroundLight"/>
-            </item>
-        </selector>
-    </item>
-</ripple>

+ 0 - 19
app/src/main/res/drawable-v21/list_item_selector_amoled.xml

@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/rippleColorDark">
-    <item>
-        <selector>
-            <item android:state_selected="true">
-                <color android:color="@color/rippleColorDark"/>
-            </item>
-
-            <item android:state_activated="true">
-                <color android:color="@color/rippleColorDark"/>
-            </item>
-
-            <item>
-                <color android:color="@color/md_black_1000"/>
-            </item>
-        </selector>
-    </item>
-</ripple>

+ 0 - 19
app/src/main/res/drawable-v21/list_item_selector_dark.xml

@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/rippleColorDark">
-    <item>
-        <selector>
-            <item android:state_selected="true">
-                <color android:color="@color/rippleColorDark"/>
-            </item>
-
-            <item android:state_activated="true">
-                <color android:color="@color/rippleColorDark"/>
-            </item>
-
-            <item>
-                <color android:color="@color/dialogDark"/>
-            </item>
-        </selector>
-    </item>
-</ripple>

+ 0 - 19
app/src/main/res/drawable-v21/list_item_selector_light.xml

@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
-    android:color="@color/rippleColorLight">
-    <item>
-        <selector>
-            <item android:state_selected="true">
-                <color android:color="@color/rippleColorLight"/>
-            </item>
-
-            <item android:state_activated="true">
-                <color android:color="@color/rippleColorLight"/>
-            </item>
-
-            <item>
-                <color android:color="@color/dialogLight"/>
-            </item>
-        </selector>
-    </item>
-</ripple>

+ 16 - 7
app/src/main/res/drawable/library_item_selector_amoled.xml

@@ -1,10 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
-<selector android:exitFadeDuration="@android:integer/config_longAnimTime"
-    xmlns:android="http://schemas.android.com/apk/res/android">
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/selectorColorDark">
+    <item>
+        <selector>
+            <item android:state_selected="true">
+                <color android:color="@color/selectorColorDark" />
+            </item>
 
-    <item android:state_focused="true" android:drawable="@color/selectorColorDark"/>
-    <item android:state_pressed="true" android:drawable="@color/selectorColorDark"/>
-    <item android:state_activated="true" android:drawable="@color/selectorColorDark"/>
-    <item android:drawable="@color/md_black_1000"/>
+            <item android:state_activated="true">
+                <color android:color="@color/selectorColorDark" />
+            </item>
 
-</selector>
+            <item>
+                <color android:color="@color/md_black_1000" />
+            </item>
+        </selector>
+    </item>
+</ripple>

+ 16 - 7
app/src/main/res/drawable/library_item_selector_dark.xml

@@ -1,10 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
-<selector android:exitFadeDuration="@android:integer/config_longAnimTime"
-    xmlns:android="http://schemas.android.com/apk/res/android">
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/colorAccentDark">
+    <item>
+        <selector>
+            <item android:state_selected="true">
+                <color android:color="@color/selectorColorDark" />
+            </item>
 
-    <item android:state_focused="true" android:drawable="@color/selectorColorDark"/>
-    <item android:state_pressed="true" android:drawable="@color/selectorColorDark"/>
-    <item android:state_activated="true" android:drawable="@color/selectorColorDark"/>
-    <item android:drawable="@color/backgroundDark"/>
+            <item android:state_activated="true">
+                <color android:color="@color/selectorColorDark" />
+            </item>
 
-</selector>
+            <item>
+                <color android:color="@color/backgroundDark" />
+            </item>
+        </selector>
+    </item>
+</ripple>

+ 16 - 7
app/src/main/res/drawable/library_item_selector_light.xml

@@ -1,10 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
-<selector android:exitFadeDuration="@android:integer/config_longAnimTime"
-    xmlns:android="http://schemas.android.com/apk/res/android">
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/colorAccentLight">
+    <item>
+        <selector>
+            <item android:state_selected="true">
+                <color android:color="@color/selectorColorLight" />
+            </item>
 
-    <item android:state_focused="true" android:drawable="@color/selectorColorLight"/>
-    <item android:state_pressed="true" android:drawable="@color/selectorColorLight"/>
-    <item android:state_activated="true" android:drawable="@color/selectorColorLight"/>
-    <item android:drawable="@color/backgroundLight"/>
+            <item android:state_activated="true">
+                <color android:color="@color/selectorColorLight" />
+            </item>
 
-</selector>
+            <item>
+                <color android:color="@color/backgroundLight" />
+            </item>
+        </selector>
+    </item>
+</ripple>

+ 16 - 7
app/src/main/res/drawable/list_item_selector_amoled.xml

@@ -1,10 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:exitFadeDuration="@android:integer/config_longAnimTime">
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/rippleColorDark">
+    <item>
+        <selector>
+            <item android:state_selected="true">
+                <color android:color="@color/rippleColorDark" />
+            </item>
 
-    <item android:drawable="@color/rippleColorDark" android:state_focused="true"/>
-    <item android:drawable="@color/rippleColorDark" android:state_pressed="true"/>
-    <item android:drawable="@color/rippleColorDark" android:state_activated="true"/>
-    <item android:drawable="@color/md_black_1000"/>
+            <item android:state_activated="true">
+                <color android:color="@color/rippleColorDark" />
+            </item>
 
-</selector>
+            <item>
+                <color android:color="@color/md_black_1000" />
+            </item>
+        </selector>
+    </item>
+</ripple>

+ 16 - 7
app/src/main/res/drawable/list_item_selector_dark.xml

@@ -1,10 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:exitFadeDuration="@android:integer/config_longAnimTime">
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/rippleColorDark">
+    <item>
+        <selector>
+            <item android:state_selected="true">
+                <color android:color="@color/rippleColorDark" />
+            </item>
 
-    <item android:drawable="@color/rippleColorDark" android:state_focused="true"/>
-    <item android:drawable="@color/rippleColorDark" android:state_pressed="true"/>
-    <item android:drawable="@color/rippleColorDark" android:state_activated="true"/>
-    <item android:drawable="@color/dialogDark"/>
+            <item android:state_activated="true">
+                <color android:color="@color/rippleColorDark" />
+            </item>
 
-</selector>
+            <item>
+                <color android:color="@color/dialogDark" />
+            </item>
+        </selector>
+    </item>
+</ripple>

+ 16 - 7
app/src/main/res/drawable/list_item_selector_light.xml

@@ -1,10 +1,19 @@
 <?xml version="1.0" encoding="utf-8"?>
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
-    android:exitFadeDuration="@android:integer/config_longAnimTime">
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="@color/rippleColorLight">
+    <item>
+        <selector>
+            <item android:state_selected="true">
+                <color android:color="@color/rippleColorLight" />
+            </item>
 
-    <item android:drawable="@color/rippleColorLight" android:state_focused="true"/>
-    <item android:drawable="@color/rippleColorLight" android:state_pressed="true"/>
-    <item android:drawable="@color/rippleColorLight" android:state_activated="true"/>
-    <item android:drawable="@color/dialogLight"/>
+            <item android:state_activated="true">
+                <color android:color="@color/rippleColorLight" />
+            </item>
 
-</selector>
+            <item>
+                <color android:color="@color/dialogLight" />
+            </item>
+        </selector>
+    </item>
+</ripple>

+ 0 - 5
app/src/main/res/values-v21/dimens.xml

@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!--Nav header-->
-    <dimen name="navigation_drawer_header_margin">41dp</dimen>
-</resources>

+ 0 - 6
app/src/main/res/values-v21/keys.xml

@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!-- String Fonts -->
-    <string name="font_roboto_medium" translatable="false">sans-serif-medium</string>
-    <string name="font_roboto_regular" translatable="false">sans-serif-regular</string>
-</resources>

+ 0 - 58
app/src/main/res/values-v21/themes.xml

@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <!--===========-->
-    <!-- Main Theme-->
-    <!--===========-->
-    <style name="Theme.Tachiyomi" parent="Theme.Base">
-        <!-- Attributes specific for SDK 21 and up  -->
-        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
-        <item name="android:statusBarColor">@android:color/transparent</item>
-        <item name="android:navigationBarColor">@color/colorPrimaryDark</item>
-    </style>
-
-    <!--=============-->
-    <!-- Dark Themes -->
-    <!--=============-->
-    <style name="Theme.Tachiyomi.Dark" parent="Theme.Base.Dark">
-        <!-- Attributes specific for SDK 21 and up  -->
-        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
-        <item name="android:statusBarColor">@android:color/transparent</item>
-        <item name="android:navigationBarColor">@color/colorDarkPrimaryDark</item>
-    </style>
-
-    <style name="Theme.Tachiyomi.DarkBlue" parent="Theme.Base.Dark">
-        <item name="colorPrimary">@color/colorPrimary</item>
-        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
-
-        <!-- Attributes specific for SDK 21 and up  -->
-        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
-        <item name="android:statusBarColor">@android:color/transparent</item>
-        <item name="android:navigationBarColor">@color/colorDarkPrimaryDark</item>
-    </style>
-
-    <!--==============-->
-    <!-- Amoled Theme -->
-    <!--==============-->
-    <style name="Theme.Tachiyomi.Amoled" parent="Theme.Base.Amoled">
-        <!-- Attributes specific for SDK 21 and up  -->
-        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
-        <item name="android:statusBarColor">@android:color/transparent</item>
-        <item name="android:navigationBarColor">@android:color/transparent</item>
-    </style>
-
-    <!--==============-->
-    <!-- Reader Theme -->
-    <!--==============-->
-    <style name="Theme.Reader" parent="Theme.Base.Reader.Dark">
-        <!-- Attributes specific for SDK 21 and up  -->
-        <item name="android:statusBarColor">?colorPrimaryDark</item>
-        <item name="android:navigationBarColor">?colorPrimaryDark</item>
-    </style>
-
-    <style name="Theme.Reader.Light" parent="Theme.Base.Reader.Light">
-        <!-- Attributes specific for SDK 21 and up  -->
-        <item name="android:statusBarColor">?colorPrimaryDark</item>
-        <item name="android:navigationBarColor">?colorPrimaryDark</item>
-    </style>
-
-</resources>

+ 1 - 2
app/src/main/res/values/dimens.xml

@@ -20,10 +20,9 @@
     <dimen name="text_body">16sp</dimen>
     <dimen name="text_small_body">14sp</dimen>
 
-
     <!--Nav header-->
     <dimen name="navigation_drawer_header_height">158dp</dimen>
-    <dimen name="navigation_drawer_header_margin">16dp</dimen>
+    <dimen name="navigation_drawer_header_margin">41dp</dimen>
 
     <dimen name="bottom_sheet_width">0dp</dimen>
 </resources>

+ 0 - 7
app/src/main/res/values/keys.xml

@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-
-    <!-- String Fonts -->
-    <string name="font_roboto_medium" translatable="false">sans-serif</string>
-    <string name="font_roboto_regular" translatable="false">sans-serif</string>
-</resources>

+ 2 - 2
app/src/main/res/values/styles.xml

@@ -50,7 +50,7 @@
     </style>
 
     <style name="TextAppearance.Regular">
-        <item name="android:fontFamily">@string/font_roboto_regular</item>
+        <item name="android:fontFamily">sans-serif-regular</item>
     </style>
 
     <style name="TextAppearance.Regular.Body1">
@@ -102,7 +102,7 @@
     </style>
 
     <style name="TextAppearance.Medium">
-        <item name="android:fontFamily">@string/font_roboto_medium</item>
+        <item name="android:fontFamily">sans-serif-medium</item>
     </style>
 
     <style name="TextAppearance.Medium.Title">

+ 24 - 1
app/src/main/res/values/themes.xml

@@ -39,8 +39,13 @@
         <item name="icon_color">@color/iconColorLight</item>
     </style>
 
+    <!--===========-->
+    <!-- Main Theme-->
+    <!--===========-->
     <style name="Theme.Tachiyomi" parent="Theme.Base">
-        <!-- Attributes specific for SDK 16 to SDK 20 -->
+        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
+        <item name="android:statusBarColor">@android:color/transparent</item>
+        <item name="android:navigationBarColor">@color/colorPrimaryDark</item>
     </style>
 
     <!--=============-->
@@ -61,6 +66,10 @@
         <item name="android:divider">@color/dividerDark</item>
         <item name="android:listDivider">@drawable/line_divider_dark</item>
 
+        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
+        <item name="android:statusBarColor">@android:color/transparent</item>
+        <item name="android:navigationBarColor">@color/colorDarkPrimaryDark</item>
+
         <!-- Themes -->
         <item name="windowActionModeOverlay">true</item>
         <item name="actionBarTheme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
@@ -86,6 +95,10 @@
     <style name="Theme.Tachiyomi.DarkBlue" parent="Theme.Base.Dark">
         <item name="colorPrimary">@color/colorPrimary</item>
         <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
+
+        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
+        <item name="android:statusBarColor">@android:color/transparent</item>
+        <item name="android:navigationBarColor">@color/colorDarkPrimaryDark</item>
     </style>
 
     <!--==============-->
@@ -96,6 +109,10 @@
         <item name="colorPrimaryDark">@color/colorAmoledPrimary</item>
         <item name="android:colorBackground">@color/md_black_1000</item>
 
+        <item name="android:windowDrawsSystemBarBackgrounds">true</item>
+        <item name="android:statusBarColor">@android:color/transparent</item>
+        <item name="android:navigationBarColor">@android:color/transparent</item>
+
         <!-- Custom Attributes-->
         <item name="selectable_list_drawable">@drawable/list_item_selector_amoled</item>
         <item name="selectable_library_drawable">@drawable/library_item_selector_amoled</item>
@@ -113,12 +130,18 @@
         <item name="colorPrimary">@color/colorDarkPrimary</item>
         <item name="colorPrimaryDark">@color/colorDarkPrimaryDark</item>
         <item name="android:colorBackground">@android:color/black</item>
+
+        <item name="android:statusBarColor">?colorPrimaryDark</item>
+        <item name="android:navigationBarColor">?colorPrimaryDark</item>
     </style>
 
     <style name="Theme.Base.Reader.Light" parent="Theme.Base">
         <item name="colorPrimary">@color/colorDarkPrimary</item>
         <item name="colorPrimaryDark">@color/colorDarkPrimaryDark</item>
         <item name="android:colorBackground">@android:color/white</item>
+
+        <item name="android:statusBarColor">?colorPrimaryDark</item>
+        <item name="android:navigationBarColor">?colorPrimaryDark</item>
     </style>
 
     <style name="Theme.Reader" parent="Theme.Base.Reader.Dark">