Git Product home page Git Product logo

restic-android's Introduction

restic-android (Unofficial)

build Release Notes Restic@IoD GNU General Public License, Version 2

Icon

This project aims to make Backups on Android easy and fast using Restic.

It also makes use of termux/proot to run the Restic linux binaries on android.

This project is still in a very early state and contributions are welcome!

Disclaimer

This project is not an official app made by the restic team.

Please report any issues on the restic-android issue tracker.

Features

  • Manage Restic Repositories (S3, B2, Rest are currently the only supported protocols)
  • Manage Restic Snapshots
  • Manage Folders for Backup
  • Configure Schedules for automatic Backups
  • Configure Cleanup Policies for Folders
  • Progress Notification

Roadmap

  • Clean up WIP Code
  • Support more protocols
  • More granular Backup Schedules and Cleanup Policies
  • Improve Error messages
  • Backup Rules (only backup when charging or only use wifi etc.)

Screenshots

Notice

See the file called NOTICE.

License

This project uses the GNU General Public License, Version 2. See the file called LICENSE.

restic-android's People

Contributors

dependabot[bot] avatar izzysoft avatar jpds avatar lhns avatar lolhens avatar marc31 avatar quantum-byte avatar shelliis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

restic-android's Issues

S3 region setting

The S3 repo options selection should also include a region setting.

Ignore patterns

It'd be great to exclude files that shouldn't be backed up (e.g. temporary files) through a text field or an ignore file through --exclude-file <folder to back up>/.resticignore.

Build signed apk

The unsigned apk that is currently published cannot be installed on other devices easily.

Notifications

This app should pop-up a notification access request when it first starts up.

Rclone support

Restic supports a whole bunch of services via rclone [1]. Perhaps we could support this by embedding rclone and accepting a custom path to rclone config file. Related to #20.

Allow unhiding credentials

The repository password, S3 access key and S3 secret key should be unhideable as these are usually long, and there's way for the user to verify they've inputted the correct thing.

please fix versionCode & versionName in APK

Your APKs all seem to still use the initial default version: versionCode 1 and versionName 1.0 โ€“ while the releases page already lists 5 releases (i.e. versionCode should be โ‰ฅ 5) with the latest one tagged "0.2.0" (suggesting a similar versionName). As this is not only a cosmetical thing (Android decides based on versionCode whether there's an update or not), could you please bring that "into sync"? For the easiest approach, you could use versionCode as a "release counter" (i.e. always increase it by 1), and use the tag name as versionName.

Thanks!

Restic error 1: Fatal: unable to open config file: Stat The difference between the request time and the server's time is too large. Is there a repository at the following location? s3:http://172.18.100.77:9000/android-test

I build apk from source, any wrong procedure I got error like this when at new repository:

Failed to initialize Repository

Failed to initialize Repository!

Restic error 1:
Fatal: create repository at s3:http//172.18.100.77:900/android-test failed: client.BucketExists: The difference between the request time and the server's time is too large.

Do you want to save anyway?

Cancel OK

I click OK, result:

android test
s3:http://172.18.100.77:9000/android-test

Snapshots
Restic error 1:
Fatal: unable to open config file: Stat The difference between the request time and the server's time is too large.
Is there a repository at the following location?
s3:http://172.18.100.77:9000/android-test

image

image

I have check the time client and server is match, and di url repository is correct.

Please help to solve build from source.

Thanks,

Eko

App Startup Crash

Hi everyone, i am experiencing direct crash of the app upon start. Only splash logo shows. This happens after upgrading to 0.4.2.1941* from 0.2.2.1941*, with universal and split-apk. Phone OS Graphene Android 13, Pixel 6.

The following report is in the crash details:

osVersion: google/oriole/oriole:13/TQ1A.230205.002/2023030400:user/release-keys
package: de.lolhens.resticui:1941588711
process: de.lolhens.resticui
processUptime: 249 + 886 ms

java.lang.RuntimeException: Unable to start activity ComponentInfo{de.lolhens.resticui/de.lolhens.resticui.MainActivity}: android.view.InflateException: Binary XML file line #32 in de.lolhens.resticui:layout/activity_main: Binary XML file line #32 in de.lolhens.resticui:layout/activity_main: Error inflating class fragment
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3646)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3783)
	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loopOnce(Looper.java:201)
	at android.os.Looper.loop(Looper.java:288)
	at android.app.ActivityThread.main(ActivityThread.java:7879)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
	at com.android.internal.os.ExecInit.main(ExecInit.java:49)
	at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
	at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:355)
