diff --git a/CHANGELOG.md b/CHANGELOG.md index 650e6e38cf9..1934362128a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,7 +42,7 @@ ownCloud admins and users. * Enhancement - Auto upload in oCIS accounts allows upload to any space: [#4117](https://github.com/owncloud/android/issues/4117) * Enhancement - Thumbnail improvements in grid view: [#4145](https://github.com/owncloud/android/issues/4145) * Enhancement - Logging changes: [#4151](https://github.com/owncloud/android/issues/4151) -* Enhancement - Download log files: [#4155](https://github.com/owncloud/android/issues/4155) +* Enhancement - Download log files on Android10+ devices: [#4155](https://github.com/owncloud/android/issues/4155) * Enhancement - Log file sharing allowed within ownCloud Android app: [#4156](https://github.com/owncloud/android/issues/4156) * Enhancement - New field "last usage" in database: [#4173](https://github.com/owncloud/android/issues/4173) * Enhancement - Use invoke operator to execute usecases: [#4179](https://github.com/owncloud/android/pull/4179) @@ -180,10 +180,10 @@ ownCloud admins and users. https://github.com/owncloud/android/issues/4151 https://github.com/owncloud/android/pull/4204 -* Enhancement - Download log files: [#4155](https://github.com/owncloud/android/issues/4155) +* Enhancement - Download log files on Android10+ devices: [#4155](https://github.com/owncloud/android/issues/4155) A new icon to download a log file to the Downloads folder of the device has been - added to the log list screen. + added to the log list screen on Android10+ devices. https://github.com/owncloud/android/issues/4155 https://github.com/owncloud/android/pull/4205 diff --git a/changelog/unreleased/4205 b/changelog/unreleased/4205 index 3796992743e..74f95a60627 100644 --- a/changelog/unreleased/4205 +++ b/changelog/unreleased/4205 @@ -1,6 +1,7 @@ -Enhancement: Download log files +Enhancement: Download log files on Android10+ devices -A new icon to download a log file to the Downloads folder of the device has been added to the log list screen. +A new icon to download a log file to the Downloads folder of the device has been added to the log list screen +on Android10+ devices. https://github.com/owncloud/android/issues/4155 https://github.com/owncloud/android/pull/4205 diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/logging/LogsListActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/logging/LogsListActivity.kt index d8c7e4836c0..5175f399f0e 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/logging/LogsListActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/logging/LogsListActivity.kt @@ -22,10 +22,13 @@ package com.owncloud.android.presentation.logging import android.app.DownloadManager import android.content.ActivityNotFoundException +import android.content.ContentValues import android.content.Intent +import android.os.Build import android.os.Bundle -import android.os.Environment +import android.provider.MediaStore import android.view.MenuItem +import androidx.annotation.RequiresApi import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar @@ -46,7 +49,6 @@ import org.koin.androidx.viewmodel.ext.android.viewModel import timber.log.Timber import java.io.File import java.io.FileInputStream -import java.io.FileOutputStream import java.io.IOException class LogsListActivity : AppCompatActivity() { @@ -76,7 +78,9 @@ class LogsListActivity : AppCompatActivity() { } override fun download(file: File) { - downloadFile(file) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + downloadFileQOrAbove(file) + } } }, context = this) @@ -140,31 +144,44 @@ class LogsListActivity : AppCompatActivity() { recyclerViewLogsAdapter.setData(items) } - private fun downloadFile(file: File) { - val destinationPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath - val destinationFolder = File(destinationPath) + @RequiresApi(Build.VERSION_CODES.Q) + private fun downloadFileQOrAbove(file: File) { val originalName = file.name - var uniqueName = originalName - var fileNumber = 1 - while (File(destinationFolder, uniqueName).exists()) { - uniqueName = "$originalName ($fileNumber).log" - fileNumber++ + val resolver = applicationContext.contentResolver + val contentValues = ContentValues().apply { + put(MediaStore.Downloads.DISPLAY_NAME, originalName) + put(MediaStore.Downloads.MIME_TYPE, "application/octet-stream") + put(MediaStore.Downloads.IS_PENDING, 1) } - val destination = File(destinationFolder, uniqueName) + val uri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues) try { - val sourceChannel = FileInputStream(file).channel - val destinationChannel = FileOutputStream(destination).channel - sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel) - sourceChannel.close() - destinationChannel.close() - showDownloadDialog(destination.name) - + uri?.let { downloadUri -> + resolver.openOutputStream(downloadUri)?.use { outputStream -> + FileInputStream(file).use { fileInputStream -> + fileInputStream.copyTo(outputStream) + } + } + contentValues.clear() + contentValues.put(MediaStore.Downloads.IS_PENDING, 0) + resolver.update(downloadUri, contentValues, null, null) + + val cursor = resolver.query(downloadUri, null, null, null, null) + cursor?.use { + if (it.moveToFirst()) { + val displayNameIndex = it.getColumnIndex(MediaStore.Downloads.DISPLAY_NAME) + if (displayNameIndex != -1) { + val finalName = it.getString(displayNameIndex) + showDownloadDialog(finalName) + } + } + } + } } catch (e: IOException) { e.printStackTrace() - Timber.e(e, "There was a problem to download the file to Download folder.") + Timber.e(e, "There was a problem to download the file to Downloads folder.") } } @@ -175,7 +192,7 @@ class LogsListActivity : AppCompatActivity() { .setMessage(getString(R.string.log_file_downloaded_description, fileName)) .setPositiveButton(R.string.go_to_download_folder) { dialog, _ -> dialog.dismiss() - goToDownloadsFolder() + openDownloadsFolder() } .setNegativeButton(R.string.drawer_close) { dialog, _ -> dialog.dismiss() @@ -184,7 +201,7 @@ class LogsListActivity : AppCompatActivity() { dialog.show() } - private fun goToDownloadsFolder() { + private fun openDownloadsFolder() { try { val intent = Intent(DownloadManager.ACTION_VIEW_DOWNLOADS) startActivity(intent) diff --git a/owncloudApp/src/main/java/com/owncloud/android/presentation/logging/RecyclerViewLogsAdapter.kt b/owncloudApp/src/main/java/com/owncloud/android/presentation/logging/RecyclerViewLogsAdapter.kt index 2d86ec2ea69..18aa0db9355 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/presentation/logging/RecyclerViewLogsAdapter.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/presentation/logging/RecyclerViewLogsAdapter.kt @@ -21,9 +21,11 @@ package com.owncloud.android.presentation.logging import android.content.Context +import android.os.Build import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.core.view.isVisible import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import com.owncloud.android.R @@ -49,6 +51,9 @@ class RecyclerViewLogsAdapter( holder.binding.apply { textViewTitleActivityLogsList.text = log.name textViewSubtitleActivityLogsList.text = log.toLegibleStringSize(context) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + imageViewDownloadActivityLogsList.isVisible = false + } imageViewShareActivityLogsList.setOnClickListener { listener.share(log) }