This commit is contained in:
Felix 2019-05-29 22:47:12 +02:00
parent 86f6ef6c4b
commit 42cb76f443
2 changed files with 128 additions and 74 deletions

View file

@ -34,7 +34,8 @@ class OfflineItemManager(
val downloadStatus: MutableMap<Long, DownloadStatus> = HashMap()
private val downloadManager: DownloadManager = context.applicationContext.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
private val downloadManager: DownloadManager =
context.applicationContext.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
private val handler = ThreadHandler()
@ -50,7 +51,8 @@ class OfflineItemManager(
fun updateDownloadStatus(offlineEvents: List<OfflineEvent>) {
if (offlineEvents.isNotEmpty()) {
val downloadRef = offlineEvents.map { it.downloadReference }.toTypedArray().toLongArray()
val downloadRef =
offlineEvents.map { it.downloadReference }.toTypedArray().toLongArray()
updateDownloads(downloadRef)
}
}
@ -64,20 +66,21 @@ class OfflineItemManager(
val id = cursor.getLong(columnId)
val columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)
val status = cursor.getInt(columnIndex)
val bytesSoFarIndex = cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
val bytesSoFarIndex =
cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)
val bytesSoFar = cursor.getInt(bytesSoFarIndex)
val bytesTotalIndex = cursor.getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)
val bytesTotal = cursor.getInt(bytesTotalIndex)
val statusText: String =
when (status) {
DownloadManager.STATUS_RUNNING -> "Running"
DownloadManager.STATUS_FAILED -> "Failed"
DownloadManager.STATUS_PAUSED -> "Paused"
DownloadManager.STATUS_SUCCESSFUL -> "Successful"
DownloadManager.STATUS_PENDING -> "Pending"
else -> "UNKNOWN"
}
when (status) {
DownloadManager.STATUS_RUNNING -> "Running"
DownloadManager.STATUS_FAILED -> "Failed"
DownloadManager.STATUS_PAUSED -> "Paused"
DownloadManager.STATUS_SUCCESSFUL -> "Successful"
DownloadManager.STATUS_PENDING -> "Pending"
else -> "UNKNOWN"
}
if (downloadStatus.containsKey(id)) {
val item = downloadStatus[id]
item?.statusText?.set(statusText)
@ -86,52 +89,73 @@ class OfflineItemManager(
item?.status = status
} else {
downloadStatus.put(
id,
DownloadStatus(statusText, bytesSoFar, bytesTotal, status))
id,
DownloadStatus(statusText, bytesSoFar, bytesTotal, status)
)
}
} while (cursor.moveToNext())
}
}
fun download(event: Event, recording: Recording): LiveData<LiveEvent<State, String, Exception>> {
fun download(
event: Event,
recording: Recording
): LiveData<LiveEvent<State, String, Exception>> {
val result = MutableLiveData<LiveEvent<State, String, Exception>>()
result.postValue(LiveEvent(State.Downloading))
handler.runOnBackgroundThread {
if (ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(
applicationContext,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
!= PackageManager.PERMISSION_GRANTED
) {
result.postValue(LiveEvent(State.PermissionRequired))
} else {
val offlineEvent = offlineEventDao.getByEventGuidSync(event.guid)
if (offlineEvent == null) {
val downloadUri = getDownloadDir()
File(getDownloadDir().toString())
// .buildUpon()
// .appendPath(recording.filename)
// .build()
val request = DownloadManager.Request(Uri.parse(recording.recordingUrl)).apply {
setTitle(event.title)
val request = DownloadManager.Request(Uri.parse(recording.recordingUrl))
request.setTitle(event.title)
setDestinationUri(downloadUri)
setDescription(event.title)
setMimeType(recording.mimeType)
request.setDestinationUri(
Uri.withAppendedPath(Uri.fromFile(
File(getDownloadDir())), recording.filename))
setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
setVisibleInDownloadsUi(true)
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
request.setVisibleInDownloadsUi(true)
if (!preferencesManager.getMetered()) {
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI)
request.setAllowedOverMetered(false)
if (!preferencesManager.getMetered()) {
setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI)
setAllowedOverMetered(false)
}
}
val downloadReference = downloadManager.enqueue(request)
Log.d(DetailsViewModel.TAG, "download started $downloadReference")
val cancelHandler = DownloadCancelHandler(applicationContext, downloadReference, offlineEventDao, preferencesManager)
val cancelHandler = DownloadCancelHandler(
applicationContext,
downloadReference,
offlineEventDao,
preferencesManager
)
val intentFilter = IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
applicationContext.registerReceiver(cancelHandler, intentFilter)
try {
offlineEventDao.insert(
OfflineEvent(eventGuid = event.guid,
recordingId = recording.id,
localPath = getDownloadDir() + recording.filename,
downloadReference = downloadReference))
OfflineEvent(
eventGuid = event.guid,
recordingId = recording.id,
localPath = downloadUri.toString(),
downloadReference = downloadReference
)
)
} catch (ex: SQLiteConstraintException) {
Log.d(DetailsViewModel.TAG, ex.message)
}
@ -192,7 +216,8 @@ class OfflineItemManager(
override fun onReceive(p0: Context?, p1: Intent?) {
val downloadId = p1?.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0)
if (downloadId != null && downloadId == id) {
val offlineItemManager = OfflineItemManager(context, offlineEventDao, preferencesManager)
val offlineItemManager =
OfflineItemManager(context, offlineEventDao, preferencesManager)
offlineItemManager.addDownloadRefs(listOf(downloadId))
offlineItemManager.updateDownloadStatus()
val downloadStatus = offlineItemManager.downloadStatus[downloadId]
@ -209,14 +234,13 @@ class OfflineItemManager(
private fun getMovieDir(): String {
val sharedPref: SharedPreferences = PreferenceManager
.getDefaultSharedPreferences(applicationContext)
var dir = sharedPref.getString("download_folder", null)
return dir ?: Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).path
.getDefaultSharedPreferences(applicationContext)
val dir = sharedPref.getString("download_folder", null)
return dir
?: Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).path + DOWNLOAD_DIR
}
private fun getDownloadDir(): String {
return getMovieDir() + DOWNLOAD_DIR
}
private fun getDownloadDir(): Uri = Uri.parse(getMovieDir())
companion object {
const val DOWNLOAD_DIR = "/chaosflix/"
@ -225,4 +249,4 @@ class OfflineItemManager(
enum class State {
Downloading, Done, PermissionRequired
}
}
}

View file

@ -1,6 +1,7 @@
package de.nicidienase.chaosflix.touch.settings
import android.Manifest
import android.app.Activity
import android.arch.lifecycle.Observer
import android.arch.lifecycle.ViewModelProviders
import android.content.Context
@ -14,8 +15,6 @@ import de.nicidienase.chaosflix.R
import de.nicidienase.chaosflix.common.checkPermission
import de.nicidienase.chaosflix.common.viewmodel.PreferencesViewModel
import de.nicidienase.chaosflix.common.viewmodel.ViewModelFactory
import net.rdrei.android.dirchooser.DirectoryChooserActivity
import net.rdrei.android.dirchooser.DirectoryChooserConfig
class SettingsFragment : PreferenceFragmentCompat() {
private val REQUEST_DIRECTORY: Int = 0
@ -25,42 +24,58 @@ class SettingsFragment : PreferenceFragmentCompat() {
override fun onAttach(context: Context?) {
super.onAttach(context)
context?.let { c ->
viewModel = ViewModelProviders.of(this, ViewModelFactory(c)).get(PreferencesViewModel::class.java)
viewModel = ViewModelProviders.of(this, ViewModelFactory(c))
.get(PreferencesViewModel::class.java)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_DIRECTORY && resultCode == Activity.RESULT_OK) {
data?.data
val dir = data?.data
if (requestCode == REQUEST_DIRECTORY) {
if (resultCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) {
val dir = data?.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR)
val sharedPref = PreferenceManager.getDefaultSharedPreferences(requireContext().applicationContext)
val edit = sharedPref.edit()
edit.putString("download_folder", dir)
edit.apply()
this.updateSummary()
}
val uri = data?.data
if (uri != null && "content".equals(uri.getScheme())) {
val cursor = requireContext()
.contentResolver
.query(uri, arrayOf(android.provider.MediaStore.Files.), null, null, null)
cursor.moveToFirst()
val filePath = cursor.getString(0)
cursor.close()
}
val sharedPref =
PreferenceManager.getDefaultSharedPreferences(requireContext().applicationContext)
val edit = sharedPref.edit()
edit.putString(DOWNLOAD_FOLDER_KEY, dir.toString())
edit.apply()
this.updateSummary()
}
super.onActivityResult(requestCode, resultCode, data)
}
private fun updateSummary() {
val sharedPref = PreferenceManager.getDefaultSharedPreferences(requireContext().applicationContext)
val folder = sharedPref.getString("download_folder", "")
val pref = this.findPreference("download_folder")
pref.setSummary(folder)
val sharedPref =
PreferenceManager.getDefaultSharedPreferences(requireContext().applicationContext)
val folder = sharedPref.getString(DOWNLOAD_FOLDER_KEY, "")
val pref = this.findPreference(DOWNLOAD_FOLDER_KEY)
pref.summary = folder
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences, rootKey)
updateSummary()
val downloadFolderPref = this.findPreference("download_folder")
val downloadFolderPref = this.findPreference(DOWNLOAD_FOLDER_KEY)
val cleanCachePref = this.findPreference("delete_data")
val exportFavorites = this.findPreference("export_favorites")
val importFavorites = this.findPreference("import_favorites")
downloadFolderPref?.setOnPreferenceClickListener {
checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE, PERMISSION_REQUEST_CHOOSE_DOWNLOAD_FOLDER) {
checkPermission(
Manifest.permission.READ_EXTERNAL_STORAGE,
PERMISSION_REQUEST_CHOOSE_DOWNLOAD_FOLDER
) {
chooseDownloadFolder()
}
return@setOnPreferenceClickListener true
@ -72,14 +87,20 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
exportFavorites?.setOnPreferenceClickListener {
checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, PERMISSION_REQUEST_EXPORT_FAVORITES) {
checkPermission(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
PERMISSION_REQUEST_EXPORT_FAVORITES
) {
viewModel.exportFavorites()
}
return@setOnPreferenceClickListener true
}
importFavorites?.setOnPreferenceClickListener {
checkPermission(Manifest.permission.READ_EXTERNAL_STORAGE, PERMISSION_REQUEST_IMPORT_FAVORITES) {
checkPermission(
Manifest.permission.READ_EXTERNAL_STORAGE,
PERMISSION_REQUEST_IMPORT_FAVORITES
) {
importFavorites()
}
return@setOnPreferenceClickListener true
@ -87,39 +108,47 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
private fun chooseDownloadFolder() {
val chooserIntent = Intent(context, DirectoryChooserActivity::class.java)
val config = DirectoryChooserConfig.builder()
.newDirectoryName("Download folder")
.allowReadOnlyDirectory(false)
.allowNewDirectoryNameModification(true)
.build()
chooserIntent.putExtra(DirectoryChooserActivity.EXTRA_CONFIG, config)
val chooserIntent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
startActivityForResult(chooserIntent, REQUEST_DIRECTORY)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
when (requestCode) {
PERMISSION_REQUEST_IMPORT_FAVORITES -> {
if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
importFavorites()
} else {
Snackbar.make(listView, "Cannot import without Storage Permission.", Snackbar.LENGTH_SHORT).show()
Snackbar.make(
listView,
"Cannot import without Storage Permission.",
Snackbar.LENGTH_SHORT
).show()
}
}
PERMISSION_REQUEST_EXPORT_FAVORITES -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
viewModel.exportFavorites()
} else {
Snackbar.make(listView, "Cannot export without Storage Permission.", Snackbar.LENGTH_SHORT).show()
Snackbar.make(
listView,
"Cannot export without Storage Permission.",
Snackbar.LENGTH_SHORT
).show()
}
}
PERMISSION_REQUEST_CHOOSE_DOWNLOAD_FOLDER -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
chooseDownloadFolder()
} else {
Snackbar.make(listView, "Cannot access folders without Storage Permission.", Snackbar.LENGTH_SHORT).show()
Snackbar.make(
listView,
"Cannot access folders without Storage Permission.",
Snackbar.LENGTH_SHORT
).show()
}
}
else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults)
@ -155,6 +184,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
const val PERMISSION_REQUEST_EXPORT_FAVORITES = 23
const val PERMISSION_REQUEST_IMPORT_FAVORITES = 24
const val PERMISSION_REQUEST_CHOOSE_DOWNLOAD_FOLDER = 25
const val DOWNLOAD_FOLDER_KEY = "download_folder"
fun getInstance(): SettingsFragment {
val fragment = SettingsFragment()