Caused by: android.view.InflateException: Binary XML file line #32 in de.lolhens.resticui:layout/activity_main: Binary XML file line #32 in de.lolhens.resticui:layout/activity_main: Error inflating class fragment
Caused by: android.view.InflateException: Binary XML file line #32 in de.lolhens.resticui:layout/activity_main: Error inflating class fragment
Caused by: java.lang.SecurityException: Need android.permission.BLUETOOTH_CONNECT permission for android.content.AttributionSource@7deca34a: getName
	at android.os.Parcel.createExceptionOrNull(Parcel.java:3021)
	at android.os.Parcel.createException(Parcel.java:3005)
	at android.os.Parcel.readException(Parcel.java:2981)
	at android.os.Parcel.readException(Parcel.java:2923)
	at android.bluetooth.IBluetoothManager$Stub$Proxy.getName(IBluetoothManager.java:552)
	at android.bluetooth.BluetoothAdapter.getName(BluetoothAdapter.java:1573)
	at de.lolhens.resticui.util.HostnameUtil.detectHostname(HostnameUtil.kt:14)
	at de.lolhens.resticui.BackupManager.initRestic(BackupManager.kt:60)
	at de.lolhens.resticui.BackupManager.<init>(BackupManager.kt:208)
	at de.lolhens.resticui.BackupManager.<init>(Unknown Source:0)
	at de.lolhens.resticui.BackupManager$Companion.instance(BackupManager.kt:28)
	at de.lolhens.resticui.ui.folders.FoldersFragment.onCreateView(FoldersFragment.kt:32)
	at androidx.fragment.app.Fragment.performCreateView(Fragment.java:3104)
	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:524)
	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
	at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:113)
	at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1433)
	at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2977)
	at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2888)
	at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3129)
	at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:394)
	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:260)
	at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:142)
	at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:136)
	at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:248)
	at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:227)
	at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1073)
	at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:1001)
	at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:965)
	at android.view.LayoutInflater.rInflate(LayoutInflater.java:1127)
	at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1088)
	at android.view.LayoutInflater.inflate(LayoutInflater.java:686)
	at android.view.LayoutInflater.inflate(LayoutInflater.java:538)
	at de.lolhens.resticui.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:49)
	at de.lolhens.resticui.databinding.ActivityMainBinding.inflate(ActivityMainBinding.java:43)
	at de.lolhens.resticui.MainActivity.onCreate(MainActivity.kt:20)
	at android.app.Activity.performCreate(Activity.java:8352)
	at android.app.Activity.performCreate(Activity.java:8331)
	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1422)
	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3627)
	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3783)
	at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:101)
	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308)
	at android.os.Handler.dispatchMessage(Handler.java:106)
	at android.os.Looper.loopOnce(Looper.java:201)
	at android.os.Looper.loop(Looper.java:288)
	at android.app.ActivityThread.main(ActivityThread.java:7879)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
	at com.android.internal.os.ExecInit.main(ExecInit.java:49)
	at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
	at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:355)
Caused by: android.os.RemoteException: Remote stack trace:
	at com.android.server.bluetooth.BluetoothManagerService.checkPermissionForDataDelivery(BluetoothManagerService.java:3239)
	at com.android.server.bluetooth.BluetoothManagerService.checkConnectPermissionForDataDelivery(BluetoothManagerService.java:3257)
	at com.android.server.bluetooth.BluetoothManagerService.getName(BluetoothManagerService.java:1942)
	at android.bluetooth.IBluetoothManager$Stub.onTransact(IBluetoothManager.java:256)
	at android.os.Binder.execTransactInternal(Binder.java:1302)

If somebody has an idea how to fix this, I would appreciate a lot!

lib/arm64/proot: No such file or directory

/data/app/.../lib/arm64/proot: No such file or directory

Despite android:extractNativeLibs="true" the libs are not extracted when installing the apk in production environments.

Backup rules

  • only backup with WiFi connection
  • only backup when charging

Saving repo configuration downloads large amount of snapshots

I had to reinstall this app and upon saving my S3 configuration - a large amount of data was downloaded in order to display the available snapshots in the repo in the next view.

If the app is closed whilst this process is happening - then the entire thing has to be repeated.

