From 8a4d4b084d9ad1fb133eac2e483a7035d00bac09 Mon Sep 17 00:00:00 2001 From: Shahriar Zaman Date: Mon, 10 Apr 2023 13:09:04 +0600 Subject: [PATCH 1/3] - api 19 supported - Threads are replaced with lifecycle aware executor services --- .idea/.name | 1 + app/build.gradle | 8 +- app/src/main/AndroidManifest.xml | 3 +- .../java/com/tos/drivebackup/MainActivity.kt | 7 +- .../drive_backup/DriveBackupUtils.kt | 4 - app/src/main/res/layout/main_activity.xml | 2 +- libDriveBackup/build.gradle | 6 +- .../GoogleDriveBackupManager.kt | 67 ++- .../libdrivebackup/useCase/GetCredential.kt | 2 +- .../uqab/libdrivebackup/util/FileUtils.java | 465 ------------------ .../media/uqab/libdrivebackup/util/Helper.kt | 17 - 11 files changed, 72 insertions(+), 510 deletions(-) create mode 100644 .idea/.name delete mode 100644 libDriveBackup/src/main/java/media/uqab/libdrivebackup/util/FileUtils.java delete mode 100644 libDriveBackup/src/main/java/media/uqab/libdrivebackup/util/Helper.kt diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..8ab1629 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +DriveBackup \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 1182772..6052c24 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,11 +9,13 @@ android { defaultConfig { applicationId "com.tos.drivebackup" - minSdk 21 + minSdk 19 targetSdk 33 versionCode 1 versionName "1.0" + multiDexEnabled true + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary true @@ -50,6 +52,8 @@ dependencies { implementation 'com.google.android.material:material:1.8.0' implementation 'com.google.code.gson:gson:2.10.1' + implementation "androidx.multidex:multidex:2.0.1" + implementation project(':libDriveBackup') -// implementation 'com.github.fcat97:driveBackupApi:1.0.5' +// implementation 'com.github.fcat97:driveBackupApi:1.0.6' } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7462378..7884786 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,7 +5,8 @@ diff --git a/libDriveBackup/build.gradle b/libDriveBackup/build.gradle index 2f421d6..14b838e 100644 --- a/libDriveBackup/build.gradle +++ b/libDriveBackup/build.gradle @@ -9,7 +9,7 @@ android { compileSdk 33 defaultConfig { - minSdk 21 + minSdk 19 targetSdk 33 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -40,7 +40,7 @@ dependencies { implementation 'com.google.auth:google-auth-library-oauth2-http:1.16.0' implementation 'com.google.api-client:google-api-client-android:2.2.0' - implementation 'com.google.android.gms:play-services-auth:20.4.1' + implementation 'com.google.android.gms:play-services-auth:20.5.0' } @@ -50,7 +50,7 @@ afterEvaluate { publications { maven(MavenPublication) { group = 'media.uqab.driveBackupApi' - version = '1.0.5' + version = '1.0.6' artifactId = "driveBackupApi" from components.release diff --git a/libDriveBackup/src/main/java/media/uqab/libdrivebackup/GoogleDriveBackupManager.kt b/libDriveBackup/src/main/java/media/uqab/libdrivebackup/GoogleDriveBackupManager.kt index 5cacbdc..203fbc6 100644 --- a/libDriveBackup/src/main/java/media/uqab/libdrivebackup/GoogleDriveBackupManager.kt +++ b/libDriveBackup/src/main/java/media/uqab/libdrivebackup/GoogleDriveBackupManager.kt @@ -1,21 +1,23 @@ package media.uqab.libdrivebackup -import android.Manifest import android.app.Activity import android.content.Intent import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver +import androidx.lifecycle.LifecycleOwner import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential import media.uqab.libdrivebackup.model.* -import media.uqab.libdrivebackup.model.Constants import media.uqab.libdrivebackup.useCase.* import media.uqab.libdrivebackup.useCase.GetCredential.getCredential import media.uqab.libdrivebackup.useCase.GetOneTapSignInIntent.getSignInIntent import java.io.File import java.io.FileOutputStream import java.util.* +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors /** * A manager class to view, update, delete and modify @@ -34,19 +36,33 @@ import java.util.* class GoogleDriveBackupManager( appID: String, private val activity: ComponentActivity, - private val credentialID: String, + private val credentialID: String ) { init { if (activity.lifecycle.currentState != Lifecycle.State.INITIALIZED) { throw InitializationException("Must initialize before OnStart but initialized in ${activity.lifecycle.currentState}") } + // attach an observer to cancel all running executor services + activity.lifecycle.addObserver(object : LifecycleEventObserver { + override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) { + if (event == Lifecycle.Event.ON_DESTROY) { + _executor?.shutdown() + } + } + }) + if (credentialID.isBlank()) throw InitializationException("Credential ID not provided") if (appID.isEmpty()) throw InitializationException("App Name not provided") Constants.APP_NAME = appID } + /** + * A single threaded executor to run all the background tasks + */ + private var _executor: ExecutorService? = null + /** * Run this block when user grants drive uses permission. Must be set before * each operation. @@ -86,7 +102,7 @@ class GoogleDriveBackupManager( onFailed: ((Exception) -> Unit)? = null, result: (List) -> Unit ) = requestConsentAndProceed(onFailed) { - Thread { + execute(onFailed) { try { val files = GetFiles.getFiles(it).files.map { FileInfo( @@ -110,7 +126,7 @@ class GoogleDriveBackupManager( onFailed?.invoke(e) } } - }.start() + } } /** @@ -125,7 +141,7 @@ class GoogleDriveBackupManager( onFailed: ((Exception) -> Unit)? = null, result: (FileInfo) -> Unit ) = requestConsentAndProceed(onFailed) { c -> - Thread { + execute(onFailed) { try { val file = GetFile.getFile(fileID, c).let { FileInfo( @@ -145,7 +161,7 @@ class GoogleDriveBackupManager( onFailed?.invoke(e) } } - }.start() + } } /** @@ -157,7 +173,7 @@ class GoogleDriveBackupManager( onFailed: ((Exception) -> Unit)? = null, onUpload: (fileID: String) -> Unit ) = requestConsentAndProceed(onFailed) { - Thread { + execute(onFailed) { try { val fileID = UploadAppData.uploadAppData(it, file, mimeType) @@ -170,7 +186,7 @@ class GoogleDriveBackupManager( onFailed?.invoke(e) } } - }.start() + } } /** @@ -188,7 +204,7 @@ class GoogleDriveBackupManager( onFailed: ((Exception) -> Unit)? = null, onDownload: (File) -> Unit ) = requestConsentAndProceed(onFailed) { - Thread { + execute(onFailed) { val fos = FileOutputStream(outputFile) try { val baOs = DownloadFile.downloadFile(it, fileID) @@ -207,7 +223,7 @@ class GoogleDriveBackupManager( } finally { fos.close() } - }.start() + } } /** @@ -220,7 +236,7 @@ class GoogleDriveBackupManager( onFailed: ((Exception) -> Unit)? = null, onCreate: (String) -> Unit ) = requestConsentAndProceed(onFailed) { - Thread { + execute(onFailed) { try { val folderID = CreateRootFolder.create(it) activity.runOnUiThread { @@ -233,7 +249,7 @@ class GoogleDriveBackupManager( onFailed?.invoke(e) } } - }.start() + } } /** @@ -247,7 +263,7 @@ class GoogleDriveBackupManager( onFailed: ((Exception) -> Unit)? = null, onDelete: () -> Unit ) = requestConsentAndProceed(onFailed) { - Thread { + execute(onFailed) { try { DeleteFile.delete(it, fileID) activity.runOnUiThread { @@ -259,7 +275,7 @@ class GoogleDriveBackupManager( } Log.w(TAG, "failed to delete file $fileID", e) } - }.start() + } } fun signOut( @@ -330,6 +346,27 @@ class GoogleDriveBackupManager( consentLauncher.launch(signInIntent) } + /** + * Execute the task on the executor. + * + */ + private fun execute(onFailed: ((Exception) -> Unit)?, task: Runnable) { + try { + getExecutor().submit(task) + } catch (e: Exception) { + activity.runOnUiThread { + onFailed?.invoke(e) + } + } + } + + private fun getExecutor(): ExecutorService { + if (_executor == null) _executor = Executors.newSingleThreadExecutor() + else if (_executor!!.isTerminated) _executor = Executors.newSingleThreadExecutor() + + return _executor!! + } + companion object { private const val TAG = "BackupManager" } diff --git a/libDriveBackup/src/main/java/media/uqab/libdrivebackup/useCase/GetCredential.kt b/libDriveBackup/src/main/java/media/uqab/libdrivebackup/useCase/GetCredential.kt index 1d72381..39d9efb 100644 --- a/libDriveBackup/src/main/java/media/uqab/libdrivebackup/useCase/GetCredential.kt +++ b/libDriveBackup/src/main/java/media/uqab/libdrivebackup/useCase/GetCredential.kt @@ -44,7 +44,7 @@ internal object GetCredential { return credential } catch (e: Exception) { if(e is ApiException && e.statusCode == 10) { - Log.e(TAG, "Not configured properly. Maybe you used wrong credential.") + Log.e(TAG, "GCP not configured properly. Maybe you used wrong credential ID or wrong SHA-1.") } else { Log.e(TAG, "Failed to get credential", e) } diff --git a/libDriveBackup/src/main/java/media/uqab/libdrivebackup/util/FileUtils.java b/libDriveBackup/src/main/java/media/uqab/libdrivebackup/util/FileUtils.java deleted file mode 100644 index 3e23a9e..0000000 --- a/libDriveBackup/src/main/java/media/uqab/libdrivebackup/util/FileUtils.java +++ /dev/null @@ -1,465 +0,0 @@ -package media.uqab.libdrivebackup.util; - -import android.annotation.SuppressLint; -import android.content.ContentResolver; -import android.content.ContentUris; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.Build; -import android.os.Environment; -import android.provider.DocumentsContract; -import android.provider.MediaStore; -import android.provider.OpenableColumns; -import android.text.TextUtils; -import android.util.Log; - -import androidx.documentfile.provider.DocumentFile; - -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.UUID; - -/** - * @author github/fCat97 - */ -class FileUtils { - public static String a = "upload_part"; - - private static String b = "FileUtils"; - - private static Uri c = null; - - Context d; - - public FileUtils(Context context) { - this.d = context; - } - - @SuppressLint("NewApi") - public String getPath(final Uri uri) { - // check here to KITKAT or new version - final boolean kp = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; - String ut = null; - String[] no = null; - final Uri o = uri; - // DocumentProvider - - if (kp) { - // ExternalStorageProvider - - if (u(o)) { - final String di = DocumentsContract.getDocumentId(o); - final String[] po = di.split(":"); - final String tp = po[0]; - - String fp = t(po); - - if (fp == null || !u(fp)) { - Log.d(b, "Copy files as a fallback"); - fp = c(o, a); - } - - if (fp != "") { - return fp; - } else { - return null; - } - } - - - // DownloadsProvider - - if (k(o)) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - final String yt; - Cursor cursor = null; - try { - cursor = d.getContentResolver().query(o, new String[] { - MediaStore.MediaColumns.DISPLAY_NAME - }, null, null, null); - if (cursor != null && cursor.moveToFirst()) { - String ni = cursor.getString(0); - String ac = Environment.getExternalStorageDirectory().toString() + "/Download/" + ni; - if (!TextUtils.isEmpty(ac)) { - return ac; - } - } - } finally { - if (cursor != null) - cursor.close(); - } - yt = DocumentsContract.getDocumentId(o); - - if (!TextUtils.isEmpty(yt)) { - if (yt.startsWith("raw:")) { - return yt.replaceFirst("raw:", ""); - } - String[] db = new String[] { - "content://downloads/public_downloads", - "content://downloads/my_downloads" - }; - - for (String contentUriPrefix: db) { - try { - final Uri b = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(yt)); - - return n(d, b, null, null); - } catch (NumberFormatException e) { - //In Android 8 and Android P the id is not a number - return o.getPath().replaceFirst("^/document/raw:", "").replaceFirst("^raw:", ""); - } - } - } - } else { - final String id = DocumentsContract.getDocumentId(o); - - if (id.startsWith("raw:")) { - return id.replaceFirst("raw:", ""); - } - try { - c = ContentUris.withAppendedId( - Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); - } catch (NumberFormatException e) { - e.printStackTrace(); - } - - if (c != null) - return n(d, c, null, null); - } - } - - - // MediaProvider - if (m(o)) { - final String docId = DocumentsContract.getDocumentId(o); - final String[] split = docId.split(":"); - final String type = split[0]; - - Log.d(b, "MEDIA DOCUMENT TYPE: " + type); - - Uri contentUri = null; - - if ("image".equals(type)) { - contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; - } else if ("video".equals(type)) { - contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; - } else if ("audio".equals(type)) { - contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; - } else if ("document".equals(type)) { - contentUri = MediaStore.Files.getContentUri(MediaStore.getVolumeName(o)); - } - - ut = "_id=?"; - no = new String[] { - split[1] - }; - - - return n(d, contentUri, ut, no); - } - - if (d(o)) { - return b(o); - } - - if (w(o)) { - return l(o); - } - - if ("content".equalsIgnoreCase(o.getScheme())) { - if (p(o)) { - return o.getLastPathSegment(); - } - - if (d(o)) { - return b(o); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - // return getFilePathFromURI(context,uri); - return c(o, a); - // return getRealPathFromURI(context,uri); - } else { - return n(d, o, null, null); - } - - } - - if ("file".equalsIgnoreCase(o.getScheme())) { - return o.getPath(); - } - } else { - if (w(o)) { - return l(o); - } - - if ("content".equalsIgnoreCase(o.getScheme())) { - String[] projection = { - MediaStore.Images.Media.DATA - }; - Cursor cursor = null; - - try { - cursor = d.getContentResolver() - .query(o, projection, ut, no, null); - int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); - - if (cursor.moveToFirst()) { - return cursor.getString(column_index); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - return c(o, a); - } - - public File copyToAppsDir(final Uri uri, @Nullable final String parentDir) { - File copiedFile = null; - - // Read the contents of the file using a ContentResolver - ContentResolver resolver = d.getContentResolver(); - try (InputStream inputStream = resolver.openInputStream(uri)) { - // Convert the URI to a DocumentFile - DocumentFile documentFile = DocumentFile.fromSingleUri(d, uri); - - // Create a new File object - File outputFile; - if (parentDir == null) { - outputFile = new File(d.getExternalFilesDir(null), documentFile.getName()); - } else { - File parentFolder = new File(parentDir); - if (!parentFolder.exists()) parentFolder.mkdirs(); - - outputFile = new File(parentDir, documentFile.getName()); - } - - // Write the contents of the InputStream to the new file - try (FileOutputStream outputStream = new FileOutputStream(outputFile)) { - byte[] buffer = new byte[1024]; - int read; - while ((read = inputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, read); - } - outputStream.flush(); - } catch (IOException e) { - throw new RuntimeException(e); - } - - // The file is now available as a java.io.File object - copiedFile = outputFile; - } catch (Exception e) { - // Handle the exception - Log.e(b, "copyToAppsDir: ", e); - } - - return copiedFile; - } - - private static boolean u(String hg) { - File file = new File(hg); - - return file.exists(); - } - - private static String t(String[] g) { - final String i = g[0]; - final String p = File.separator + g[1]; - String f = ""; - - - Log.d(b, "MEDIA EXTSD TYPE: " + i); - Log.d(b, "Relative path: " + p); - // on my Sony devices (4.4.4 & 5.1.1), `type` is a dynamic string - // something like "71F8-2C0A", some kind of unique id per storage - // don't know any API that can get the root path of that storage based on its id. - // - // so no "primary" type, but let the check here for other devices - if ("primary".equalsIgnoreCase(i)) { - f = Environment.getExternalStorageDirectory() + p; - if (u(f)) { - return f; - } - } - - if ("home".equalsIgnoreCase(i)) { - f = "/storage/emulated/0/Documents" + p; - if (u(f)) { - return f; - } - } - - // Environment.isExternalStorageRemovable() is `true` for external and internal storage - // so we cannot relay on it. - // - // instead, for each possible path, check if file exists - // we'll start with secondary storage as this could be our (physically) removable sd card - f = System.getenv("SECONDARY_STORAGE") + p; - if (u(f)) { - return f; - } - - f = System.getenv("EXTERNAL_STORAGE") + p; - if (u(f)) { - return f; - } - - return null; - } - - private String b(Uri bn) { - Uri v = bn; - Cursor returnCursor = d.getContentResolver().query(v, null, null, null, null); - /* - * Get the column indexes of the data in the Cursor, - * * move to the first row in the Cursor, get the data, - * * and display it. - * */ - int c = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); - int e = returnCursor.getColumnIndex(OpenableColumns.SIZE); - returnCursor.moveToFirst(); - String l = (returnCursor.getString(c)); - String z = (Long.toString(returnCursor.getLong(e))); - File a = new File(d.getCacheDir(), l); - try { - InputStream q = d.getContentResolver().openInputStream(bn); - FileOutputStream w = new FileOutputStream(a); - int ll = 0; - int pp = 1 * 1024 * 1024; - int mm = q.available(); - - //int bufferSize = 1024; - int ii = Math.min(mm, pp); - - final byte[] ss = new byte[ii]; - while ((ll = q.read(ss)) != -1) { - w.write(ss, 0, ll); - } - Log.e(b, "Size " + a.length()); - q.close(); - w.close(); - Log.e(b, "Path " + a.getPath()); - Log.e(b, "Size " + a.length()); - } catch (Exception ex) { - Log.e(b, ex.getMessage()); - } - - return a.getPath(); - } - - /*** - * Used for Android Q+ - * @param po - * @param cv if you want to create a directory, you can set this variable - * @return - */ - private String c(Uri po, String cv) { - Uri rr = po; - - Cursor uu = d.getContentResolver().query(rr, new String[] { - OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE - }, null, null, null); - - - /* - * Get the column indexes of the data in the Cursor, - * * move to the first row in the Cursor, get the data, - * * and display it. - * */ - int qq = uu.getColumnIndex(OpenableColumns.DISPLAY_NAME); - int ss = uu.getColumnIndex(OpenableColumns.SIZE); - uu.moveToFirst(); - String hh = (uu.getString(qq)); - String kk = (Long.toString(uu.getLong(ss))); - - File nn; - if (!cv.equals("")) { - String oo = UUID.randomUUID().toString(); - - File ii = new File(d.getFilesDir() + File.separator + cv + File.separator + oo); - if (!ii.exists()) { - ii.mkdirs(); - } - nn = new File(d.getFilesDir() + File.separator + cv + File.separator + oo + File.separator + hh); - } else { - nn = new File(d.getFilesDir() + File.separator + hh); - } - - try { - InputStream vv = d.getContentResolver().openInputStream(po); - FileOutputStream jj = new FileOutputStream(nn); - int dd = 0; - int op = 1024; - final byte[] buffers = new byte[op]; - - while ((dd = vv.read(buffers)) != -1) { - jj.write(buffers, 0, dd); - } - - vv.close(); - jj.close(); - } catch (Exception e) { - Log.e(b, e.getMessage()); - } - - return nn.getPath(); - } - - private String l(Uri kj) { - return c(kj, "whatsapp"); - } - - private String n(Context vv, Uri lo, String jn, String[] tr) { - Cursor cursor = null; - final String column = "_data"; - final String[] projection = { - column - }; - - try { - cursor = vv.getContentResolver().query(lo, projection, - jn, tr, null); - - if (cursor != null && cursor.moveToFirst()) { - final int index = cursor.getColumnIndexOrThrow(column); - return cursor.getString(index); - } - } finally { - if (cursor != null) - cursor.close(); - } - - return null; - } - - private static boolean u(Uri yh) { - return "com.android.externalstorage.documents".equals(yh.getAuthority()); - } - - private static boolean k(Uri cj) { - return "com.android.providers.downloads.documents".equals(cj.getAuthority()); - } - - private boolean m(Uri io) { - return "com.android.providers.media.documents".equals(io.getAuthority()); - } - - private boolean p(Uri nr) { - return "com.google.android.apps.photos.content".equals(nr.getAuthority()); - } - - public boolean w(Uri qw) { - return "com.whatsapp.provider.media".equals(qw.getAuthority()); - } - - private boolean d(Uri xc) { - return "com.google.android.apps.docs.storage".equals(xc.getAuthority()) || "com.google.android.apps.docs.storage.legacy".equals(xc.getAuthority()); - } -} \ No newline at end of file diff --git a/libDriveBackup/src/main/java/media/uqab/libdrivebackup/util/Helper.kt b/libDriveBackup/src/main/java/media/uqab/libdrivebackup/util/Helper.kt deleted file mode 100644 index 02e4acd..0000000 --- a/libDriveBackup/src/main/java/media/uqab/libdrivebackup/util/Helper.kt +++ /dev/null @@ -1,17 +0,0 @@ -package media.uqab.libdrivebackup.util - -import android.content.Context -import android.net.Uri -import java.io.File - -object Helper { - fun Uri?.toFile(context: Context): File? = try { - if (this == null) { - null - } else { - FileUtils(context).copyToAppsDir(this, null) - } - } catch (e: Exception) { - null - } -} \ No newline at end of file From 1f54e567dfd3a26ddb285613cde18be2133f1bce Mon Sep 17 00:00:00 2001 From: Shahriar Zaman Date: Wed, 12 Apr 2023 12:38:01 +0600 Subject: [PATCH 2/3] - [fix] java.lang.NoClassDefFoundError: com.google.common.base.CharMatcher --- app/build.gradle | 2 +- .../java/com/tos/drivebackup/MainActivity.kt | 3 +-- build.gradle | 2 +- libDriveBackup/build.gradle | 18 ++++++++++++------ 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 6052c24..a4a7891 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -55,5 +55,5 @@ dependencies { implementation "androidx.multidex:multidex:2.0.1" implementation project(':libDriveBackup') -// implementation 'com.github.fcat97:driveBackupApi:1.0.6' +// implementation 'com.github.fcat97:driveBackupApi:1.0.7' } \ No newline at end of file diff --git a/app/src/main/java/com/tos/drivebackup/MainActivity.kt b/app/src/main/java/com/tos/drivebackup/MainActivity.kt index d562f74..619ea06 100644 --- a/app/src/main/java/com/tos/drivebackup/MainActivity.kt +++ b/app/src/main/java/com/tos/drivebackup/MainActivity.kt @@ -9,14 +9,12 @@ import androidx.activity.ComponentActivity import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatDelegate import androidx.lifecycle.MutableLiveData -import androidx.multidex.BuildConfig import com.google.android.material.color.DynamicColors import com.google.android.material.textfield.TextInputEditText import com.tos.drivebackup.drive_backup.DriveBackupUtils import media.uqab.libdrivebackup.GoogleDriveBackupManager import java.io.File import java.io.FileReader -import java.util.concurrent.Executors class MainActivity : ComponentActivity() { companion object { @@ -113,6 +111,7 @@ class MainActivity : ComponentActivity() { private fun fetchFiles() { googleDriveBackupManager.getFiles { + Log.d(TAG, "fetchFiles: ${it.joinToString(separator = "\n")}") printToTerminal("[backups]: \n" + it.joinToString(separator = "\n\n")) } } diff --git a/build.gradle b/build.gradle index 0a5c93e..85f1717 100644 --- a/build.gradle +++ b/build.gradle @@ -7,5 +7,5 @@ buildscript { plugins { id 'com.android.application' version '7.3.1' apply false id 'com.android.library' version '7.3.1' apply false - id 'org.jetbrains.kotlin.android' version '1.6.10' apply false + id 'org.jetbrains.kotlin.android' version '1.8.10' apply false } \ No newline at end of file diff --git a/libDriveBackup/build.gradle b/libDriveBackup/build.gradle index 14b838e..38a3981 100644 --- a/libDriveBackup/build.gradle +++ b/libDriveBackup/build.gradle @@ -35,12 +35,18 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.documentfile:documentfile:1.0.1' - implementation 'com.google.api-client:google-api-client:2.2.0' - implementation 'com.google.apis:google-api-services-drive:v3-rev20220815-2.0.0' - implementation 'com.google.auth:google-auth-library-oauth2-http:1.16.0' + implementation('com.google.api-client:google-api-client:2.2.0') + implementation('com.google.apis:google-api-services-drive:v3-rev20220815-2.0.0') + implementation('com.google.auth:google-auth-library-oauth2-http:1.16.0') + implementation('com.google.api-client:google-api-client-android:2.2.0') + implementation('com.google.android.gms:play-services-auth:20.5.0') - implementation 'com.google.api-client:google-api-client-android:2.2.0' - implementation 'com.google.android.gms:play-services-auth:20.5.0' + // https://stackoverflow.com/a/71085378/8229399 + implementation("com.google.guava:guava") { + version { + strictly '31.1-android' + } + } } @@ -50,7 +56,7 @@ afterEvaluate { publications { maven(MavenPublication) { group = 'media.uqab.driveBackupApi' - version = '1.0.6' + version = '1.0.7' artifactId = "driveBackupApi" from components.release From e36de01f997dc3c2c899fca6ed97b4da50a8c6f3 Mon Sep 17 00:00:00 2001 From: Shahriar Zaman Date: Wed, 12 Apr 2023 13:08:37 +0600 Subject: [PATCH 3/3] - [fix] parameters obfuscated --- build.gradle | 2 +- libDriveBackup/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 85f1717..0a5c93e 100644 --- a/build.gradle +++ b/build.gradle @@ -7,5 +7,5 @@ buildscript { plugins { id 'com.android.application' version '7.3.1' apply false id 'com.android.library' version '7.3.1' apply false - id 'org.jetbrains.kotlin.android' version '1.8.10' apply false + id 'org.jetbrains.kotlin.android' version '1.6.10' apply false } \ No newline at end of file diff --git a/libDriveBackup/build.gradle b/libDriveBackup/build.gradle index 38a3981..7e886c7 100644 --- a/libDriveBackup/build.gradle +++ b/libDriveBackup/build.gradle @@ -56,7 +56,7 @@ afterEvaluate { publications { maven(MavenPublication) { group = 'media.uqab.driveBackupApi' - version = '1.0.7' + version = '1.0.8' artifactId = "driveBackupApi" from components.release