Skip to content

Commit

Permalink
WIP: Background Scan
Browse files Browse the repository at this point in the history
  • Loading branch information
newhinton committed Nov 14, 2024
1 parent 709e7cb commit bb235da
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 1 deletion.
5 changes: 4 additions & 1 deletion app/src/main/java/de/felixnuesse/disky/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import de.felixnuesse.disky.ui.BottomSheet
import de.felixnuesse.disky.ui.ChangeFolderCallback
import de.felixnuesse.disky.ui.RecyclerViewAdapter
import de.felixnuesse.disky.utils.PermissionManager
import de.felixnuesse.disky.worker.WorkerManager
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -96,6 +97,7 @@ class MainActivity : AppCompatActivity(), ChangeFolderCallback, ScanCompleteCall
//finish()
}


storageManager = getSystemService(Context.STORAGE_SERVICE) as StorageManager

ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
Expand Down Expand Up @@ -131,7 +133,8 @@ class MainActivity : AppCompatActivity(), ChangeFolderCallback, ScanCompleteCall

registerReciever()
if(isIntroComplete) {
triggerDataUpdate()
//triggerDataUpdate()
WorkerManager().scheduleDaily(this)
}
}

Expand Down
128 changes: 128 additions & 0 deletions app/src/main/java/de/felixnuesse/disky/worker/BackgroundScanWorker.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package de.felixnuesse.disky.worker

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service.NOTIFICATION_SERVICE
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Environment.MEDIA_UNMOUNTED
import android.os.storage.StorageManager
import android.os.storage.StorageVolume
import android.util.Log
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import de.felixnuesse.disky.R
import de.felixnuesse.disky.background.ScanService
import de.felixnuesse.disky.background.ScanService.Companion.SCAN_ABORTED
import de.felixnuesse.disky.background.ScanService.Companion.SCAN_COMPLETE
import de.felixnuesse.disky.background.ScanService.Companion.SCAN_PROGRESSED
import de.felixnuesse.disky.background.ScanService.Companion.SCAN_STORAGE
import de.felixnuesse.disky.extensions.tag

class BackgroundScanWorker(private var context: Context, workerParams: WorkerParameters): Worker(context, workerParams) {

companion object {
private val NOTIFICATION_CHANNEL_ID = "background_scan_notification_channel"
private val NOTIFICATION_ID = 5692

}

override fun doWork(): Result {

createNotificationChannel()

Log.e(tag(), "trigger doWork!!")

val storageManager = context.getSystemService(Context.STORAGE_SERVICE) as StorageManager
storageManager.storageVolumes.forEach {
if(it.state == MEDIA_UNMOUNTED) {
return@forEach
}

//while(ScanService.isRunning()) {
// Thread.sleep(1000)
//todo: dont run this endlessly
//}

if(it.isPrimary) {
scanStorage(it)
}
}


// Indicate whether the work finished successfully with the Result
return Result.success()
}

fun scanStorage(storageVolume: StorageVolume) {

var lastScanStarted = System.currentTimeMillis()
Log.e(tag(), "trigger update for: ${storageVolume.getDescription(context)}")

val reciever = object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent) {
if(intent.action == SCAN_ABORTED) {
//todo: show error
return
}

if(intent.action == SCAN_PROGRESSED) {
// no action needed
}

if(intent.action == SCAN_COMPLETE) {
ScanService.getResult()?.let {

val rootUsed = it.rootElement?.getCalculatedSize()?: 0L
val rootTotal = it.total
val currentlyUsed = rootUsed.div(rootTotal.toDouble()) * 100

// todo: make configurable
if(currentlyUsed > 90) {
showNotification("Used: $currentlyUsed %")
}
}

Log.e(tag(), "Scanning and processing took: ${System.currentTimeMillis()-lastScanStarted}ms")
}
}
}
val filter = IntentFilter(SCAN_COMPLETE)
filter.addAction(SCAN_ABORTED)
filter.addAction(SCAN_PROGRESSED)
LocalBroadcastManager.getInstance(context).registerReceiver(reciever, filter)
val service = Intent(context, ScanService::class.java)
service.putExtra(SCAN_STORAGE, storageVolume.getDescription(context))
context.startForegroundService(service)
}

private fun createNotificationChannel() {
val channel = NotificationChannel(
NOTIFICATION_CHANNEL_ID,
context.getString(R.string.storagewarning_notification_channel_name),
NotificationManager.IMPORTANCE_DEFAULT
)
channel.setSound(null, null)

val notificationManager = context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}

private fun showNotification(message: String) {
createNotificationChannel()
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setContentTitle(context.getString(R.string.storagewarning_notification_title))
.setSmallIcon(R.drawable.icon_disc_full)
.setContentText(message)

with(NotificationManagerCompat.from(context)) {
notify(NOTIFICATION_ID, notification.build())
}
}

}
32 changes: 32 additions & 0 deletions app/src/main/java/de/felixnuesse/disky/worker/WorkerManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package de.felixnuesse.disky.worker

import android.content.Context
import androidx.work.Constraints
import androidx.work.PeriodicWorkRequest
import androidx.work.WorkManager
import java.util.concurrent.TimeUnit


class WorkerManager{


fun scheduleDaily (context: Context) {


// Todo: make configurable
val backgroundScannerConstraints = Constraints.Builder()
.setRequiresCharging(false)
.setRequiresBatteryNotLow(true)
.build()


// Todo: Calculate initial delay to 9 oclock
val workerRequest = PeriodicWorkRequest.Builder(BackgroundScanWorker::class.java, 24, TimeUnit.HOURS)
.setConstraints(backgroundScannerConstraints)
.setInitialDelay(60, TimeUnit.MINUTES)
.build()
WorkManager.getInstance(context).enqueue(workerRequest)
}


}
5 changes: 5 additions & 0 deletions app/src/main/res/drawable/icon_disc_full.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">

<path android:fillColor="@android:color/white" android:pathData="M20,7h2v5h-2zM10,4c-4.42,0 -8,3.58 -8,8s3.58,8 8,8 8,-3.58 8,-8 -3.58,-8 -8,-8zM10,18c-3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6 6,2.69 6,6 -2.69,6 -6,6zM20,14h2v2h-2zM10,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>

</vector>
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@
<string name="delete_confirmation_text">Are you sure you want to delete \"%1$s\"? This cannot be undone!</string>
<string name="delete_file_title">Delete File</string>
<string name="delete_folder_title">Delete Folder</string>
<string name="storagewarning_notification_title">Disky: Warning! Storage filling up!</string>
<string name="storagewarning_notification_channel_name">Full Storage Warning</string>

<string name="action_cancel">Cancel</string>
<string name="activity_about_madeby">Made by:</string>
<string name="help">Help</string>
Expand Down

0 comments on commit bb235da

Please sign in to comment.