It's probably better if there was a way to save the configuration and asynchronously load the snapshots in the background.

[Feature request] Update Restic 0.14.0

Restic 0.14.0 includes several improvements and new features.
https://github.com/restic/restic/releases/tag/v0.14.0

The most important change is from version 0.14.0 they bumped the repository version to 2. Version 2 is the default and version 1 is still compatible but it doesn't support new features like compression.

That means this app is not working with repositories v2 (created with Restic .14.0)

Here is info about the migration to v2 => https://restic.readthedocs.io/en/stable/045_working_with_repos.html#upgrading-the-repository-format-version

Problem connecting S3 repository

Screenshot_20211117-100127
Screenshot_20211117-100239
:

Using APK from Release 4 with Android 11 (same with Release 3)
ACCESS_KEY and SECURITY_KEY are correct and working (for example with a RaspberryPi).
Repository does not yet exist.
Error does appears after several minutes of showing progress animation when saving the repository configuration.

Anything I can do?

self-signed certificat / insecure-tls

Thanks for the grate app.
Is there a way to add optional flags like --insecure-tls to use a self-signed certificat? If I'm blind and there ja a was please tell me where I can find it.

Thanks and keep up the great work.

wrong APK attached to release 0.3.0?

The APK attached to release 0.3.0 identifies as

package: name='de.lolhens.resticui' versionCode='1941588398' versionName='0.2.2'

Could you please replace it by the correct one? Or is a new release already pending (0.3.0 was about a year ago)? Thanks in advance!

Missing information regarding how jniLibs are build or commited to repository

Discussed in #145

Originally posted by aamirmohammedhussain March 31, 2023
Hi all

I was just going through the code base

But i couldn't find git action workflow or any information regarding how the jniLibs located at [main/app/src/main/jniLibs](https://github.com/lhns/restic-android/tree/main/app/src/main/jniLibs is build or commited to repository.
)

  1. libdata_libtalloc.so.2.so
  2. libdata_loader.so
  3. libdata_loader32.so
  4. libdata_proot.so
  5. libdata_restic.so

Is there anything i am missing?

Hope you could help me figure out

Immediate crash

When launching restic-android-0.4.6-arm64-v8a-release.apk I get an immediate crash
Here is the full stacktrace https://paste.evolution-x.org/qT8V7x

android.security.KeyStoreException: Signature/MAC verification failed (internal Keystore code: -30 message: In KeystoreOperation::finish

I also tried the universal binary, same thing.

My phone is running Evolution X which is an Android 13 based custom ROM.

Backup schedule timing

How do you control what time the backup runs when you select daily/weekly/etc? I've just started using this to backup my phone, and I'm running into issues with Restic sometimes running before the apps I'm backing up generate their daily backups. I can control what time they generate the backup files, so I don't necessarily need to be able to control the time, but I do need it to be consistent and known so I can schedule around it.

Publish different android ABI artifacts to the IzzyOnDroid Repo for F-Droid Package Managers etc.

Hi @lhns

up until now i always used F-Droid and the IzzyOnDroid package repo to install restic-android. But my new Phone uses the arm64-v8a ABI exclusively. At the moment though you only seem to publish packages/artifacts of restic-android with armeabi-v7a to the repo.

I was able to manually download and install the restic-android-0.4.6-arm64-v8a-release.apk version just fine. Would it be possible to publish this or - i assume - the "Universal" package/artifact to the IzzyOnDroid repo ?

Thanks and have a nice day :)!

Folder Backup Rule "Delete content after successful snapshot"

I see a use case where i want restic-android to delete the contents of the folder once it made a successful snapshot of it.

For example my Mi9 has a way to backup app and os settings and i can configure it to create a backup file each day but it does not allow me to only keep backup files for the last 7 days. So they just accumulate until i manually delete them.

Through this feature they would be automatically deleted locally once a successful snapshot has been taken. This combines really well with the "folder retain for x days" feature.

Binary blobs

This repo contains binary *.so libraries of restic, proot, libtalloc commited here

how do you create these binary blobs?

it looks like at least proot is licensed under GPL, which might cause some issues. i'm not a lawyer but i suspect you have to at least provide the source (or refer to it) your binary was built from :p

it's also not great since updating those binaries in the git tree will bloat the size of the checkout, since git keeps copies of the old revisions around.

Retain days, weeks, months, years

