Remove BackupJobService as the OS is scheduling its own backups
This commit is contained in:
parent
a6e971609c
commit
bd968be0b1
8 changed files with 35 additions and 112 deletions
|
@ -55,10 +55,5 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service
|
|
||||||
android:name=".service.backup.BackupJobService"
|
|
||||||
android:exported="false"
|
|
||||||
android:permission="android.permission.BIND_JOB_SERVICE" />
|
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -11,7 +11,6 @@ import com.stevesoltys.backup.R;
|
||||||
|
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static com.stevesoltys.backup.settings.SettingsManagerKt.areBackupsScheduled;
|
|
||||||
|
|
||||||
public class MainActivity extends Activity implements View.OnClickListener {
|
public class MainActivity extends Activity implements View.OnClickListener {
|
||||||
|
|
||||||
|
@ -37,7 +36,6 @@ public class MainActivity extends Activity implements View.OnClickListener {
|
||||||
|
|
||||||
automaticBackupsButton = findViewById(R.id.automatic_backups_button);
|
automaticBackupsButton = findViewById(R.id.automatic_backups_button);
|
||||||
automaticBackupsButton.setOnClickListener(this);
|
automaticBackupsButton.setOnClickListener(this);
|
||||||
if (areBackupsScheduled(this)) automaticBackupsButton.setVisibility(GONE);
|
|
||||||
|
|
||||||
changeLocationButton = findViewById(R.id.change_backup_location_button);
|
changeLocationButton = findViewById(R.id.change_backup_location_button);
|
||||||
changeLocationButton.setOnClickListener(this);
|
changeLocationButton.setOnClickListener(this);
|
||||||
|
|
|
@ -1,35 +1,26 @@
|
||||||
package com.stevesoltys.backup.activity;
|
package com.stevesoltys.backup.activity;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.job.JobInfo;
|
|
||||||
import android.app.job.JobScheduler;
|
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.stevesoltys.backup.activity.backup.CreateBackupActivity;
|
import com.stevesoltys.backup.activity.backup.CreateBackupActivity;
|
||||||
import com.stevesoltys.backup.activity.restore.RestoreBackupActivity;
|
import com.stevesoltys.backup.activity.restore.RestoreBackupActivity;
|
||||||
import com.stevesoltys.backup.service.backup.BackupJobService;
|
|
||||||
import com.stevesoltys.backup.transport.ConfigurableBackupTransportService;
|
import com.stevesoltys.backup.transport.ConfigurableBackupTransportService;
|
||||||
|
|
||||||
import static android.app.job.JobInfo.NETWORK_TYPE_UNMETERED;
|
|
||||||
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
|
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
|
||||||
import static android.content.Intent.ACTION_OPEN_DOCUMENT_TREE;
|
import static android.content.Intent.ACTION_OPEN_DOCUMENT_TREE;
|
||||||
import static android.content.Intent.CATEGORY_OPENABLE;
|
import static android.content.Intent.CATEGORY_OPENABLE;
|
||||||
import static android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION;
|
import static android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION;
|
||||||
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
|
||||||
import static android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
|
import static android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
|
||||||
import static com.stevesoltys.backup.BackupKt.JOB_ID_BACKGROUND_BACKUP;
|
|
||||||
import static com.stevesoltys.backup.activity.MainActivity.OPEN_DOCUMENT_TREE_BACKUP_REQUEST_CODE;
|
import static com.stevesoltys.backup.activity.MainActivity.OPEN_DOCUMENT_TREE_BACKUP_REQUEST_CODE;
|
||||||
import static com.stevesoltys.backup.activity.MainActivity.OPEN_DOCUMENT_TREE_REQUEST_CODE;
|
import static com.stevesoltys.backup.activity.MainActivity.OPEN_DOCUMENT_TREE_REQUEST_CODE;
|
||||||
import static com.stevesoltys.backup.settings.SettingsManagerKt.getBackupFolderUri;
|
import static com.stevesoltys.backup.settings.SettingsManagerKt.getBackupFolderUri;
|
||||||
import static com.stevesoltys.backup.settings.SettingsManagerKt.getBackupPassword;
|
import static com.stevesoltys.backup.settings.SettingsManagerKt.getBackupPassword;
|
||||||
import static com.stevesoltys.backup.settings.SettingsManagerKt.setBackupFolderUri;
|
import static com.stevesoltys.backup.settings.SettingsManagerKt.setBackupFolderUri;
|
||||||
import static com.stevesoltys.backup.settings.SettingsManagerKt.setBackupsScheduled;
|
|
||||||
import static java.util.Objects.requireNonNull;
|
|
||||||
import static java.util.concurrent.TimeUnit.DAYS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Steve Soltys
|
* @author Steve Soltys
|
||||||
|
@ -89,24 +80,8 @@ public class MainActivityController {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// schedule backups
|
|
||||||
final ComponentName serviceName = new ComponentName(parent, BackupJobService.class);
|
|
||||||
JobInfo job = new JobInfo.Builder(JOB_ID_BACKGROUND_BACKUP, serviceName)
|
|
||||||
.setRequiredNetworkType(NETWORK_TYPE_UNMETERED)
|
|
||||||
.setRequiresBatteryNotLow(true)
|
|
||||||
.setRequiresStorageNotLow(true) // TODO warn the user instead
|
|
||||||
.setPeriodic(DAYS.toMillis(1))
|
|
||||||
.setRequiresCharging(true)
|
|
||||||
.setPersisted(true)
|
|
||||||
.build();
|
|
||||||
JobScheduler scheduler = requireNonNull(parent.getSystemService(JobScheduler.class));
|
|
||||||
scheduler.schedule(job);
|
|
||||||
|
|
||||||
// remember that backups were scheduled
|
|
||||||
setBackupsScheduled(parent);
|
|
||||||
|
|
||||||
// show Toast informing the user
|
// show Toast informing the user
|
||||||
Toast.makeText(parent, "Backups will run automatically now", Toast.LENGTH_SHORT).show();
|
Toast.makeText(parent, "REMOVED", Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +0,0 @@
|
||||||
package com.stevesoltys.backup.service.backup
|
|
||||||
|
|
||||||
import android.app.backup.BackupManager
|
|
||||||
import android.app.backup.BackupManager.FLAG_NON_INCREMENTAL_BACKUP
|
|
||||||
import android.app.backup.BackupTransport.FLAG_USER_INITIATED
|
|
||||||
import android.app.job.JobParameters
|
|
||||||
import android.app.job.JobService
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Context.BACKUP_SERVICE
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.RemoteException
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.annotation.WorkerThread
|
|
||||||
import com.stevesoltys.backup.Backup
|
|
||||||
import com.stevesoltys.backup.NotificationBackupObserver
|
|
||||||
import com.stevesoltys.backup.service.PackageService
|
|
||||||
import com.stevesoltys.backup.session.backup.BackupMonitor
|
|
||||||
import com.stevesoltys.backup.transport.ConfigurableBackupTransportService
|
|
||||||
|
|
||||||
private val TAG = BackupJobService::class.java.name
|
|
||||||
|
|
||||||
// TODO might not be needed, if the OS really schedules backups on its own
|
|
||||||
class BackupJobService : JobService() {
|
|
||||||
|
|
||||||
override fun onStartJob(params: JobParameters): Boolean {
|
|
||||||
Log.i(TAG, "Triggering full backup")
|
|
||||||
try {
|
|
||||||
requestFullBackup(this)
|
|
||||||
} finally {
|
|
||||||
jobFinished(params, false)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStopJob(params: JobParameters): Boolean {
|
|
||||||
try {
|
|
||||||
Backup.backupManager.cancelBackups()
|
|
||||||
} catch (e: RemoteException) {
|
|
||||||
Log.e(TAG, "Error cancelling backup: ", e)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@WorkerThread
|
|
||||||
fun requestFullBackup(context: Context) {
|
|
||||||
context.startService(Intent(context, ConfigurableBackupTransportService::class.java))
|
|
||||||
val observer = NotificationBackupObserver(context, true)
|
|
||||||
val flags = FLAG_NON_INCREMENTAL_BACKUP or FLAG_USER_INITIATED
|
|
||||||
val packages = PackageService().eligiblePackages
|
|
||||||
val result = try {
|
|
||||||
Backup.backupManager.requestBackup(packages, observer, BackupMonitor(), flags)
|
|
||||||
} catch (e: RemoteException) {
|
|
||||||
// TODO show notification on backup error
|
|
||||||
Log.e(TAG, "Error during backup: ", e)
|
|
||||||
}
|
|
||||||
if (result == BackupManager.SUCCESS) {
|
|
||||||
Log.i(TAG, "Backup succeeded ")
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Backup failed: $result")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -48,16 +48,3 @@ fun setBackupPassword(context: Context, password: String) {
|
||||||
fun getBackupPassword(context: Context): String? {
|
fun getBackupPassword(context: Context): String? {
|
||||||
return getDefaultSharedPreferences(context).getString(PREF_KEY_BACKUP_PASSWORD, null)
|
return getDefaultSharedPreferences(context).getString(PREF_KEY_BACKUP_PASSWORD, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated("Our own scheduling will be removed")
|
|
||||||
fun setBackupsScheduled(context: Context) {
|
|
||||||
getDefaultSharedPreferences(context)
|
|
||||||
.edit()
|
|
||||||
.putBoolean(PREF_KEY_BACKUPS_SCHEDULED, true)
|
|
||||||
.apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated("Our own scheduling will be removed")
|
|
||||||
fun areBackupsScheduled(context: Context): Boolean {
|
|
||||||
return getDefaultSharedPreferences(context).getBoolean(PREF_KEY_BACKUPS_SCHEDULED, false)
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ import androidx.lifecycle.AndroidViewModel
|
||||||
import com.stevesoltys.backup.Backup
|
import com.stevesoltys.backup.Backup
|
||||||
import com.stevesoltys.backup.LiveEvent
|
import com.stevesoltys.backup.LiveEvent
|
||||||
import com.stevesoltys.backup.MutableLiveEvent
|
import com.stevesoltys.backup.MutableLiveEvent
|
||||||
import com.stevesoltys.backup.service.backup.requestFullBackup
|
|
||||||
import com.stevesoltys.backup.transport.ConfigurableBackupTransportService
|
import com.stevesoltys.backup.transport.ConfigurableBackupTransportService
|
||||||
|
import com.stevesoltys.backup.transport.requestBackup
|
||||||
|
|
||||||
private val TAG = SettingsViewModel::class.java.simpleName
|
private val TAG = SettingsViewModel::class.java.simpleName
|
||||||
|
|
||||||
|
@ -54,6 +54,6 @@ class SettingsViewModel(application: Application) : AndroidViewModel(application
|
||||||
Log.d(TAG, "New storage location chosen: $folderUri")
|
Log.d(TAG, "New storage location chosen: $folderUri")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun backupNow() = Thread { requestFullBackup(app) }.start()
|
fun backupNow() = Thread { requestBackup(app) }.start()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,21 @@
|
||||||
package com.stevesoltys.backup.transport
|
package com.stevesoltys.backup.transport
|
||||||
|
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
|
import android.app.backup.BackupManager
|
||||||
|
import android.app.backup.BackupTransport
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Context.BACKUP_SERVICE
|
||||||
|
import android.app.backup.BackupManager.FLAG_NON_INCREMENTAL_BACKUP
|
||||||
|
import android.app.backup.BackupTransport.FLAG_USER_INITIATED
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
|
import android.os.RemoteException
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.annotation.WorkerThread
|
||||||
|
import com.stevesoltys.backup.Backup
|
||||||
|
import com.stevesoltys.backup.NotificationBackupObserver
|
||||||
|
import com.stevesoltys.backup.service.PackageService
|
||||||
|
import com.stevesoltys.backup.session.backup.BackupMonitor
|
||||||
|
|
||||||
private val TAG = ConfigurableBackupTransportService::class.java.simpleName
|
private val TAG = ConfigurableBackupTransportService::class.java.simpleName
|
||||||
|
|
||||||
|
@ -35,3 +47,22 @@ class ConfigurableBackupTransportService : Service() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WorkerThread
|
||||||
|
fun requestBackup(context: Context) {
|
||||||
|
context.startService(Intent(context, ConfigurableBackupTransportService::class.java))
|
||||||
|
val observer = NotificationBackupObserver(context, true)
|
||||||
|
val flags = FLAG_NON_INCREMENTAL_BACKUP or FLAG_USER_INITIATED
|
||||||
|
val packages = PackageService().eligiblePackages
|
||||||
|
val result = try {
|
||||||
|
Backup.backupManager.requestBackup(packages, observer, BackupMonitor(), flags)
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
// TODO show notification on backup error
|
||||||
|
Log.e(TAG, "Error during backup: ", e)
|
||||||
|
}
|
||||||
|
if (result == BackupManager.SUCCESS) {
|
||||||
|
Log.i(TAG, "Backup succeeded ")
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Backup failed: $result")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ class KeyManagerTestImpl : KeyManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun storeBackupKey(seed: ByteArray) {
|
override fun storeBackupKey(seed: ByteArray) {
|
||||||
TODO("not implemented")
|
throw NotImplementedError("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hasBackupKey(): Boolean {
|
override fun hasBackupKey(): Boolean {
|
||||||
|
|
Loading…
Reference in a new issue