#268 Optionally upload newly created videos via automatic upload as well

This commit is contained in:
Julian Raufelder 2021-02-21 00:19:23 +01:00
parent 1db64d3701
commit d6d5546c17
No known key found for this signature in database
GPG Key ID: 17EE71F6634E381D
4 changed files with 50 additions and 22 deletions

View File

@ -7,18 +7,18 @@ import android.app.job.JobScheduler
import android.app.job.JobService import android.app.job.JobService
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.database.Cursor
import android.database.MergeCursor import android.database.MergeCursor
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
import android.provider.MediaStore import android.provider.MediaStore
import android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
import android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import org.cryptomator.domain.exception.FatalBackendException import org.cryptomator.domain.exception.FatalBackendException
import org.cryptomator.presentation.R import org.cryptomator.presentation.R
import org.cryptomator.presentation.util.FileUtil import org.cryptomator.presentation.util.FileUtil
import org.cryptomator.presentation.util.ResourceHelper import org.cryptomator.presentation.util.ResourceHelper
import org.cryptomator.util.SharedPreferencesHandler
import org.cryptomator.util.file.MimeTypeMap_Factory import org.cryptomator.util.file.MimeTypeMap_Factory
import org.cryptomator.util.file.MimeTypes import org.cryptomator.util.file.MimeTypes
import timber.log.Timber import timber.log.Timber
@ -45,13 +45,10 @@ class PhotoContentJob : JobService() {
if (params.triggeredContentUris != null) { if (params.triggeredContentUris != null) {
val ids = getIds(params) val ids = getIds(params)
if (ids != null && ids.isNotEmpty()) { if (ids != null && ids.isNotEmpty()) {
val selection = buildSelection(ids) MergeCursor(getContentResolvers(ids)).use {
contentResolver.query(EXTERNAL_CONTENT_URI, PROJECTION, selection, null, null).use { externalCursor -> while (it.moveToNext()) {
contentResolver.query(INTERNAL_CONTENT_URI, PROJECTION, selection, null, null).use { internalCursor ->
MergeCursor(arrayOf(externalCursor, internalCursor)).use { cursor ->
while (cursor.moveToNext()) {
try { try {
val dir = cursor.getString(PROJECTION_DATA) val dir = it.getString(PROJECTION_DATA)
fileUtil.addImageToAutoUploads(dir) fileUtil.addImageToAutoUploads(dir)
Timber.tag("PhotoContentJob").i("Added file to UploadList") Timber.tag("PhotoContentJob").i("Added file to UploadList")
Timber.tag("PhotoContentJob").d(String.format("Added file to UploadList %s", dir)) Timber.tag("PhotoContentJob").d(String.format("Added file to UploadList %s", dir))
@ -62,8 +59,6 @@ class PhotoContentJob : JobService() {
} }
} }
} }
}
}
} else { } else {
Timber.tag("PhotoContentJob").d("ids are null or 0: %s", ids) Timber.tag("PhotoContentJob").d("ids are null or 0: %s", ids)
} }
@ -77,10 +72,29 @@ class PhotoContentJob : JobService() {
return false return false
} }
private fun getContentResolvers(ids: Set<String>): Array<Cursor?> {
val selection = buildSelection(ids)
var resolvers = arrayOf(contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, PROJECTION_IMAGES, selection, null, null),
contentResolver.query(MediaStore.Images.Media.INTERNAL_CONTENT_URI, PROJECTION_IMAGES, selection, null, null))
if (SharedPreferencesHandler(applicationContext).autoPhotoUploadIncludingVideos()) {
resolvers += arrayOf(contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, PROJECTION_VIDEOS, selection, null, null),
contentResolver.query(MediaStore.Video.Media.INTERNAL_CONTENT_URI, PROJECTION_VIDEOS, selection, null, null))
}
return resolvers
}
private fun getIds(params: JobParameters): Set<String>? { private fun getIds(params: JobParameters): Set<String>? {
return params.triggeredContentUris return params.triggeredContentUris
?.map { it.pathSegments } ?.map { it.pathSegments }
?.filter { it != null && (it.size == EXTERNAL_CONTENT_URI.pathSegments.size + 1 || it.size == INTERNAL_CONTENT_URI.pathSegments.size + 1) } ?.filter {
it != null && (it.size == MediaStore.Images.Media.EXTERNAL_CONTENT_URI.pathSegments.size + 1
|| it.size == MediaStore.Video.Media.EXTERNAL_CONTENT_URI.pathSegments.size + 1
|| it.size == MediaStore.Images.Media.INTERNAL_CONTENT_URI.pathSegments.size + 1
|| it.size == MediaStore.Video.Media.INTERNAL_CONTENT_URI.pathSegments.size + 1)
}
?.mapTo(HashSet()) { it[it.size - 1] } ?.mapTo(HashSet()) { it[it.size - 1] }
} }
@ -112,7 +126,8 @@ class PhotoContentJob : JobService() {
companion object { companion object {
private val MEDIA_URI = Uri.parse("content://" + MediaStore.AUTHORITY + "/") private val MEDIA_URI = Uri.parse("content://" + MediaStore.AUTHORITY + "/")
internal val PROJECTION = arrayOf(MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATA) internal val PROJECTION_IMAGES = arrayOf(MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATA)
internal val PROJECTION_VIDEOS = arrayOf(MediaStore.Video.VideoColumns._ID, MediaStore.Video.VideoColumns.DATA)
internal const val PROJECTION_DATA = 1 internal const val PROJECTION_DATA = 1
@ -121,8 +136,10 @@ class PhotoContentJob : JobService() {
init { init {
val builder = JobInfo.Builder(PHOTOS_CONTENT_JOB, ComponentName(ResourceHelper.getString(R.string.app_id), PhotoContentJob::class.java.name)) val builder = JobInfo.Builder(PHOTOS_CONTENT_JOB, ComponentName(ResourceHelper.getString(R.string.app_id), PhotoContentJob::class.java.name))
builder.addTriggerContentUri(JobInfo.TriggerContentUri(EXTERNAL_CONTENT_URI, FLAG_NOTIFY_FOR_DESCENDANTS)) builder.addTriggerContentUri(JobInfo.TriggerContentUri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, FLAG_NOTIFY_FOR_DESCENDANTS))
builder.addTriggerContentUri(JobInfo.TriggerContentUri(INTERNAL_CONTENT_URI, FLAG_NOTIFY_FOR_DESCENDANTS)) builder.addTriggerContentUri(JobInfo.TriggerContentUri(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, FLAG_NOTIFY_FOR_DESCENDANTS))
builder.addTriggerContentUri(JobInfo.TriggerContentUri(MediaStore.Images.Media.INTERNAL_CONTENT_URI, FLAG_NOTIFY_FOR_DESCENDANTS))
builder.addTriggerContentUri(JobInfo.TriggerContentUri(MediaStore.Video.Media.INTERNAL_CONTENT_URI, FLAG_NOTIFY_FOR_DESCENDANTS))
builder.addTriggerContentUri(JobInfo.TriggerContentUri(MEDIA_URI, FLAG_NOTIFY_FOR_DESCENDANTS)) builder.addTriggerContentUri(JobInfo.TriggerContentUri(MEDIA_URI, FLAG_NOTIFY_FOR_DESCENDANTS))
jobInfo = builder.build() jobInfo = builder.build()
} }

View File

@ -212,6 +212,7 @@
<string name="screen_settings_section_auto_photo_upload_vault">Choose vault for upload</string> <string name="screen_settings_section_auto_photo_upload_vault">Choose vault for upload</string>
<string name="screen_settings_section_auto_photo_upload_toggle">Activate</string> <string name="screen_settings_section_auto_photo_upload_toggle">Activate</string>
<string name="screen_settings_section_auto_photo_upload_only_wifi_toggle">Upload only using WIFI</string> <string name="screen_settings_section_auto_photo_upload_only_wifi_toggle">Upload only using WIFI</string>
<string name="screen_settings_section_auto_photo_upload_including_videos">Upload videos</string>
<string name="screen_settings_auto_photo_upload_title">Save auto upload files to&#8230;</string> <string name="screen_settings_auto_photo_upload_title">Save auto upload files to&#8230;</string>

View File

@ -110,6 +110,11 @@
android:key="photoUploadOnlyUsingWifi" android:key="photoUploadOnlyUsingWifi"
android:title="@string/screen_settings_section_auto_photo_upload_only_wifi_toggle" /> android:title="@string/screen_settings_section_auto_photo_upload_only_wifi_toggle" />
<androidx.preference.SwitchPreferenceCompat
android:defaultValue="false"
android:key="photoUploadIncludingVideos"
android:title="@string/screen_settings_section_auto_photo_upload_including_videos" />
<Preference <Preference
android:key="photoUploadVault" android:key="photoUploadVault"
android:title="@string/screen_settings_section_auto_photo_upload_vault"> android:title="@string/screen_settings_section_auto_photo_upload_vault">

View File

@ -148,6 +148,10 @@ constructor(context: Context) : SharedPreferences.OnSharedPreferenceChangeListen
defaultSharedPreferences.setValue(PHOTO_UPLOAD_FOLDER, location) defaultSharedPreferences.setValue(PHOTO_UPLOAD_FOLDER, location)
} }
fun autoPhotoUploadIncludingVideos(): Boolean {
return defaultSharedPreferences.getValue(PHOTO_UPLOAD_INCLUDING_VIDEOS, false)
}
fun useLruCache(): Boolean { fun useLruCache(): Boolean {
return defaultSharedPreferences.getValue(USE_LRU_CACHE, false) return defaultSharedPreferences.getValue(USE_LRU_CACHE, false)
} }
@ -243,6 +247,7 @@ constructor(context: Context) : SharedPreferences.OnSharedPreferenceChangeListen
const val PHOTO_UPLOAD_ONLY_USING_WIFI = "photoUploadOnlyUsingWifi" const val PHOTO_UPLOAD_ONLY_USING_WIFI = "photoUploadOnlyUsingWifi"
const val PHOTO_UPLOAD_VAULT = "photoUploadVault" const val PHOTO_UPLOAD_VAULT = "photoUploadVault"
const val PHOTO_UPLOAD_FOLDER = "photoUploadFolder" const val PHOTO_UPLOAD_FOLDER = "photoUploadFolder"
const val PHOTO_UPLOAD_INCLUDING_VIDEOS = "photoUploadIncludingVideos"
const val USE_LRU_CACHE = "lruCache" const val USE_LRU_CACHE = "lruCache"
const val LRU_CACHE_SIZE = "lruCacheSize" const val LRU_CACHE_SIZE = "lruCacheSize"
const val MAIL = "mail" const val MAIL = "mail"