I like to keep many backups of the last few days, but only a few of the last years. restic supports retaining a different number of backups for the last days, weeks, months and years via --keep-daily, --keep-weekly, --keep-monthly and --keep-yearly. The app currently seems to only support --keep-daily. It'd be great if you could also add the other options. ๐Ÿ™

Feature request: root access

My phone is rooted (through Magisk) and I'd like to backup some directories on my phone that aren't available through the normal Android APIs, such as my Termux home directory at /data/data/com.termux/files/home (well, the file picker actually allows me to pick this directory, but it crashes restic-android) or my WhatsApp media at /sdcard/Android/media/com.whatsapp.

Would it be possible to support root access to back up directories like these?

Storage backend logos

Tiny UI suggestions, but the repositories page should have a storage backend logo next to the name of the repo.

Bugs creating folders and syncthing

Trying this on samsung fold4

  1. Creating folders won't save folder

  2. Creating repo won't save repo.

  3. No option for local storage repo

End result I can't use this at all.

Any advice please?

[Feature request] Support multiple folders in the same backup

First of all, thank you for this amazing App. Its the best app I have found for Restic / Android. You should publish it in the marketplaces, it will be more visible.

I have a smartphone with Android 13. The app is working well but the configuration is a bit more complicate than it should be.

Use case: I want to backup all the files in my phone. I can't not select the main folder of my phone (where DCIM and Android folders are) because privacy or permissions. I don't care about permissions but Android don't let me.
To solve this I'm creating different backups. One for DCIM, one for Android folder... It works but instead of having 1 backup, I have a lot of different backups and if I want to restore my phone I have to restore many backups one by one.

My proposals:

  1. Find a way to select the main folder. I don't see the reason it's not allowed. This will be perfect combined with #86
  2. Allow the user to select more than one folder in each backup. Convert the folder path into a list with multiple paths. All files from all paths will be included in the same backup. It's supported by Restic using restic ... backup folder1 folder2 ... Another way of doing the same is => https://restic.readthedocs.io/en/stable/040_backup.html#including-files

Release 0.4.5 without icon

I just installed restic-android-0.4.5-arm64-v8a-release.apk (downloaded from GitHub) in Android 12 and I see a "green droid icon". Is that expected?

Crash on Android 12 when starting backup

When I select a folder to backup and press the Backup button the app crashes like this:

FATAL EXCEPTION: main
Process: de.lolhens.resticui, PID: 1886
java.lang.IllegalArgumentException: de.lolhens.resticui: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
  at android.app.PendingIntent.checkFlags(PendingIntent.java:377)
  at android.app.PendingIntent.getActivityAsUser(PendingIntent.java:460)
  at android.app.PendingIntent.getActivity(PendingIntent.java:446)
  at android.app.PendingIntent.getActivity(PendingIntent.java:410)
  at de.lolhens.resticui.BackupManager.updateNotification$pendingIntent(BackupManager.kt:97)
  at de.lolhens.resticui.BackupManager.updateNotification(BackupManager.kt:118)
  at de.lolhens.resticui.BackupManager.updateNotification$default(BackupManager.kt:90)
  at de.lolhens.resticui.BackupManager.backup(BackupManager.kt:248)
  at de.lolhens.resticui.BackupManager.backup$default(BackupManager.kt:231)
  at de.lolhens.resticui.ui.folder.FolderFragment.onCreateView$lambda$6(FolderFragment.kt:208)
  at de.lolhens.resticui.ui.folder.FolderFragment.$r8$lambda$5ujabiUaNEHzHkmV9aEW9wPM-dc(Unknown Source:0)
  at de.lolhens.resticui.ui.folder.FolderFragment$$ExternalSyntheticLambda5.onClick(Unknown Source:4)
  at android.view.View.performClick(View.java:7467)
  at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1202)
  at android.view.View.performClickInternal(View.java:7444)
  at android.view.View.access$3700(View.java:840)
  at android.view.View$PerformClick.run(View.java:28830)
  at android.os.Handler.handleCallback(Handler.java:978)
  at android.os.Handler.dispatchMessage(Handler.java:104)
  at android.os.Looper.loopOnce(Looper.java:238)
  at android.os.Looper.loop(Looper.java:357)
  at android.app.ActivityThread.main(ActivityThread.java:8089)
  at java.lang.reflect.Method.invoke(Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1026)

Seems like you need to add FLAG_IMMUTABLE to your PendingIntents.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.