From 48a282f075b339fffc7238de00eb29914a1b4c0a Mon Sep 17 00:00:00 2001 From: T B Date: Fri, 28 Jan 2022 19:54:47 +0000 Subject: [PATCH 01/14] Translated using Weblate (German) Currently translated at 100.0% (8 of 8 strings) Co-authored-by: T B Translate-URL: https://weblate.pixeldroid.org/projects/pixeldroid/fastlane/de/ Translation: PixelDroid/Fastlane --- fastlane/metadata/android/de/changelogs/7.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/de/changelogs/7.txt diff --git a/fastlane/metadata/android/de/changelogs/7.txt b/fastlane/metadata/android/de/changelogs/7.txt new file mode 100644 index 00000000..cecbe566 --- /dev/null +++ b/fastlane/metadata/android/de/changelogs/7.txt @@ -0,0 +1,2 @@ +* Aktualisierung von Übersetzungen +* Auswählen von nicht lokal gespeicherten Dateien (z.B. Nextcloud) beim Upload eingeführt From 0affdb1f06a4c439ad481dd28eaca243452eaa80 Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Tue, 1 Feb 2022 13:20:06 +0100 Subject: [PATCH 02/14] Update dependencies --- app/build.gradle | 26 ++++++------- .../app/settings/SettingsActivity.kt | 5 ++- .../main/res/drawable/notification_icon.xml | 38 +++++++++++++++++++ build.gradle | 2 +- 4 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 app/src/main/res/drawable/notification_icon.xml diff --git a/app/build.gradle b/app/build.gradle index dd67da16..62a5e53d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -34,9 +34,6 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunnerArguments clearPackageData: 'true' } - lintOptions{ - disable 'MissingTranslation' - } sourceSets { main.java.srcDirs += 'src/main/java' test.java.srcDirs += 'src/test/java' @@ -96,6 +93,9 @@ android { } apply plugin: 'kotlin-kapt' + lint { + disable 'MissingTranslation' + } } dependencies { @@ -108,15 +108,15 @@ dependencies { */ implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'androidx.core:core-ktx:1.7.0' - implementation 'androidx.preference:preference-ktx:1.1.1' + implementation 'androidx.preference:preference-ktx:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.3' - implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' - implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' + implementation 'androidx.navigation:navigation-fragment-ktx:2.4.0' + implementation 'androidx.navigation:navigation-ui-ktx:2.4.0' implementation "androidx.browser:browser:1.4.0" implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" - implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5' - implementation 'androidx.navigation:navigation-ui-ktx:2.3.5' + implementation 'androidx.navigation:navigation-fragment-ktx:2.4.0' + implementation 'androidx.navigation:navigation-ui-ktx:2.4.0' implementation 'androidx.paging:paging-runtime-ktx:3.1.0' implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0' @@ -126,18 +126,18 @@ dependencies { implementation "androidx.annotation:annotation:1.3.0" implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation "androidx.activity:activity-ktx:1.4.0" - implementation 'androidx.fragment:fragment-ktx:1.4.0' + implementation 'androidx.fragment:fragment-ktx:1.4.1' implementation 'androidx.work:work-runtime-ktx:2.7.1' // Use the most recent version of CameraX - def cameraX_version = '1.0.2' - implementation "androidx.camera:camera-core:${cameraX_version}" - implementation "androidx.camera:camera-camera2:${cameraX_version}" + def cameraX_version = '1.1.0-beta01' + implementation "androidx.camera:camera-core:$cameraX_version" + implementation "androidx.camera:camera-camera2:$cameraX_version" // CameraX Lifecycle library implementation "androidx.camera:camera-lifecycle:$cameraX_version" // CameraX View class - implementation 'androidx.camera:camera-view:1.0.0-alpha32' + implementation "androidx.camera:camera-view:$cameraX_version" def room_version = "2.4.1" implementation "androidx.room:room-runtime:$room_version" diff --git a/app/src/main/java/org/pixeldroid/app/settings/SettingsActivity.kt b/app/src/main/java/org/pixeldroid/app/settings/SettingsActivity.kt index 53f97023..baea9c0e 100644 --- a/app/src/main/java/org/pixeldroid/app/settings/SettingsActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/settings/SettingsActivity.kt @@ -4,6 +4,7 @@ import android.content.Intent import android.content.SharedPreferences import android.os.Build import android.os.Bundle +import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceManager import org.pixeldroid.app.MainActivity @@ -83,7 +84,9 @@ class SettingsActivity : BaseActivity(), SharedPreferences.OnSharedPreferenceCha //Hide Notification setting for Android versions where it doesn't work if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { - preferenceScreen.removePreference(preferenceManager.findPreference("notification")) + preferenceManager.findPreference("notification")?.let { + preferenceScreen.removePreference(it) + } } } } diff --git a/app/src/main/res/drawable/notification_icon.xml b/app/src/main/res/drawable/notification_icon.xml new file mode 100644 index 00000000..b382f73c --- /dev/null +++ b/app/src/main/res/drawable/notification_icon.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 5b832a92..8070833f 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.0.4' + classpath 'com.android.tools.build:gradle:7.1.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong From 94e431d93f4016abaf59b67311ca93ad7e67eb38 Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Tue, 1 Feb 2022 13:54:56 +0100 Subject: [PATCH 03/14] Format html --- .../app/utils/notificationsWorker/NotificationsWorker.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt b/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt index ddac7f4c..6184e425 100644 --- a/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt +++ b/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt @@ -15,6 +15,7 @@ import androidx.work.WorkerParameters import org.pixeldroid.app.MainActivity import org.pixeldroid.app.R import org.pixeldroid.app.posts.PostActivity +import org.pixeldroid.app.posts.fromHtml import org.pixeldroid.app.utils.PixelDroidApplication import org.pixeldroid.app.utils.api.PixelfedAPI.Companion.apiForUser import org.pixeldroid.app.utils.api.objects.Notification @@ -166,7 +167,7 @@ class NotificationsWorker( .setAutoCancel(true) if (notification.type == mention || notification.type == comment || notification.type == poll){ - builder.setContentText(notification.status?.content) + builder.setContentText(notification.status?.content?.let { fromHtml(it) }) } builder.setGroup(uniqueUserId) From d8a9ba92c71501436712e7977df21f38d82df3e3 Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Tue, 1 Feb 2022 14:05:11 +0100 Subject: [PATCH 04/14] Update licenses --- app/licenses.yml | 68 ++++++++++++++++++++++++++++++- app/src/main/assets/licenses.json | 2 +- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/app/licenses.yml b/app/licenses.yml index fab30e5d..f020c466 100644 --- a/app/licenses.yml +++ b/app/licenses.yml @@ -852,4 +852,70 @@ copyrightHolder: Google Inc license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://developer.android.com/jetpack/androidx/releases/room#2.4.1 \ No newline at end of file + url: https://developer.android.com/jetpack/androidx/releases/room#2.4.1 +- artifact: androidx.window:window:+ + name: window + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: https://developer.android.com/jetpack/androidx/releases/window#1.0.0 +- artifact: com.android.support:animated-vector-drawable:+ + name: animated-vector-drawable + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html +- artifact: com.android.support:appcompat-v7:+ + name: appcompat-v7 + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html +- artifact: com.android.support:support-annotations:+ + name: support-annotations + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html +- artifact: com.android.support:support-compat:+ + name: support-compat + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html +- artifact: com.android.support:support-core-ui:+ + name: support-core-ui + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html +- artifact: com.android.support:support-core-utils:+ + name: support-core-utils + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html +- artifact: com.android.support:support-fragment:+ + name: support-fragment + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html +- artifact: com.android.support:support-media-compat:+ + name: support-media-compat + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html +- artifact: com.android.support:support-v4:+ + name: support-v4 + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html +- artifact: com.android.support:support-vector-drawable:+ + name: support-vector-drawable + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html \ No newline at end of file diff --git a/app/src/main/assets/licenses.json b/app/src/main/assets/licenses.json index f3caec20..3d00366e 100644 --- a/app/src/main/assets/licenses.json +++ b/app/src/main/assets/licenses.json @@ -1 +1 @@ -{"libraries":[{"artifactId":{"name":"materialdrawer-nav","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/MaterialDrawer","libraryName":"materialdrawer-nav"},{"artifactId":{"name":"materialdrawer-iconics","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/MaterialDrawer","libraryName":"materialdrawer-iconics"},{"artifactId":{"name":"materialdrawer","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/MaterialDrawer","libraryName":"materialdrawer"},{"artifactId":{"name":"startup-runtime","group":"androidx.startup","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/startup#1.0.0","libraryName":"startup-runtime"},{"artifactId":{"name":"iconics-views","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/Android-Iconics","libraryName":"iconics-views"},{"artifactId":{"name":"iconics-core","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/Android-Iconics","libraryName":"iconics-core"},{"artifactId":{"name":"iconics-typeface-api","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/Android-Iconics","libraryName":"iconics-typeface-api"},{"artifactId":{"name":"kotlin-stdlib-jdk8","group":"org.jetbrains.kotlin","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://kotlinlang.org/","libraryName":"kotlin-stdlib-jdk8"},{"artifactId":{"name":"kotlin-stdlib-jdk7","group":"org.jetbrains.kotlin","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://kotlinlang.org/","libraryName":"kotlin-stdlib-jdk7"},{"artifactId":{"name":"preference","group":"androidx.preference","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"preference"},{"artifactId":{"name":"constraintlayout","group":"androidx.constraintlayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://tools.android.com","libraryName":"constraintlayout"},{"artifactId":{"name":"camera-view","group":"androidx.camera","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/camera#1.0.0-alpha15","libraryName":"camera-view"},{"artifactId":{"name":"navigation-ui-ktx","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-ui-ktx"},{"artifactId":{"name":"navigation-ui","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-ui"},{"artifactId":{"name":"dexter","group":"com.karumi","version":"+"},"copyrightHolder":"Karumi and contributors","copyrightStatement":"Copyright © Karumi and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/karumi/Dexter","libraryName":"dexter"},{"artifactId":{"name":"material","group":"com.google.android.material","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/material-components/material-components-android","libraryName":"material"},{"artifactId":{"name":"dagger-android-support","group":"com.google.dagger","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Apache 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/google/dagger","libraryName":"dagger-android-support"},{"artifactId":{"name":"imagefilters","group":"info.androidhive","version":"+"},"copyrightHolder":"Zomato and ravi8x","copyrightStatement":"Copyright © Zomato and ravi8x. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","libraryName":"imagefilters"},{"artifactId":{"name":"ucrop","group":"com.github.yalantis","version":"+"},"copyrightHolder":"Yalantis","copyrightStatement":"Copyright © Yalantis. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0","normalizedLicense":"apache2","url":"https://github.com/Yalantis/uCrop","libraryName":"ucrop"},{"artifactId":{"name":"tracedroid","group":"com.github.ligi","version":"+"},"copyrightHolder":"ligi","copyrightStatement":"Copyright © ligi. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","url":"https://github.com/ligi/tracedroid","libraryName":"tracedroid"},{"artifactId":{"name":"supportemail","group":"com.github.ligi.tracedroid","version":"+"},"copyrightHolder":"ligi","copyrightStatement":"Copyright © ligi. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","url":"https://github.com/ligi/tracedroid","libraryName":"supportemail"},{"artifactId":{"name":"lib","group":"com.github.ligi.tracedroid","version":"+"},"copyrightHolder":"ligi","copyrightStatement":"Copyright © ligi. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","url":"https://github.com/ligi/tracedroid","libraryName":"lib"},{"artifactId":{"name":"timber","group":"com.jakewharton.timber","version":"+"},"copyrightHolder":"Jake Wharton and contributors","copyrightStatement":"Copyright © Jake Wharton and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/JakeWharton/timber","libraryName":"timber"},{"artifactId":{"name":"fastadapter-extensions-expandable","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/FastAdapter","libraryName":"fastadapter-extensions-expandable"},{"artifactId":{"name":"fastadapter","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/FastAdapter","libraryName":"fastadapter"},{"artifactId":{"name":"appcompat","group":"androidx.appcompat","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"appcompat"},{"artifactId":{"name":"navigation-fragment-ktx","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-fragment-ktx"},{"artifactId":{"name":"fragment-ktx","group":"androidx.fragment","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"fragment-ktx"},{"artifactId":{"name":"navigation-runtime-ktx","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-runtime-ktx"},{"artifactId":{"name":"navigation-common-ktx","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-common-ktx"},{"artifactId":{"name":"activity-ktx","group":"androidx.activity","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"activity-ktx"},{"artifactId":{"name":"core-ktx","group":"androidx.core","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"core-ktx"},{"artifactId":{"name":"navigation-fragment","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-fragment"},{"artifactId":{"name":"browser","group":"androidx.browser","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"browser"},{"artifactId":{"name":"paging-runtime-ktx","group":"androidx.paging","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"paging-runtime-ktx"},{"artifactId":{"name":"paging-runtime","group":"androidx.paging","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"paging-runtime"},{"artifactId":{"name":"viewpager2","group":"androidx.viewpager2","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"viewpager2"},{"artifactId":{"name":"recyclerview","group":"androidx.recyclerview","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"recyclerview"},{"artifactId":{"name":"legacy-support-v4","group":"androidx.legacy","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"legacy-support-v4"},{"artifactId":{"name":"legacy-support-core-ui","group":"androidx.legacy","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"legacy-support-core-ui"},{"artifactId":{"name":"swiperefreshlayout","group":"androidx.swiperefreshlayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"swiperefreshlayout"},{"artifactId":{"name":"lifecycle-livedata-ktx","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"lifecycle-livedata-ktx"},{"artifactId":{"name":"okhttp-integration","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"okhttp-integration"},{"artifactId":{"name":"glide","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"glide"},{"artifactId":{"name":"fragment","group":"androidx.fragment","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"fragment"},{"artifactId":{"name":"navigation-runtime","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-runtime"},{"artifactId":{"name":"activity","group":"androidx.activity","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"activity"},{"artifactId":{"name":"lifecycle-viewmodel-savedstate","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-viewmodel-savedstate"},{"artifactId":{"name":"lifecycle-runtime-ktx","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"lifecycle-runtime-ktx"},{"artifactId":{"name":"camera-camera2","group":"androidx.camera","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/camera#1.0.0-beta08","libraryName":"camera-camera2"},{"artifactId":{"name":"camera-lifecycle","group":"androidx.camera","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/camera#1.0.0-beta08","libraryName":"camera-lifecycle"},{"artifactId":{"name":"camera-core","group":"androidx.camera","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/camera#1.0.0-beta08","libraryName":"camera-core"},{"artifactId":{"name":"dagger-android","group":"com.google.dagger","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Apache 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/google/dagger","libraryName":"dagger-android"},{"artifactId":{"name":"cursoradapter","group":"androidx.cursoradapter","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"cursoradapter"},{"artifactId":{"name":"appcompat-resources","group":"androidx.appcompat","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"appcompat-resources"},{"artifactId":{"name":"drawerlayout","group":"androidx.drawerlayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"drawerlayout"},{"artifactId":{"name":"coordinatorlayout","group":"androidx.coordinatorlayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"coordinatorlayout"},{"artifactId":{"name":"viewpager","group":"androidx.viewpager","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"viewpager"},{"artifactId":{"name":"slidingpanelayout","group":"androidx.slidingpanelayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"slidingpanelayout"},{"artifactId":{"name":"customview","group":"androidx.customview","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"customview"},{"artifactId":{"name":"transition","group":"androidx.transition","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"transition"},{"artifactId":{"name":"vectordrawable-animated","group":"androidx.vectordrawable","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"vectordrawable-animated"},{"artifactId":{"name":"vectordrawable","group":"androidx.vectordrawable","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"vectordrawable"},{"artifactId":{"name":"media","group":"androidx.media","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"media"},{"artifactId":{"name":"legacy-support-core-utils","group":"androidx.legacy","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"legacy-support-core-utils"},{"artifactId":{"name":"loader","group":"androidx.loader","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"loader"},{"artifactId":{"name":"navigation-common","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-common"},{"artifactId":{"name":"asynclayoutinflater","group":"androidx.asynclayoutinflater","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"asynclayoutinflater"},{"artifactId":{"name":"core","group":"androidx.core","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"core"},{"artifactId":{"name":"versionedparcelable","group":"androidx.versionedparcelable","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"versionedparcelable"},{"artifactId":{"name":"collection-ktx","group":"androidx.collection","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"collection-ktx"},{"artifactId":{"name":"collection","group":"androidx.collection","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"collection"},{"artifactId":{"name":"concurrent-futures","group":"androidx.concurrent","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"concurrent-futures"},{"artifactId":{"name":"interpolator","group":"androidx.interpolator","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"interpolator"},{"artifactId":{"name":"savedstate","group":"androidx.savedstate","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"savedstate"},{"artifactId":{"name":"lifecycle-viewmodel-ktx","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"lifecycle-viewmodel-ktx"},{"artifactId":{"name":"lifecycle-viewmodel","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-viewmodel"},{"artifactId":{"name":"lifecycle-runtime","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-runtime"},{"artifactId":{"name":"room-ktx","group":"androidx.room","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"room-ktx"},{"artifactId":{"name":"room-runtime","group":"androidx.room","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"room-runtime"},{"artifactId":{"name":"room-common","group":"androidx.room","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"room-common"},{"artifactId":{"name":"sqlite-framework","group":"androidx.sqlite","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"sqlite-framework"},{"artifactId":{"name":"sqlite","group":"androidx.sqlite","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"sqlite"},{"artifactId":{"name":"cardview","group":"androidx.cardview","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"cardview"},{"artifactId":{"name":"exifinterface","group":"androidx.exifinterface","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"exifinterface"},{"artifactId":{"name":"gifdecoder","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"gifdecoder"},{"artifactId":{"name":"paging-common-ktx","group":"androidx.paging","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"paging-common-ktx"},{"artifactId":{"name":"constraintlayout-core","group":"androidx.constraintlayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://tools.android.com","libraryName":"constraintlayout-core"},{"artifactId":{"name":"databinding-ktx","group":"androidx.databinding","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","libraryName":"databinding-ktx"},{"artifactId":{"name":"lifecycle-extensions","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-extensions"},{"artifactId":{"name":"lifecycle-process","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-process"},{"artifactId":{"name":"lifecycle-service","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-service"},{"artifactId":{"name":"work-runtime-ktx","group":"androidx.work","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/work#2.5.0","libraryName":"work-runtime-ktx"},{"artifactId":{"name":"work-runtime","group":"androidx.work","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/work#2.5.0","libraryName":"work-runtime"},{"artifactId":{"name":"paging-common","group":"androidx.paging","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"paging-common"},{"artifactId":{"name":"lifecycle-livedata","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-livedata"},{"artifactId":{"name":"lifecycle-livedata-core-ktx","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"lifecycle-livedata-core-ktx"},{"artifactId":{"name":"lifecycle-livedata-core","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-livedata-core"},{"artifactId":{"name":"core-runtime","group":"androidx.arch.core","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"core-runtime"},{"artifactId":{"name":"core-common","group":"androidx.arch.core","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"core-common"},{"artifactId":{"name":"lifecycle-common","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-common"},{"artifactId":{"name":"documentfile","group":"androidx.documentfile","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"documentfile"},{"artifactId":{"name":"localbroadcastmanager","group":"androidx.localbroadcastmanager","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"localbroadcastmanager"},{"artifactId":{"name":"print","group":"androidx.print","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"print"},{"artifactId":{"name":"annotation","group":"androidx.annotation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"annotation"},{"artifactId":{"name":"converter-gson","group":"com.squareup.retrofit2","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/square/retrofit","libraryName":"converter-gson"},{"artifactId":{"name":"adapter-rxjava3","group":"com.squareup.retrofit2","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/square/retrofit","libraryName":"adapter-rxjava3"},{"artifactId":{"name":"retrofit","group":"com.squareup.retrofit2","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/square/retrofit","libraryName":"retrofit"},{"artifactId":{"name":"okhttp","group":"com.squareup.okhttp3","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://square.github.io/okhttp/","libraryName":"okhttp"},{"artifactId":{"name":"rxandroid","group":"io.reactivex.rxjava3","version":"+"},"copyrightHolder":"Netflix, Inc","copyrightStatement":"Copyright © Netflix, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/ReactiveX/RxAndroid","libraryName":"rxandroid"},{"artifactId":{"name":"rxjava","group":"io.reactivex.rxjava3","version":"+"},"copyrightHolder":"Netflix, Inc.","copyrightStatement":"Copyright © Netflix, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/ReactiveX/RxJava","libraryName":"rxjava"},{"artifactId":{"name":"sparkbutton","group":"com.github.connyduck","version":"+"},"copyrightHolder":"varunest and ConnyDuck","copyrightStatement":"Copyright © varunest and ConnyDuck. All rights reserved.","license":"The Apache License, Version 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/connyduck/sparkbutton","libraryName":"sparkbutton"},{"artifactId":{"name":"recyclerview-integration","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"recyclerview-integration"},{"artifactId":{"name":"google-material-typeface","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/Android-Iconics","libraryName":"google-material-typeface"},{"artifactId":{"name":"kotlinx-coroutines-android","group":"org.jetbrains.kotlinx","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/Kotlin/kotlinx.coroutines","libraryName":"kotlinx-coroutines-android"},{"artifactId":{"name":"viewbinding","group":"androidx.databinding","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","libraryName":"viewbinding"},{"artifactId":{"name":"kotlinx-coroutines-core-jvm","group":"org.jetbrains.kotlinx","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/Kotlin/kotlinx.coroutines","libraryName":"kotlinx-coroutines-core-jvm"},{"artifactId":{"name":"okhttp","group":"com.squareup.okhttp","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","libraryName":"okhttp"},{"artifactId":{"name":"okio","group":"com.squareup.okio","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/square/okio/","libraryName":"okio"},{"artifactId":{"name":"kotlin-stdlib","group":"org.jetbrains.kotlin","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://kotlinlang.org/","libraryName":"kotlin-stdlib"},{"artifactId":{"name":"listenablefuture","group":"com.google.guava","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","libraryName":"listenablefuture"},{"artifactId":{"name":"annotation-experimental","group":"androidx.annotation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"annotation-experimental"},{"artifactId":{"name":"auto-value-annotations","group":"com.google.auto.value","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","libraryName":"auto-value-annotations"},{"artifactId":{"name":"dagger","group":"com.google.dagger","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Apache 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/google/dagger","libraryName":"dagger"},{"artifactId":{"name":"dagger-lint-aar","group":"com.google.dagger","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Apache 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/google/dagger","libraryName":"dagger-lint-aar"},{"artifactId":{"name":"javax.inject","group":"javax.inject","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://code.google.com/p/atinject/","libraryName":"javax.inject"},{"artifactId":{"name":"gson","group":"com.google.code.gson","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","libraryName":"gson"},{"artifactId":{"name":"disklrucache","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"disklrucache"},{"artifactId":{"name":"annotations","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"annotations"},{"artifactId":{"name":"kotlin-stdlib-common","group":"org.jetbrains.kotlin","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://kotlinlang.org/","libraryName":"kotlin-stdlib-common"},{"artifactId":{"name":"annotations","group":"org.jetbrains","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://www.jetbrains.org","libraryName":"annotations"},{"artifactId":{"name":"gridlayout","group":"androidx.gridlayout","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"gridlayout"},{"artifactId":{"name":"preference-ktx","group":"androidx.preference","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"preference-ktx"},{"artifactId":{"name":"databinding-adapters","group":"androidx.databinding","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","libraryName":"databinding-adapters"},{"artifactId":{"name":"databinding-runtime","group":"androidx.databinding","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","libraryName":"databinding-runtime"},{"artifactId":{"name":"databinding-common","group":"androidx.databinding","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/studio","libraryName":"databinding-common"},{"artifactId":{"name":"lifecycle-common-java8","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-common-java8"},{"artifactId":{"name":"circleindicator","group":"me.relex","version":"+"},"copyrightHolder":"relex and contributors","copyrightStatement":"Copyright © relex and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/ongakuer/CircleIndicator","libraryName":"circleindicator"},{"artifactId":{"name":"dynamicanimation","group":"androidx.dynamicanimation","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"dynamicanimation"},{"artifactId":{"name":"savedstate-ktx","group":"androidx.savedstate","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/savedstate#1.1.0","libraryName":"savedstate-ktx"},{"artifactId":{"name":"tracing","group":"androidx.tracing","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/tracing#1.0.0","libraryName":"tracing"},{"artifactId":{"name":"emoji2-views-helper","group":"androidx.emoji2","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/emoji2#1.0.0","libraryName":"emoji2-views-helper"},{"artifactId":{"name":"emoji2","group":"androidx.emoji2","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/emoji2#1.0.0","libraryName":"emoji2"},{"artifactId":{"name":"resourceinspection-annotation","group":"androidx.resourceinspection","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/resourceinspection#1.0.0","libraryName":"resourceinspection-annotation"},{"artifactId":{"name":"room-paging","group":"androidx.room","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/room#2.4.1","libraryName":"room-paging"}]} \ No newline at end of file +{"libraries":[{"artifactId":{"name":"materialdrawer-nav","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/MaterialDrawer","libraryName":"materialdrawer-nav"},{"artifactId":{"name":"materialdrawer-iconics","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/MaterialDrawer","libraryName":"materialdrawer-iconics"},{"artifactId":{"name":"materialdrawer","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/MaterialDrawer","libraryName":"materialdrawer"},{"artifactId":{"name":"startup-runtime","group":"androidx.startup","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/startup#1.0.0","libraryName":"startup-runtime"},{"artifactId":{"name":"iconics-views","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/Android-Iconics","libraryName":"iconics-views"},{"artifactId":{"name":"iconics-core","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/Android-Iconics","libraryName":"iconics-core"},{"artifactId":{"name":"iconics-typeface-api","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/Android-Iconics","libraryName":"iconics-typeface-api"},{"artifactId":{"name":"kotlin-stdlib-jdk8","group":"org.jetbrains.kotlin","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://kotlinlang.org/","libraryName":"kotlin-stdlib-jdk8"},{"artifactId":{"name":"kotlin-stdlib-jdk7","group":"org.jetbrains.kotlin","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://kotlinlang.org/","libraryName":"kotlin-stdlib-jdk7"},{"artifactId":{"name":"preference","group":"androidx.preference","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"preference"},{"artifactId":{"name":"constraintlayout","group":"androidx.constraintlayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://tools.android.com","libraryName":"constraintlayout"},{"artifactId":{"name":"camera-view","group":"androidx.camera","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/camera#1.0.0-alpha15","libraryName":"camera-view"},{"artifactId":{"name":"navigation-ui-ktx","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-ui-ktx"},{"artifactId":{"name":"navigation-ui","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-ui"},{"artifactId":{"name":"dexter","group":"com.karumi","version":"+"},"copyrightHolder":"Karumi and contributors","copyrightStatement":"Copyright © Karumi and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/karumi/Dexter","libraryName":"dexter"},{"artifactId":{"name":"material","group":"com.google.android.material","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/material-components/material-components-android","libraryName":"material"},{"artifactId":{"name":"dagger-android-support","group":"com.google.dagger","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Apache 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/google/dagger","libraryName":"dagger-android-support"},{"artifactId":{"name":"imagefilters","group":"info.androidhive","version":"+"},"copyrightHolder":"Zomato and ravi8x","copyrightStatement":"Copyright © Zomato and ravi8x. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","libraryName":"imagefilters"},{"artifactId":{"name":"ucrop","group":"com.github.yalantis","version":"+"},"copyrightHolder":"Yalantis","copyrightStatement":"Copyright © Yalantis. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0","normalizedLicense":"apache2","url":"https://github.com/Yalantis/uCrop","libraryName":"ucrop"},{"artifactId":{"name":"tracedroid","group":"com.github.ligi","version":"+"},"copyrightHolder":"ligi","copyrightStatement":"Copyright © ligi. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","url":"https://github.com/ligi/tracedroid","libraryName":"tracedroid"},{"artifactId":{"name":"supportemail","group":"com.github.ligi.tracedroid","version":"+"},"copyrightHolder":"ligi","copyrightStatement":"Copyright © ligi. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","url":"https://github.com/ligi/tracedroid","libraryName":"supportemail"},{"artifactId":{"name":"lib","group":"com.github.ligi.tracedroid","version":"+"},"copyrightHolder":"ligi","copyrightStatement":"Copyright © ligi. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","url":"https://github.com/ligi/tracedroid","libraryName":"lib"},{"artifactId":{"name":"timber","group":"com.jakewharton.timber","version":"+"},"copyrightHolder":"Jake Wharton and contributors","copyrightStatement":"Copyright © Jake Wharton and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/JakeWharton/timber","libraryName":"timber"},{"artifactId":{"name":"fastadapter-extensions-expandable","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/FastAdapter","libraryName":"fastadapter-extensions-expandable"},{"artifactId":{"name":"fastadapter","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/FastAdapter","libraryName":"fastadapter"},{"artifactId":{"name":"appcompat","group":"androidx.appcompat","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"appcompat"},{"artifactId":{"name":"navigation-fragment-ktx","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-fragment-ktx"},{"artifactId":{"name":"fragment-ktx","group":"androidx.fragment","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"fragment-ktx"},{"artifactId":{"name":"navigation-runtime-ktx","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-runtime-ktx"},{"artifactId":{"name":"navigation-common-ktx","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-common-ktx"},{"artifactId":{"name":"activity-ktx","group":"androidx.activity","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"activity-ktx"},{"artifactId":{"name":"core-ktx","group":"androidx.core","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"core-ktx"},{"artifactId":{"name":"navigation-fragment","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-fragment"},{"artifactId":{"name":"browser","group":"androidx.browser","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"browser"},{"artifactId":{"name":"paging-runtime-ktx","group":"androidx.paging","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"paging-runtime-ktx"},{"artifactId":{"name":"paging-runtime","group":"androidx.paging","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"paging-runtime"},{"artifactId":{"name":"viewpager2","group":"androidx.viewpager2","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"viewpager2"},{"artifactId":{"name":"recyclerview","group":"androidx.recyclerview","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"recyclerview"},{"artifactId":{"name":"legacy-support-v4","group":"androidx.legacy","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"legacy-support-v4"},{"artifactId":{"name":"legacy-support-core-ui","group":"androidx.legacy","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"legacy-support-core-ui"},{"artifactId":{"name":"swiperefreshlayout","group":"androidx.swiperefreshlayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"swiperefreshlayout"},{"artifactId":{"name":"lifecycle-livedata-ktx","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"lifecycle-livedata-ktx"},{"artifactId":{"name":"okhttp-integration","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"okhttp-integration"},{"artifactId":{"name":"glide","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"glide"},{"artifactId":{"name":"fragment","group":"androidx.fragment","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"fragment"},{"artifactId":{"name":"navigation-runtime","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-runtime"},{"artifactId":{"name":"activity","group":"androidx.activity","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"activity"},{"artifactId":{"name":"lifecycle-viewmodel-savedstate","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-viewmodel-savedstate"},{"artifactId":{"name":"lifecycle-runtime-ktx","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"lifecycle-runtime-ktx"},{"artifactId":{"name":"camera-camera2","group":"androidx.camera","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/camera#1.0.0-beta08","libraryName":"camera-camera2"},{"artifactId":{"name":"camera-lifecycle","group":"androidx.camera","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/camera#1.0.0-beta08","libraryName":"camera-lifecycle"},{"artifactId":{"name":"camera-core","group":"androidx.camera","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/camera#1.0.0-beta08","libraryName":"camera-core"},{"artifactId":{"name":"dagger-android","group":"com.google.dagger","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Apache 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/google/dagger","libraryName":"dagger-android"},{"artifactId":{"name":"cursoradapter","group":"androidx.cursoradapter","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"cursoradapter"},{"artifactId":{"name":"appcompat-resources","group":"androidx.appcompat","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"appcompat-resources"},{"artifactId":{"name":"drawerlayout","group":"androidx.drawerlayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"drawerlayout"},{"artifactId":{"name":"coordinatorlayout","group":"androidx.coordinatorlayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"coordinatorlayout"},{"artifactId":{"name":"viewpager","group":"androidx.viewpager","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"viewpager"},{"artifactId":{"name":"slidingpanelayout","group":"androidx.slidingpanelayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"slidingpanelayout"},{"artifactId":{"name":"customview","group":"androidx.customview","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"customview"},{"artifactId":{"name":"transition","group":"androidx.transition","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"transition"},{"artifactId":{"name":"vectordrawable-animated","group":"androidx.vectordrawable","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"vectordrawable-animated"},{"artifactId":{"name":"vectordrawable","group":"androidx.vectordrawable","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"vectordrawable"},{"artifactId":{"name":"media","group":"androidx.media","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"media"},{"artifactId":{"name":"legacy-support-core-utils","group":"androidx.legacy","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"legacy-support-core-utils"},{"artifactId":{"name":"loader","group":"androidx.loader","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"loader"},{"artifactId":{"name":"navigation-common","group":"androidx.navigation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"navigation-common"},{"artifactId":{"name":"asynclayoutinflater","group":"androidx.asynclayoutinflater","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"asynclayoutinflater"},{"artifactId":{"name":"core","group":"androidx.core","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"core"},{"artifactId":{"name":"versionedparcelable","group":"androidx.versionedparcelable","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"versionedparcelable"},{"artifactId":{"name":"collection-ktx","group":"androidx.collection","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"collection-ktx"},{"artifactId":{"name":"collection","group":"androidx.collection","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"collection"},{"artifactId":{"name":"concurrent-futures","group":"androidx.concurrent","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"concurrent-futures"},{"artifactId":{"name":"interpolator","group":"androidx.interpolator","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"interpolator"},{"artifactId":{"name":"savedstate","group":"androidx.savedstate","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"savedstate"},{"artifactId":{"name":"lifecycle-viewmodel-ktx","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"lifecycle-viewmodel-ktx"},{"artifactId":{"name":"lifecycle-viewmodel","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-viewmodel"},{"artifactId":{"name":"lifecycle-runtime","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-runtime"},{"artifactId":{"name":"room-ktx","group":"androidx.room","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"room-ktx"},{"artifactId":{"name":"room-runtime","group":"androidx.room","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"room-runtime"},{"artifactId":{"name":"room-common","group":"androidx.room","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"room-common"},{"artifactId":{"name":"sqlite-framework","group":"androidx.sqlite","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"sqlite-framework"},{"artifactId":{"name":"sqlite","group":"androidx.sqlite","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"sqlite"},{"artifactId":{"name":"cardview","group":"androidx.cardview","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"cardview"},{"artifactId":{"name":"exifinterface","group":"androidx.exifinterface","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"exifinterface"},{"artifactId":{"name":"gifdecoder","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"gifdecoder"},{"artifactId":{"name":"paging-common-ktx","group":"androidx.paging","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"paging-common-ktx"},{"artifactId":{"name":"constraintlayout-core","group":"androidx.constraintlayout","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://tools.android.com","libraryName":"constraintlayout-core"},{"artifactId":{"name":"databinding-ktx","group":"androidx.databinding","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","libraryName":"databinding-ktx"},{"artifactId":{"name":"lifecycle-extensions","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-extensions"},{"artifactId":{"name":"lifecycle-process","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-process"},{"artifactId":{"name":"lifecycle-service","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-service"},{"artifactId":{"name":"work-runtime-ktx","group":"androidx.work","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/work#2.5.0","libraryName":"work-runtime-ktx"},{"artifactId":{"name":"work-runtime","group":"androidx.work","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/work#2.5.0","libraryName":"work-runtime"},{"artifactId":{"name":"paging-common","group":"androidx.paging","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"paging-common"},{"artifactId":{"name":"lifecycle-livedata","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-livedata"},{"artifactId":{"name":"lifecycle-livedata-core-ktx","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"lifecycle-livedata-core-ktx"},{"artifactId":{"name":"lifecycle-livedata-core","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-livedata-core"},{"artifactId":{"name":"core-runtime","group":"androidx.arch.core","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"core-runtime"},{"artifactId":{"name":"core-common","group":"androidx.arch.core","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"core-common"},{"artifactId":{"name":"lifecycle-common","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-common"},{"artifactId":{"name":"documentfile","group":"androidx.documentfile","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"documentfile"},{"artifactId":{"name":"localbroadcastmanager","group":"androidx.localbroadcastmanager","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"localbroadcastmanager"},{"artifactId":{"name":"print","group":"androidx.print","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"print"},{"artifactId":{"name":"annotation","group":"androidx.annotation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"annotation"},{"artifactId":{"name":"converter-gson","group":"com.squareup.retrofit2","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/square/retrofit","libraryName":"converter-gson"},{"artifactId":{"name":"adapter-rxjava3","group":"com.squareup.retrofit2","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/square/retrofit","libraryName":"adapter-rxjava3"},{"artifactId":{"name":"retrofit","group":"com.squareup.retrofit2","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/square/retrofit","libraryName":"retrofit"},{"artifactId":{"name":"okhttp","group":"com.squareup.okhttp3","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://square.github.io/okhttp/","libraryName":"okhttp"},{"artifactId":{"name":"rxandroid","group":"io.reactivex.rxjava3","version":"+"},"copyrightHolder":"Netflix, Inc","copyrightStatement":"Copyright © Netflix, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/ReactiveX/RxAndroid","libraryName":"rxandroid"},{"artifactId":{"name":"rxjava","group":"io.reactivex.rxjava3","version":"+"},"copyrightHolder":"Netflix, Inc.","copyrightStatement":"Copyright © Netflix, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/ReactiveX/RxJava","libraryName":"rxjava"},{"artifactId":{"name":"sparkbutton","group":"com.github.connyduck","version":"+"},"copyrightHolder":"varunest and ConnyDuck","copyrightStatement":"Copyright © varunest and ConnyDuck. All rights reserved.","license":"The Apache License, Version 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/connyduck/sparkbutton","libraryName":"sparkbutton"},{"artifactId":{"name":"recyclerview-integration","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"recyclerview-integration"},{"artifactId":{"name":"google-material-typeface","group":"com.mikepenz","version":"+"},"copyrightHolder":"Mike Penz and contributors","copyrightStatement":"Copyright © Mike Penz and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/mikepenz/Android-Iconics","libraryName":"google-material-typeface"},{"artifactId":{"name":"kotlinx-coroutines-android","group":"org.jetbrains.kotlinx","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/Kotlin/kotlinx.coroutines","libraryName":"kotlinx-coroutines-android"},{"artifactId":{"name":"viewbinding","group":"androidx.databinding","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","libraryName":"viewbinding"},{"artifactId":{"name":"kotlinx-coroutines-core-jvm","group":"org.jetbrains.kotlinx","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/Kotlin/kotlinx.coroutines","libraryName":"kotlinx-coroutines-core-jvm"},{"artifactId":{"name":"okhttp","group":"com.squareup.okhttp","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","libraryName":"okhttp"},{"artifactId":{"name":"okio","group":"com.squareup.okio","version":"+"},"copyrightHolder":"Square, Inc.","copyrightStatement":"Copyright © Square, Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/square/okio/","libraryName":"okio"},{"artifactId":{"name":"kotlin-stdlib","group":"org.jetbrains.kotlin","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://kotlinlang.org/","libraryName":"kotlin-stdlib"},{"artifactId":{"name":"listenablefuture","group":"com.google.guava","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","libraryName":"listenablefuture"},{"artifactId":{"name":"annotation-experimental","group":"androidx.annotation","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"annotation-experimental"},{"artifactId":{"name":"auto-value-annotations","group":"com.google.auto.value","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","libraryName":"auto-value-annotations"},{"artifactId":{"name":"dagger","group":"com.google.dagger","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Apache 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/google/dagger","libraryName":"dagger"},{"artifactId":{"name":"dagger-lint-aar","group":"com.google.dagger","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Apache 2.0","licenseUrl":"https://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/google/dagger","libraryName":"dagger-lint-aar"},{"artifactId":{"name":"javax.inject","group":"javax.inject","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://code.google.com/p/atinject/","libraryName":"javax.inject"},{"artifactId":{"name":"gson","group":"com.google.code.gson","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","normalizedLicense":"apache2","libraryName":"gson"},{"artifactId":{"name":"disklrucache","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"disklrucache"},{"artifactId":{"name":"annotations","group":"com.github.bumptech.glide","version":"+"},"copyrightHolder":"Google Inc.","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"Simplified BSD License","licenseUrl":"http://www.opensource.org/licenses/bsd-license","normalizedLicense":"bsd_2_clauses","url":"https://github.com/bumptech/glide","libraryName":"annotations"},{"artifactId":{"name":"kotlin-stdlib-common","group":"org.jetbrains.kotlin","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://kotlinlang.org/","libraryName":"kotlin-stdlib-common"},{"artifactId":{"name":"annotations","group":"org.jetbrains","version":"+"},"copyrightHolder":"JetBrains s.r.o. and contributors","copyrightStatement":"Copyright © JetBrains s.r.o. and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://www.jetbrains.org","libraryName":"annotations"},{"artifactId":{"name":"gridlayout","group":"androidx.gridlayout","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"gridlayout"},{"artifactId":{"name":"preference-ktx","group":"androidx.preference","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx","libraryName":"preference-ktx"},{"artifactId":{"name":"databinding-adapters","group":"androidx.databinding","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","libraryName":"databinding-adapters"},{"artifactId":{"name":"databinding-runtime","group":"androidx.databinding","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","libraryName":"databinding-runtime"},{"artifactId":{"name":"databinding-common","group":"androidx.databinding","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/studio","libraryName":"databinding-common"},{"artifactId":{"name":"lifecycle-common-java8","group":"androidx.lifecycle","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/topic/libraries/architecture/index.html","libraryName":"lifecycle-common-java8"},{"artifactId":{"name":"circleindicator","group":"me.relex","version":"+"},"copyrightHolder":"relex and contributors","copyrightStatement":"Copyright © relex and contributors. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://github.com/ongakuer/CircleIndicator","libraryName":"circleindicator"},{"artifactId":{"name":"dynamicanimation","group":"androidx.dynamicanimation","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"dynamicanimation"},{"artifactId":{"name":"savedstate-ktx","group":"androidx.savedstate","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/savedstate#1.1.0","libraryName":"savedstate-ktx"},{"artifactId":{"name":"tracing","group":"androidx.tracing","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/tracing#1.0.0","libraryName":"tracing"},{"artifactId":{"name":"emoji2-views-helper","group":"androidx.emoji2","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/emoji2#1.0.0","libraryName":"emoji2-views-helper"},{"artifactId":{"name":"emoji2","group":"androidx.emoji2","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/emoji2#1.0.0","libraryName":"emoji2"},{"artifactId":{"name":"resourceinspection-annotation","group":"androidx.resourceinspection","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/resourceinspection#1.0.0","libraryName":"resourceinspection-annotation"},{"artifactId":{"name":"room-paging","group":"androidx.room","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/room#2.4.1","libraryName":"room-paging"},{"artifactId":{"name":"window","group":"androidx.window","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"https://developer.android.com/jetpack/androidx/releases/window#1.0.0","libraryName":"window"},{"artifactId":{"name":"animated-vector-drawable","group":"com.android.support","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"animated-vector-drawable"},{"artifactId":{"name":"appcompat-v7","group":"com.android.support","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"appcompat-v7"},{"artifactId":{"name":"support-annotations","group":"com.android.support","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"support-annotations"},{"artifactId":{"name":"support-compat","group":"com.android.support","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"support-compat"},{"artifactId":{"name":"support-core-ui","group":"com.android.support","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"support-core-ui"},{"artifactId":{"name":"support-core-utils","group":"com.android.support","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"support-core-utils"},{"artifactId":{"name":"support-fragment","group":"com.android.support","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"support-fragment"},{"artifactId":{"name":"support-media-compat","group":"com.android.support","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"support-media-compat"},{"artifactId":{"name":"support-v4","group":"com.android.support","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"support-v4"},{"artifactId":{"name":"support-vector-drawable","group":"com.android.support","version":"+"},"copyrightHolder":"Google Inc","copyrightStatement":"Copyright © Google Inc. All rights reserved.","license":"The Apache Software License, Version 2.0","licenseUrl":"http://www.apache.org/licenses/LICENSE-2.0.txt","normalizedLicense":"apache2","url":"http://developer.android.com/tools/extras/support-library.html","libraryName":"support-vector-drawable"}]} \ No newline at end of file From 57d8962eb60442f355f729c6e26466978704feac Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Thu, 3 Feb 2022 00:35:53 +0100 Subject: [PATCH 05/14] Group notifications --- .../NotificationsWorker.kt | 69 ++++++++++++++++++- .../main/res/drawable/notification_icon.xml | 28 ++------ app/src/main/res/values/strings.xml | 9 +++ 3 files changed, 79 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt b/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt index 6184e425..23e360fe 100644 --- a/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt +++ b/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt @@ -12,6 +12,7 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.work.CoroutineWorker import androidx.work.WorkerParameters +import okhttp3.internal.format import org.pixeldroid.app.MainActivity import org.pixeldroid.app.R import org.pixeldroid.app.posts.PostActivity @@ -72,8 +73,7 @@ class NotificationsWorker( ) while (!newNotifications.isNullOrEmpty() - && newNotifications.map { it.created_at ?: Instant.MIN } - .maxOrNull()!! > previouslyLatestNotification?.created_at ?: Instant.MIN + && newNotifications.maxOf { it.created_at ?: Instant.MIN } > previouslyLatestNotification?.created_at ?: Instant.MIN ) { // Add to db val filteredNewNotifications: List = newNotifications.filter { @@ -84,6 +84,12 @@ class NotificationsWorker( db.notificationDao().insertAll(filteredNewNotifications) + + //If multiple notifications, show summary of them + if(filteredNewNotifications.size > 1){ + showNotificationSummary(filteredNewNotifications, uniqueUserId) + } + // Launch new notifications filteredNewNotifications.forEach { showNotification(it, user, uniqueUserId) @@ -107,6 +113,39 @@ class NotificationsWorker( return Result.success() } + private fun showNotificationSummary(notifications: List, uniqueUserId: String) { + val content = joinNames( + applicationContext, + notifications.mapNotNull { it.account?.getDisplayName() } + ) + + val title: String = applicationContext.resources.getQuantityString( + R.plurals.notification_title_summary, + notifications.size, + notifications.size + ) + + val groupBuilder = NotificationCompat.Builder(applicationContext, makeChannelId(uniqueUserId, null)) + .setContentTitle(title) + .setContentText(content) + .setGroupSummary(true) + .setAutoCancel(true) + .setGroup(uniqueUserId) + .setSmallIcon(R.drawable.notification_icon) + .setStyle(NotificationCompat.BigTextStyle().bigText(content)) + .setContentIntent( + PendingIntent.getActivity(applicationContext, 0, Intent(applicationContext, MainActivity::class.java).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + putExtra(SHOW_NOTIFICATION_TAG, true) + }, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT) + ) + + with(NotificationManagerCompat.from(applicationContext)) { + notify(uniqueUserId.hashCode(), groupBuilder.build()) + } + + } + private fun showNotification( notification: Notification, user: UserDatabaseEntity, @@ -238,7 +277,8 @@ fun makeNotificationChannels(context: Context, handle: String, channelGroupId: S /** * [channelGroupId] is the id used to uniquely identify the group: for us it is a unique id - * identifying a user consisting of the concatenation of the instance uri and user id. + * identifying a user consisting of the concatenation of the instance uri and user id + * (see [makeChannelGroupId]). */ private fun makeChannelId(channelGroupId: String, type: Notification.NotificationType?): String = (channelGroupId + (type ?: NotificationsWorker.otherNotificationType)).hashCode().toString() @@ -265,4 +305,27 @@ fun removeNotificationChannelsFromAccount(context: Context, user: UserDatabaseEn } } } +} + + +/** + * BidiFormatter.unicodeWrap is insufficient in some cases (see Tusky#1921) + * So we force isolation manually + * https://unicode.org/reports/tr9/#Explicit_Directional_Isolates + */ +fun CharSequence.unicodeWrap(): String = "\u2068${this}\u2069" + +private fun joinNames(context: Context, notifications: List): String { + return when { + notifications.size > 3 -> { + context.getString(R.string.notification_summary_large).format( + *notifications.subList(0, 3).map { it.unicodeWrap() }.toTypedArray(), + notifications.size - 3 + ) + } + else -> context.getString( when(notifications.size) { + 2 -> R.string.notification_summary_small + else /* ==3 */-> R.string.notification_summary_medium + }).format(*notifications.map { it.unicodeWrap() }.toTypedArray()) + } } \ No newline at end of file diff --git a/app/src/main/res/drawable/notification_icon.xml b/app/src/main/res/drawable/notification_icon.xml index b382f73c..aec004ef 100644 --- a/app/src/main/res/drawable/notification_icon.xml +++ b/app/src/main/res/drawable/notification_icon.xml @@ -1,33 +1,13 @@ - - - - - - - - + android:scaleX="4" + android:scaleY="4" + android:translateX="-53" + android:translateY="-53"> "Polls" "Other" + + "%d new notification" + "%d new notifications" + + %1$s, %2$s, %3$s and %4$d others + %1$s, %2$s, and %3$s + %1$s and %2$s + + From 9b0cabe37c19b2188d145730973579c50002b75b Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Sun, 6 Feb 2022 14:56:48 +0100 Subject: [PATCH 06/14] Dismiss notification group of current account when notification tab is opened --- .../notifications/NotificationsFragment.kt | 12 ++++++++++++ .../utils/notificationsWorker/NotificationsWorker.kt | 1 - 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/pixeldroid/app/posts/feeds/cachedFeeds/notifications/NotificationsFragment.kt b/app/src/main/java/org/pixeldroid/app/posts/feeds/cachedFeeds/notifications/NotificationsFragment.kt index b378b676..d3f031ce 100644 --- a/app/src/main/java/org/pixeldroid/app/posts/feeds/cachedFeeds/notifications/NotificationsFragment.kt +++ b/app/src/main/java/org/pixeldroid/app/posts/feeds/cachedFeeds/notifications/NotificationsFragment.kt @@ -9,6 +9,7 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView +import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat import androidx.lifecycle.LifecycleCoroutineScope import androidx.lifecycle.ViewModelProvider @@ -31,6 +32,7 @@ import org.pixeldroid.app.utils.api.objects.Account import org.pixeldroid.app.utils.api.objects.Notification import org.pixeldroid.app.utils.api.objects.Status import org.pixeldroid.app.utils.di.PixelfedAPIHolder +import org.pixeldroid.app.utils.notificationsWorker.makeChannelGroupId /** @@ -64,6 +66,16 @@ class NotificationsFragment : CachedFeedFragment() { } + override fun onResume() { + super.onResume() + with(NotificationManagerCompat.from(requireContext())) { + // Cancel account notification group + db.userDao().getActiveUser()?.let { + cancel( makeChannelGroupId(it).hashCode()) + } + } + } + /** * View Holder for a [Notification] RecyclerView list item. */ diff --git a/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt b/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt index 23e360fe..1133e298 100644 --- a/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt +++ b/app/src/main/java/org/pixeldroid/app/utils/notificationsWorker/NotificationsWorker.kt @@ -12,7 +12,6 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.work.CoroutineWorker import androidx.work.WorkerParameters -import okhttp3.internal.format import org.pixeldroid.app.MainActivity import org.pixeldroid.app.R import org.pixeldroid.app.posts.PostActivity From d8634f4bee2004aa749055966eacee89f6cf7110 Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Mon, 14 Feb 2022 11:33:00 +0100 Subject: [PATCH 07/14] Update dependencies --- app/build.gradle | 21 ++++++++++++--------- app/licenses.yml | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 62a5e53d..87c6680e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -110,24 +110,27 @@ dependencies { implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.preference:preference-ktx:1.2.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.3' - implementation 'androidx.navigation:navigation-fragment-ktx:2.4.0' - implementation 'androidx.navigation:navigation-ui-ktx:2.4.0' + implementation 'androidx.navigation:navigation-fragment-ktx:2.4.1' + implementation 'androidx.navigation:navigation-ui-ktx:2.4.1' implementation "androidx.browser:browser:1.4.0" implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" - implementation 'androidx.navigation:navigation-fragment-ktx:2.4.0' - implementation 'androidx.navigation:navigation-ui-ktx:2.4.0' + implementation 'androidx.navigation:navigation-fragment-ktx:2.4.1' + implementation 'androidx.navigation:navigation-ui-ktx:2.4.1' implementation 'androidx.paging:paging-runtime-ktx:3.1.0' - implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.0' - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0' - implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.4.0' - implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.0" - implementation "androidx.lifecycle:lifecycle-common-java8:2.4.0" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.4.1' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1' + implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.4.1' + implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.4.1" + implementation "androidx.lifecycle:lifecycle-common-java8:2.4.1" implementation "androidx.annotation:annotation:1.3.0" implementation 'androidx.gridlayout:gridlayout:1.0.0' implementation "androidx.activity:activity-ktx:1.4.0" implementation 'androidx.fragment:fragment-ktx:1.4.1' implementation 'androidx.work:work-runtime-ktx:2.7.1' + implementation 'androidx.media2:media2-widget:1.2.1' + implementation 'androidx.media2:media2-player:1.2.1' + // Use the most recent version of CameraX def cameraX_version = '1.1.0-beta01' diff --git a/app/licenses.yml b/app/licenses.yml index f020c466..39aafb07 100644 --- a/app/licenses.yml +++ b/app/licenses.yml @@ -918,4 +918,40 @@ copyrightHolder: Google Inc license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: http://developer.android.com/tools/extras/support-library.html \ No newline at end of file + url: http://developer.android.com/tools/extras/support-library.html +- artifact: androidx.media2:media2-widget:+ + name: media2-widget + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: https://developer.android.com/jetpack/androidx/releases/media2 +- artifact: androidx.palette:palette:+ + name: palette + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: http://developer.android.com/tools/extras/support-library.html +- artifact: androidx.media2:media2-player:+ + name: media2-player + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: https://developer.android.com/jetpack/androidx/releases/media2 +- artifact: androidx.media2:media2-session:+ + name: media2-session + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: https://developer.android.com/jetpack/androidx/releases/media2 +- artifact: androidx.media2:media2-common:+ + name: media2-common + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: https://developer.android.com/jetpack/androidx/releases/media2 +- artifact: androidx.media2:media2-exoplayer:+ + name: media2-exoplayer + copyrightHolder: Google Inc + license: The Apache Software License, Version 2.0 + licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt + url: https://developer.android.com/jetpack/androidx/releases/media2 From 277dd3c66e2131dd3510cd2bf8c3719c1bf30832 Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Mon, 14 Feb 2022 11:41:51 +0100 Subject: [PATCH 08/14] Allow video uploads --- app/src/main/AndroidManifest.xml | 14 ++++++++++++++ .../app/postCreation/camera/CameraFragment.kt | 5 +++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 130b3dcb..0ac6a1e0 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -44,6 +44,20 @@ + + + + + + + + + + + + + + Date: Thu, 10 Feb 2022 18:24:44 +0100 Subject: [PATCH 09/14] Add video play support --- app/src/main/AndroidManifest.xml | 29 ++++++++----- .../app/posts/MediaViewerActivity.kt | 42 +++++++++++++++++++ .../pixeldroid/app/posts/StatusViewHolder.kt | 20 ++++++++- .../pixeldroid/app/profile/ProfileActivity.kt | 7 +++- .../ProfilePostsRecyclerViewAdapter.kt | 1 + .../searchDiscover/SearchDiscoverFragment.kt | 5 +++ .../main/res/drawable/play_circle_filled.xml | 9 ++++ .../main/res/layout/activity_mediaviewer.xml | 12 ++++++ app/src/main/res/layout/album_image_view.xml | 11 +++++ .../res/layout/fragment_profile_posts.xml | 17 +++++++- app/src/main/res/values/strings.xml | 7 ++-- 11 files changed, 143 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt create mode 100644 app/src/main/res/drawable/play_circle_filled.xml create mode 100644 app/src/main/res/layout/activity_mediaviewer.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0ac6a1e0..447f538c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -22,6 +22,10 @@ android:supportsRtl="true" android:theme="@style/AppTheme" tools:replace="android:allowBackup"> + + tools:ignore="LockedOrientationActivity"> + + + + @@ -83,11 +91,11 @@ tools:ignore="LockedOrientationActivity" /> + tools:ignore="LockedOrientationActivity"> @@ -100,11 +108,11 @@ + tools:ignore="LockedOrientationActivity"> @@ -118,16 +126,16 @@ + tools:ignore="LockedOrientationActivity" /> + tools:ignore="LockedOrientationActivity"> @@ -156,7 +164,6 @@ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> - \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt b/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt new file mode 100644 index 00000000..5ac282af --- /dev/null +++ b/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt @@ -0,0 +1,42 @@ +package org.pixeldroid.app.posts + +import android.os.Bundle +import androidx.core.net.toUri +import androidx.media2.common.MediaMetadata +import androidx.media2.common.UriMediaItem +import androidx.media2.player.MediaPlayer +import org.pixeldroid.app.databinding.ActivityMediaviewerBinding +import org.pixeldroid.app.utils.BaseActivity + +class MediaViewerActivity : BaseActivity() { + + private lateinit var binding: ActivityMediaviewerBinding + + companion object { + const val VIDEO_URL_TAG = "video_url_mediavieweractivity" + const val VIDEO_DESCRIPTION_TAG = "video_description_mediavieweractivity" + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = ActivityMediaviewerBinding.inflate(layoutInflater) + setContentView(binding.root) + + val uri: String = intent.getStringExtra(VIDEO_URL_TAG).orEmpty() + val description: String? = intent.getStringExtra(VIDEO_DESCRIPTION_TAG) + + val mediaItem: UriMediaItem = UriMediaItem.Builder(uri.toUri()).build() + mediaItem.metadata = MediaMetadata.Builder() + .putString(MediaMetadata.METADATA_KEY_TITLE, description ?: "") + .build() + + val mediaPlayer = MediaPlayer(this) + mediaPlayer.setMediaItem(mediaItem) + mediaPlayer.prepare() + + binding.videoView.setPlayer(mediaPlayer) + + // Start actually playing the video + mediaPlayer.play() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt b/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt index 1a2fbbf2..62891e34 100644 --- a/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt +++ b/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt @@ -37,6 +37,8 @@ import com.karumi.dexter.listener.PermissionDeniedResponse import com.karumi.dexter.listener.PermissionGrantedResponse import com.karumi.dexter.listener.single.BasePermissionListener import kotlinx.coroutines.launch +import org.pixeldroid.app.posts.MediaViewerActivity.Companion.VIDEO_DESCRIPTION_TAG +import org.pixeldroid.app.posts.MediaViewerActivity.Companion.VIDEO_URL_TAG import retrofit2.HttpException import java.io.IOException import kotlin.math.roundToInt @@ -594,6 +596,7 @@ private class AlbumViewPagerAdapter(private val media_attachments: List 1) { albumIcon.visibility = View.VISIBLE } else { albumIcon.visibility = View.GONE + if(post.media_attachments?.get(0)?.type == Attachment.AttachmentType.video) { + videoIcon.visibility = View.VISIBLE + } else videoIcon.visibility = View.GONE + } postPreview.setOnClickListener { diff --git a/app/src/main/java/org/pixeldroid/app/profile/ProfilePostsRecyclerViewAdapter.kt b/app/src/main/java/org/pixeldroid/app/profile/ProfilePostsRecyclerViewAdapter.kt index fd5fb36f..5a33a222 100644 --- a/app/src/main/java/org/pixeldroid/app/profile/ProfilePostsRecyclerViewAdapter.kt +++ b/app/src/main/java/org/pixeldroid/app/profile/ProfilePostsRecyclerViewAdapter.kt @@ -8,4 +8,5 @@ import org.pixeldroid.app.R class ProfilePostViewHolder(val postView: View) : RecyclerView.ViewHolder(postView) { val postPreview: ImageView = postView.findViewById(R.id.postPreview) val albumIcon: ImageView = postView.findViewById(R.id.albumIcon) + val videoIcon: ImageView = postView.findViewById(R.id.albumIcon) } \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/searchDiscover/SearchDiscoverFragment.kt b/app/src/main/java/org/pixeldroid/app/searchDiscover/SearchDiscoverFragment.kt index a0530e7c..a19a88d8 100644 --- a/app/src/main/java/org/pixeldroid/app/searchDiscover/SearchDiscoverFragment.kt +++ b/app/src/main/java/org/pixeldroid/app/searchDiscover/SearchDiscoverFragment.kt @@ -19,6 +19,7 @@ import org.pixeldroid.app.utils.api.objects.Status import org.pixeldroid.app.posts.PostActivity import org.pixeldroid.app.utils.BaseFragment import org.pixeldroid.app.utils.ImageConverter +import org.pixeldroid.app.utils.api.objects.Attachment import org.pixeldroid.app.utils.bindingLifecycleAware import retrofit2.HttpException import java.io.IOException @@ -120,6 +121,10 @@ class SearchDiscoverFragment : BaseFragment() { holder.albumIcon.visibility = View.VISIBLE } else { holder.albumIcon.visibility = View.GONE + if(post?.media_attachments?.get(0)?.type == Attachment.AttachmentType.video) { + holder.videoIcon.visibility = View.VISIBLE + } else holder.videoIcon.visibility = View.GONE + } ImageConverter.setSquareImageFromURL(holder.postView, post?.getPostPreviewURL(), holder.postPreview, post?.media_attachments?.firstOrNull()?.blurhash) holder.postPreview.setOnClickListener { diff --git a/app/src/main/res/drawable/play_circle_filled.xml b/app/src/main/res/drawable/play_circle_filled.xml new file mode 100644 index 00000000..4e719f75 --- /dev/null +++ b/app/src/main/res/drawable/play_circle_filled.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_mediaviewer.xml b/app/src/main/res/layout/activity_mediaviewer.xml new file mode 100644 index 00000000..d28a8047 --- /dev/null +++ b/app/src/main/res/layout/activity_mediaviewer.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/album_image_view.xml b/app/src/main/res/layout/album_image_view.xml index b4042911..462eab66 100644 --- a/app/src/main/res/layout/album_image_view.xml +++ b/app/src/main/res/layout/album_image_view.xml @@ -14,4 +14,15 @@ android:adjustViewBounds="true" tools:ignore="ContentDescription" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_profile_posts.xml b/app/src/main/res/layout/fragment_profile_posts.xml index 666365b5..9df72daa 100644 --- a/app/src/main/res/layout/fragment_profile_posts.xml +++ b/app/src/main/res/layout/fragment_profile_posts.xml @@ -38,9 +38,24 @@ android:visibility="gone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" - tools:visibility="visible" + tools:visibility="gone" android:contentDescription="@string/post_is_album" /> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index db4c064a..572f2652 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -64,7 +64,7 @@ "Polls" "Other" - + "%d new notification" "%d new notifications" @@ -73,8 +73,6 @@ %1$s and %2$s - - "What's an instance?" "You might be confused by the text field asking for the domain of your 'instance'. @@ -174,6 +172,8 @@ For more info about Pixelfed, you can check here: https://pixelfed.org" Add a comment Submit comment This post is an album + This post is a video + "%d\nPost" @@ -259,4 +259,5 @@ For more info about Pixelfed, you can check here: https://pixelfed.org" Couldn\'t fetch latest notifications Camera permission not granted, grant the permission in settings if you want to let PixelDroid use the camera Storage permission not granted, grant the permission in settings if you want to let PixelDroid show the thumbnail + Play video \ No newline at end of file From 63362a031b5c7e211ced381c0b0b0702ac4c568b Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Mon, 14 Feb 2022 13:56:40 +0100 Subject: [PATCH 10/14] Only allow video upload when supported by instance --- .../app/postCreation/PostCreationActivity.kt | 29 ++++++++++--------- .../app/postCreation/camera/CameraFragment.kt | 9 ++++-- .../pixeldroid/app/utils/db/AppDatabase.kt | 7 ++++- .../org/pixeldroid/app/utils/db/DBUtils.kt | 16 +++++----- .../app/utils/db/dao/InstanceDao.kt | 3 ++ .../db/entities/InstanceDatabaseEntity.kt | 3 ++ .../pixeldroid/app/utils/di/DatabaseModule.kt | 4 ++- app/src/main/res/values/strings.xml | 1 + 8 files changed, 48 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/org/pixeldroid/app/postCreation/PostCreationActivity.kt b/app/src/main/java/org/pixeldroid/app/postCreation/PostCreationActivity.kt index 7a407ee1..1724b18a 100644 --- a/app/src/main/java/org/pixeldroid/app/postCreation/PostCreationActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/postCreation/PostCreationActivity.kt @@ -164,16 +164,17 @@ class PostCreationActivity : BaseActivity() { } for (i in 0 until count) { clipData.getItemAt(i).uri.let { - val size = it.getSize() + val size = it.getSizeAndValidate() photoData.add(PhotoData(imageUri = it, size = size)) } } } /** - * Returns the size of the file of the Uri, and opens a dialog in case it is too big. + * Returns the size of the file of the Uri, and opens a dialog in case it is too big or in case + * the file is unsupported. */ - private fun Uri.getSize(): Long { + private fun Uri.getSizeAndValidate(): Long { val size: Long = if (toString().startsWith("content")) { contentResolver.query(this, null, null, null, null) @@ -191,16 +192,18 @@ class PostCreationActivity : BaseActivity() { } val sizeInkBytes = ceil(size.toDouble() / 1000).toLong() + val type = contentResolver.getType(this) + val isVideo = type?.startsWith("video/") == true + + if(isVideo && !instance.videoEnabled){ + AlertDialog.Builder(this@PostCreationActivity).apply { + setMessage(R.string.video_not_supported) + setNegativeButton(android.R.string.ok) { _, _ -> } + }.show() + } + if (sizeInkBytes > instance.maxPhotoSize || sizeInkBytes > instance.maxVideoSize) { - val maxSize = when { - instance.maxPhotoSize != instance.maxVideoSize -> { - val type = contentResolver.getType(this) - if (type?.startsWith("video/") == true) { - instance.maxVideoSize - } else instance.maxPhotoSize - } - else -> instance.maxPhotoSize - } + val maxSize = if (isVideo) instance.maxVideoSize else instance.maxPhotoSize AlertDialog.Builder(this@PostCreationActivity).apply { setMessage(getString(R.string.size_exceeds_instance_limit, photoData.size + 1, sizeInkBytes, maxSize)) setNegativeButton(android.R.string.ok) { _, _ -> } @@ -429,7 +432,7 @@ class PostCreationActivity : BaseActivity() { val position: Int = result.data!!.getIntExtra(PhotoEditActivity.PICTURE_POSITION, 0) photoData.getOrNull(position)?.apply { imageUri = result.data!!.getStringExtra(PhotoEditActivity.PICTURE_URI)!!.toUri() - size = imageUri.getSize() + size = imageUri.getSizeAndValidate() progress = null uploadId = null } ?: Toast.makeText(applicationContext, "Error while editing", Toast.LENGTH_SHORT).show() diff --git a/app/src/main/java/org/pixeldroid/app/postCreation/camera/CameraFragment.kt b/app/src/main/java/org/pixeldroid/app/postCreation/camera/CameraFragment.kt index 0ce67cda..2fe264ba 100644 --- a/app/src/main/java/org/pixeldroid/app/postCreation/camera/CameraFragment.kt +++ b/app/src/main/java/org/pixeldroid/app/postCreation/camera/CameraFragment.kt @@ -41,6 +41,7 @@ import kotlin.math.max import kotlin.math.min import kotlin.properties.Delegates import org.pixeldroid.app.R +import org.pixeldroid.app.utils.BaseFragment private const val ANIMATION_FAST_MILLIS = 50L private const val ANIMATION_SLOW_MILLIS = 100L @@ -48,7 +49,7 @@ private const val ANIMATION_SLOW_MILLIS = 100L /** * Camera fragment */ -class CameraFragment : Fragment() { +class CameraFragment : BaseFragment() { private lateinit var container: ConstraintLayout @@ -314,11 +315,15 @@ class CameraFragment : Fragment() { } private fun setupUploadImage() { + val videoEnabled: Boolean = db.instanceDao().getInstance(db.userDao().getActiveUser()!!.instance_uri).videoEnabled + var mimeTypes: Array = arrayOf("image/*") + if(videoEnabled) mimeTypes += "video/*" + // Listener for button used to view the most recent photo binding.photoViewButton.setOnClickListener { Intent(Intent.ACTION_GET_CONTENT).apply { type = "*/*" - putExtra(Intent.EXTRA_MIME_TYPES, arrayOf("image/*", "video/*")) + putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes) action = Intent.ACTION_GET_CONTENT addCategory(Intent.CATEGORY_OPENABLE) putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true) diff --git a/app/src/main/java/org/pixeldroid/app/utils/db/AppDatabase.kt b/app/src/main/java/org/pixeldroid/app/utils/db/AppDatabase.kt index dc3f7b4e..0b76b6ef 100644 --- a/app/src/main/java/org/pixeldroid/app/utils/db/AppDatabase.kt +++ b/app/src/main/java/org/pixeldroid/app/utils/db/AppDatabase.kt @@ -22,7 +22,7 @@ import org.pixeldroid.app.utils.api.objects.Notification PublicFeedStatusDatabaseEntity::class, Notification::class ], - version = 4 + version = 5 ) @TypeConverters(Converters::class) abstract class AppDatabase : RoomDatabase() { @@ -39,4 +39,9 @@ val MIGRATION_3_4 = object : Migration(3, 4) { database.execSQL("DELETE FROM publicPosts") database.execSQL("DELETE FROM notifications") } +} +val MIGRATION_4_5 = object : Migration(4, 5) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE instances ADD COLUMN videoEnabled INTEGER NOT NULL DEFAULT 1") + } } \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/utils/db/DBUtils.kt b/app/src/main/java/org/pixeldroid/app/utils/db/DBUtils.kt index df33746e..40f52c76 100644 --- a/app/src/main/java/org/pixeldroid/app/utils/db/DBUtils.kt +++ b/app/src/main/java/org/pixeldroid/app/utils/db/DBUtils.kt @@ -9,6 +9,7 @@ import org.pixeldroid.app.utils.db.entities.InstanceDatabaseEntity.Companion.DEF import org.pixeldroid.app.utils.db.entities.InstanceDatabaseEntity.Companion.DEFAULT_MAX_PHOTO_SIZE import org.pixeldroid.app.utils.db.entities.InstanceDatabaseEntity.Companion.DEFAULT_MAX_TOOT_CHARS import org.pixeldroid.app.utils.db.entities.InstanceDatabaseEntity.Companion.DEFAULT_MAX_VIDEO_SIZE +import org.pixeldroid.app.utils.db.entities.InstanceDatabaseEntity.Companion.DEFAULT_VIDEO_ENABLED import org.pixeldroid.app.utils.normalizeDomain import java.lang.IllegalArgumentException @@ -33,13 +34,14 @@ fun addUser(db: AppDatabase, account: Account, instance_uri: String, activeUser: fun storeInstance(db: AppDatabase, nodeInfo: NodeInfo?, instance: Instance? = null) { val dbInstance: InstanceDatabaseEntity = nodeInfo?.run { InstanceDatabaseEntity( - uri = normalizeDomain(metadata?.config?.site?.url!!), - title = metadata.config.site.name!!, - maxStatusChars = metadata.config.uploader?.max_caption_length!!.toInt(), - maxPhotoSize = metadata.config.uploader.max_photo_size?.toIntOrNull() ?: DEFAULT_MAX_PHOTO_SIZE, - //Pixelfed doesn't distinguish between max photo and video size - maxVideoSize = metadata.config.uploader.max_photo_size?.toIntOrNull() ?: DEFAULT_MAX_VIDEO_SIZE, - albumLimit = metadata.config.uploader.album_limit?.toIntOrNull() ?: DEFAULT_ALBUM_LIMIT + uri = normalizeDomain(metadata?.config?.site?.url!!), + title = metadata.config.site.name!!, + maxStatusChars = metadata.config.uploader?.max_caption_length!!.toInt(), + maxPhotoSize = metadata.config.uploader.max_photo_size?.toIntOrNull() ?: DEFAULT_MAX_PHOTO_SIZE, + // Pixelfed doesn't distinguish between max photo and video size + maxVideoSize = metadata.config.uploader.max_photo_size?.toIntOrNull() ?: DEFAULT_MAX_VIDEO_SIZE, + albumLimit = metadata.config.uploader.album_limit?.toIntOrNull() ?: DEFAULT_ALBUM_LIMIT, + videoEnabled = metadata.config.features?.video ?: DEFAULT_VIDEO_ENABLED ) } ?: instance?.run { InstanceDatabaseEntity( diff --git a/app/src/main/java/org/pixeldroid/app/utils/db/dao/InstanceDao.kt b/app/src/main/java/org/pixeldroid/app/utils/db/dao/InstanceDao.kt index 59ee3771..3e51712c 100644 --- a/app/src/main/java/org/pixeldroid/app/utils/db/dao/InstanceDao.kt +++ b/app/src/main/java/org/pixeldroid/app/utils/db/dao/InstanceDao.kt @@ -8,6 +8,9 @@ interface InstanceDao { @Query("SELECT * FROM instances") fun getAll(): List + @Query("SELECT * FROM instances WHERE uri=:instanceUri LIMIT 1") + fun getInstance(instanceUri: String): InstanceDatabaseEntity + /** * Insert an instance, if it already exists return -1 */ diff --git a/app/src/main/java/org/pixeldroid/app/utils/db/entities/InstanceDatabaseEntity.kt b/app/src/main/java/org/pixeldroid/app/utils/db/entities/InstanceDatabaseEntity.kt index 58e71342..e387e02c 100644 --- a/app/src/main/java/org/pixeldroid/app/utils/db/entities/InstanceDatabaseEntity.kt +++ b/app/src/main/java/org/pixeldroid/app/utils/db/entities/InstanceDatabaseEntity.kt @@ -14,6 +14,8 @@ data class InstanceDatabaseEntity ( var maxVideoSize: Int = DEFAULT_MAX_VIDEO_SIZE, // How many photos can go into an album. Default limit for Pixelfed and Mastodon is 4 var albumLimit: Int = DEFAULT_ALBUM_LIMIT, + // Is video functionality enabled on this instance? + var videoEnabled: Boolean = DEFAULT_VIDEO_ENABLED, ) { companion object{ // Default max number of chars for Mastodon: used when their is no other value supplied by @@ -23,5 +25,6 @@ data class InstanceDatabaseEntity ( const val DEFAULT_MAX_PHOTO_SIZE = 8000 const val DEFAULT_MAX_VIDEO_SIZE = 40000 const val DEFAULT_ALBUM_LIMIT = 4 + const val DEFAULT_VIDEO_ENABLED = true } } \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/utils/di/DatabaseModule.kt b/app/src/main/java/org/pixeldroid/app/utils/di/DatabaseModule.kt index bc08dec5..4dd5c8c3 100644 --- a/app/src/main/java/org/pixeldroid/app/utils/di/DatabaseModule.kt +++ b/app/src/main/java/org/pixeldroid/app/utils/di/DatabaseModule.kt @@ -6,6 +6,7 @@ import org.pixeldroid.app.utils.db.AppDatabase import dagger.Module import dagger.Provides import org.pixeldroid.app.utils.db.MIGRATION_3_4 +import org.pixeldroid.app.utils.db.MIGRATION_4_5 import javax.inject.Singleton @Module @@ -17,6 +18,7 @@ class DatabaseModule(private val context: Context) { return Room.databaseBuilder( context, AppDatabase::class.java, "pixeldroid" - ).addMigrations(MIGRATION_3_4).allowMainThreadQueries().build() + ).addMigrations(MIGRATION_3_4).addMigrations(MIGRATION_4_5) + .allowMainThreadQueries().build() } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 572f2652..e9739025 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -114,6 +114,7 @@ For more info about Pixelfed, you can check here: https://pixelfed.org" Add a media description here… You chose more images than the maximum your server allows (%1$s). Images beyond the limit have been ignored. Size of image number %1$d in the album exceeds the maximum size allowed by the instance (%2$d kB but the limit is %3$d kB). You might not be able to upload it. + "The server you are using doesn't support video uploads, you might not be able to upload videos included in this post" Error code returned by server: %1$d From 03f83790f239e65aec1594203f36dbe55de4cc07 Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Wed, 16 Feb 2022 13:01:32 +0100 Subject: [PATCH 11/14] Rudimentary video support in PostCreationActivity --- .../app/postCreation/PostCreationActivity.kt | 54 +++++++++++-------- .../app/postCreation/SquareLayout.kt | 3 +- .../postCreation/carousel/CarouselAdapter.kt | 20 ++++++- .../app/postCreation/carousel/CarouselItem.kt | 7 ++- .../postCreation/carousel/ImageCarousel.kt | 2 +- .../app/posts/MediaViewerActivity.kt | 9 ++++ .../pixeldroid/app/posts/StatusViewHolder.kt | 13 +++-- .../java/org/pixeldroid/app/utils/Utils.kt | 1 + .../res/layout/add_more_album_creation.xml | 1 + .../main/res/layout/image_album_creation.xml | 22 ++++++-- app/src/main/res/layout/item_carousel.xml | 31 ++++++++--- app/src/main/res/values/strings.xml | 1 + 12 files changed, 117 insertions(+), 47 deletions(-) diff --git a/app/src/main/java/org/pixeldroid/app/postCreation/PostCreationActivity.kt b/app/src/main/java/org/pixeldroid/app/postCreation/PostCreationActivity.kt index 1724b18a..72e83164 100644 --- a/app/src/main/java/org/pixeldroid/app/postCreation/PostCreationActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/postCreation/PostCreationActivity.kt @@ -50,11 +50,12 @@ import kotlin.math.ceil private const val TAG = "Post Creation Activity" data class PhotoData( - var imageUri: Uri, - var size: Long, - var uploadId: String? = null, - var progress: Int? = null, - var imageDescription: String? = null, + var imageUri: Uri, + var size: Long, + var uploadId: String? = null, + var progress: Int? = null, + var imageDescription: String? = null, + var video: Boolean, ) class PostCreationActivity : BaseActivity() { @@ -85,7 +86,7 @@ class PostCreationActivity : BaseActivity() { intent.clipData?.let { addPossibleImages(it) } val carousel: ImageCarousel = binding.carousel - carousel.addData(photoData.map { CarouselItem(it.imageUri) }) + carousel.addData(photoData.map { CarouselItem(it.imageUri, video = it.video) }) carousel.layoutCarouselCallback = { if(it){ // Became a carousel @@ -138,7 +139,7 @@ class PostCreationActivity : BaseActivity() { binding.removePhotoButton.setOnClickListener { carousel.currentPosition.takeIf { it != -1 }?.let { currentPosition -> photoData.removeAt(currentPosition) - carousel.addData(photoData.map { CarouselItem(it.imageUri, it.imageDescription) }) + carousel.addData(photoData.map { CarouselItem(it.imageUri, it.imageDescription, it.video) }) binding.addPhotoButton.isEnabled = true } } @@ -164,17 +165,17 @@ class PostCreationActivity : BaseActivity() { } for (i in 0 until count) { clipData.getItemAt(i).uri.let { - val size = it.getSizeAndValidate() - photoData.add(PhotoData(imageUri = it, size = size)) + val sizeAndVideoPair: Pair = it.getSizeAndVideoValidate() + photoData.add(PhotoData(imageUri = it, size = sizeAndVideoPair.first, video = sizeAndVideoPair.second)) } } } /** - * Returns the size of the file of the Uri, and opens a dialog in case it is too big or in case - * the file is unsupported. + * Returns the size of the file of the Uri, and whether it is a video, + * and opens a dialog in case it is too big or in case the file is unsupported. */ - private fun Uri.getSizeAndValidate(): Long { + private fun Uri.getSizeAndVideoValidate(): Pair { val size: Long = if (toString().startsWith("content")) { contentResolver.query(this, null, null, null, null) @@ -209,7 +210,7 @@ class PostCreationActivity : BaseActivity() { setNegativeButton(android.R.string.ok) { _, _ -> } }.show() } - return size + return Pair(size, isVideo) } private val addPhotoResultContract = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> @@ -217,7 +218,7 @@ class PostCreationActivity : BaseActivity() { result.data?.clipData?.let { addPossibleImages(it) } - binding.carousel.addData(photoData.map { CarouselItem(it.imageUri, it.imageDescription) }) + binding.carousel.addData(photoData.map { CarouselItem(it.imageUri, it.imageDescription, it.video) }) } else if (result.resultCode != Activity.RESULT_CANCELED) { Toast.makeText(applicationContext, "Error while adding images", Toast.LENGTH_SHORT).show() } @@ -309,8 +310,8 @@ class PostCreationActivity : BaseActivity() { */ private fun upload() { enableButton(false) - binding.uploadProgressBar.visibility = View.VISIBLE - binding.uploadCompletedTextview.visibility = View.INVISIBLE + binding.uploadProgressBar.visibility = VISIBLE + binding.uploadCompletedTextview.visibility = INVISIBLE binding.removePhotoButton.isEnabled = false binding.editPhotoButton.isEnabled = false binding.addPhotoButton.isEnabled = false @@ -432,21 +433,30 @@ class PostCreationActivity : BaseActivity() { val position: Int = result.data!!.getIntExtra(PhotoEditActivity.PICTURE_POSITION, 0) photoData.getOrNull(position)?.apply { imageUri = result.data!!.getStringExtra(PhotoEditActivity.PICTURE_URI)!!.toUri() - size = imageUri.getSizeAndValidate() + val (imageSize, imageVideo) = imageUri.getSizeAndVideoValidate() + size = imageSize + video = imageVideo progress = null uploadId = null } ?: Toast.makeText(applicationContext, "Error while editing", Toast.LENGTH_SHORT).show() - binding.carousel.addData(photoData.map { CarouselItem(it.imageUri, it.imageDescription) }) + binding.carousel.addData(photoData.map { CarouselItem(it.imageUri, it.imageDescription, it.video) }) } else if(result?.resultCode != Activity.RESULT_CANCELED){ Toast.makeText(applicationContext, "Error while editing", Toast.LENGTH_SHORT).show() } } private fun edit(position: Int) { - val intent = Intent(this, PhotoEditActivity::class.java) - .putExtra(PhotoEditActivity.PICTURE_URI, photoData[position].imageUri) - .putExtra(PhotoEditActivity.PICTURE_POSITION, position) - editResultContract.launch(intent) + if(photoData[position].video){ + AlertDialog.Builder(this).apply { + setMessage(R.string.video_edit_not_yet_supported) + setNegativeButton(android.R.string.ok) { _, _ -> } + }.show() + } else { + val intent = Intent(this, PhotoEditActivity::class.java) + .putExtra(PhotoEditActivity.PICTURE_URI, photoData[position].imageUri) + .putExtra(PhotoEditActivity.PICTURE_POSITION, position) + editResultContract.launch(intent) + } } } \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/postCreation/SquareLayout.kt b/app/src/main/java/org/pixeldroid/app/postCreation/SquareLayout.kt index cbee61a6..f024d76b 100644 --- a/app/src/main/java/org/pixeldroid/app/postCreation/SquareLayout.kt +++ b/app/src/main/java/org/pixeldroid/app/postCreation/SquareLayout.kt @@ -2,10 +2,11 @@ package org.pixeldroid.app.postCreation import android.content.Context import android.util.AttributeSet +import android.widget.FrameLayout import android.widget.RelativeLayout internal class SquareLayout(context: Context, attrs: AttributeSet) : - RelativeLayout(context, attrs) { + FrameLayout(context, attrs) { override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { super.onMeasure(widthMeasureSpec, widthMeasureSpec) diff --git a/app/src/main/java/org/pixeldroid/app/postCreation/carousel/CarouselAdapter.kt b/app/src/main/java/org/pixeldroid/app/postCreation/carousel/CarouselAdapter.kt index ca2c6384..e61febde 100644 --- a/app/src/main/java/org/pixeldroid/app/postCreation/carousel/CarouselAdapter.kt +++ b/app/src/main/java/org/pixeldroid/app/postCreation/carousel/CarouselAdapter.kt @@ -3,13 +3,17 @@ package org.pixeldroid.app.postCreation.carousel import android.graphics.drawable.Drawable import android.view.LayoutInflater import android.view.View +import android.view.View.GONE +import android.view.View.VISIBLE import android.view.ViewGroup +import android.widget.ImageButton import android.widget.ImageView import androidx.annotation.IdRes import androidx.annotation.LayoutRes import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import org.pixeldroid.app.R +import org.pixeldroid.app.posts.MediaViewerActivity class CarouselAdapter( @@ -26,6 +30,8 @@ class CarouselAdapter( class MyViewHolder(itemView: View, imageViewId: Int) : RecyclerView.ViewHolder(itemView) { var img: ImageView = itemView.findViewById(imageViewId) + // Null if not relevant + val videoIndicator: ImageButton? = itemView.findViewById(R.id.videoIndicator) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder { @@ -60,10 +66,21 @@ class CarouselAdapter( } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { - if(carousel) { + if (carousel) { holder.img.scaleType = imageScaleType + holder.videoIndicator?.setOnClickListener{ + with(dataList[position]) { + MediaViewerActivity.openActivity( + holder.itemView.context, + imageUrl.toString(), + caption + ) + } + } } + holder.videoIndicator?.visibility = if (dataList[position].video) VISIBLE else GONE + dataList.elementAtOrNull(position)?.let { Glide.with(holder.itemView.context) .load(it.imageUrl) @@ -83,7 +100,6 @@ class CarouselAdapter( true } - } } diff --git a/app/src/main/java/org/pixeldroid/app/postCreation/carousel/CarouselItem.kt b/app/src/main/java/org/pixeldroid/app/postCreation/carousel/CarouselItem.kt index 4e6f854e..37dfda86 100644 --- a/app/src/main/java/org/pixeldroid/app/postCreation/carousel/CarouselItem.kt +++ b/app/src/main/java/org/pixeldroid/app/postCreation/carousel/CarouselItem.kt @@ -4,7 +4,6 @@ import android.net.Uri data class CarouselItem constructor( val imageUrl: Uri, - val caption: String? = null -) { - constructor(imageUrl: Uri) : this(imageUrl, null) -} \ No newline at end of file + val caption: String? = null, + val video: Boolean +) \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/postCreation/carousel/ImageCarousel.kt b/app/src/main/java/org/pixeldroid/app/postCreation/carousel/ImageCarousel.kt index a95ed00d..5b628b3f 100644 --- a/app/src/main/java/org/pixeldroid/app/postCreation/carousel/ImageCarousel.kt +++ b/app/src/main/java/org/pixeldroid/app/postCreation/carousel/ImageCarousel.kt @@ -49,7 +49,7 @@ class ImageCarousel( var indicator: CircleIndicator2? = null set(newIndicator) { indicator?.apply { - // if we remove it form the view, then the caption textView constraint won't work. + // if we remove it from the view, then the caption textView constraint won't work. this.visibility = View.GONE isBuiltInIndicator = false diff --git a/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt b/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt index 5ac282af..2ca2e423 100644 --- a/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/posts/MediaViewerActivity.kt @@ -1,5 +1,7 @@ package org.pixeldroid.app.posts +import android.content.Context +import android.content.Intent import android.os.Bundle import androidx.core.net.toUri import androidx.media2.common.MediaMetadata @@ -15,6 +17,13 @@ class MediaViewerActivity : BaseActivity() { companion object { const val VIDEO_URL_TAG = "video_url_mediavieweractivity" const val VIDEO_DESCRIPTION_TAG = "video_description_mediavieweractivity" + + fun openActivity(context: Context, url: String?, description: String?){ + val intent = Intent(context, MediaViewerActivity::class.java) + intent.putExtra(VIDEO_URL_TAG, url) + intent.putExtra(VIDEO_DESCRIPTION_TAG, description) + context.startActivity(intent) + } } override fun onCreate(savedInstanceState: Bundle?) { diff --git a/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt b/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt index 62891e34..a1127538 100644 --- a/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt +++ b/app/src/main/java/org/pixeldroid/app/posts/StatusViewHolder.kt @@ -39,6 +39,7 @@ import com.karumi.dexter.listener.single.BasePermissionListener import kotlinx.coroutines.launch import org.pixeldroid.app.posts.MediaViewerActivity.Companion.VIDEO_DESCRIPTION_TAG import org.pixeldroid.app.posts.MediaViewerActivity.Companion.VIDEO_URL_TAG +import org.pixeldroid.app.posts.MediaViewerActivity.Companion.openActivity import retrofit2.HttpException import java.io.IOException import kotlin.math.roundToInt @@ -620,14 +621,12 @@ private class AlbumViewPagerAdapter(private val media_attachments: List decoder.isMutableRequired = true } } else { + @Suppress("DEPRECATION") val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, uri) modifyOrientation(bitmap!!, contentResolver, uri!!) } diff --git a/app/src/main/res/layout/add_more_album_creation.xml b/app/src/main/res/layout/add_more_album_creation.xml index 9b6b498d..65be5e0b 100644 --- a/app/src/main/res/layout/add_more_album_creation.xml +++ b/app/src/main/res/layout/add_more_album_creation.xml @@ -10,6 +10,7 @@ android:id="@+id/addPhotoSquare" android:layout_width="50dp" android:layout_height="50dp" + android:layout_gravity="center" android:layout_centerInParent="true" android:layout_centerVertical="true" android:background="@drawable/add_photo_button" diff --git a/app/src/main/res/layout/image_album_creation.xml b/app/src/main/res/layout/image_album_creation.xml index 1409a55e..974cfd55 100644 --- a/app/src/main/res/layout/image_album_creation.xml +++ b/app/src/main/res/layout/image_album_creation.xml @@ -1,15 +1,29 @@ + android:focusable="true" + android:foreground="?selectableItemBackground"> + + android:scaleType="centerCrop" /> + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_carousel.xml b/app/src/main/res/layout/item_carousel.xml index 85b4fef0..04d83070 100644 --- a/app/src/main/res/layout/item_carousel.xml +++ b/app/src/main/res/layout/item_carousel.xml @@ -1,9 +1,28 @@ - + android:layout_height="match_parent"> + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e9739025..885c39c2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -261,4 +261,5 @@ For more info about Pixelfed, you can check here: https://pixelfed.org" Camera permission not granted, grant the permission in settings if you want to let PixelDroid use the camera Storage permission not granted, grant the permission in settings if you want to let PixelDroid show the thumbnail Play video + Video editing is not yet supported \ No newline at end of file From 77c895bbf2d52e10741b71d43daaff8aaeafc958 Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Thu, 17 Feb 2022 12:08:57 +0100 Subject: [PATCH 12/14] Audio and fullscreen video --- app/src/main/AndroidManifest.xml | 1 + .../app/posts/MediaViewerActivity.kt | 53 ++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 447f538c..cfcdb8c7 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,6 +25,7 @@ + val windowInsetsController = ViewCompat.getWindowInsetsController(window.decorView) + if (!fullscreen) { + // Configure the behavior of the hidden system bars + windowInsetsController?.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + // Hide both the status bar and the navigation bar + windowInsetsController?.show(WindowInsetsCompat.Type.systemBars()) + supportActionBar?.show() + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED + } else { + // Configure the behavior of the hidden system bars + windowInsetsController?.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE + // Hide both the status bar and the navigation bar + windowInsetsController?.hide(WindowInsetsCompat.Type.systemBars()) + + requestedOrientation = + if (mediaPlayer.videoSize.height < mediaPlayer.videoSize.width) { + ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE + } else { + ActivityInfo.SCREEN_ORIENTATION_PORTRAIT + } + supportActionBar?.hide() + } + } + + // Configure audio + mediaPlayer.setAudioAttributes(AudioAttributesCompat.Builder() + .setLegacyStreamType(STREAM_MUSIC) + .setUsage(AudioAttributesCompat.USAGE_MEDIA) + .setContentType(AudioAttributesCompat.CONTENT_TYPE_MOVIE) + .build() + ) + mediaPlayer.prepare() binding.videoView.setPlayer(mediaPlayer) @@ -48,4 +89,14 @@ class MediaViewerActivity : BaseActivity() { // Start actually playing the video mediaPlayer.play() } + + override fun onPause() { + super.onPause() + mediaPlayer.pause() + } + + override fun onDestroy() { + super.onDestroy() + mediaPlayer.close() + } } \ No newline at end of file From 1462cc052ed51cda624ab3a4d2b86b1fc5bdda07 Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Thu, 17 Feb 2022 13:09:42 +0100 Subject: [PATCH 13/14] Release 8 --- app/build.gradle | 4 ++-- fastlane/metadata/android/en-US/changelogs/8.txt | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 fastlane/metadata/android/en-US/changelogs/8.txt diff --git a/app/build.gradle b/app/build.gradle index 62a5e53d..db0db74a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,8 +28,8 @@ android { applicationId "org.pixeldroid.app" minSdkVersion 23 targetSdkVersion 31 - versionCode 7 - versionName "1.0.beta7" + versionCode 8 + versionName "1.0.beta8" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunnerArguments clearPackageData: 'true' diff --git a/fastlane/metadata/android/en-US/changelogs/8.txt b/fastlane/metadata/android/en-US/changelogs/8.txt new file mode 100644 index 00000000..6a07a0e1 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/8.txt @@ -0,0 +1,4 @@ +* Add support for video playback and upload +* Notification improvements +* Translation updates +* Update dependencies From e70ee1a616b592894633f192bd7272e3996e5395 Mon Sep 17 00:00:00 2001 From: Matthieu <24-artectrex@users.noreply.shinice.net> Date: Mon, 28 Feb 2022 11:42:04 +0100 Subject: [PATCH 14/14] Fix license crash by adding proguard rules --- app/proguard-rules.pro | 7 ++++++ .../app/settings/LicenseActivity.kt | 10 ++++---- .../app/settings/OpenSourceLicenseAdapter.kt | 24 +++---------------- .../app/settings/licenseObjects/Libraries.kt | 5 ++++ .../settings/licenseObjects/OpenSourceItem.kt | 10 ++++++++ 5 files changed, 30 insertions(+), 26 deletions(-) create mode 100644 app/src/main/java/org/pixeldroid/app/settings/licenseObjects/Libraries.kt create mode 100644 app/src/main/java/org/pixeldroid/app/settings/licenseObjects/OpenSourceItem.kt diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index db0002be..5a817e2b 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -44,6 +44,13 @@ public *; } +-keepclassmembers class org.pixeldroid.app.settings.licenseObjects.* { *; } + +-keep public enum org.pixeldroid.app.settings.licenseObjects.*$** { + **[] $VALUES; + public *; +} + # preserve line numbers for crash reporting -keepattributes SourceFile,LineNumberTable -renamesourcefileattribute SourceFile diff --git a/app/src/main/java/org/pixeldroid/app/settings/LicenseActivity.kt b/app/src/main/java/org/pixeldroid/app/settings/LicenseActivity.kt index a4cce6cc..795ab47b 100644 --- a/app/src/main/java/org/pixeldroid/app/settings/LicenseActivity.kt +++ b/app/src/main/java/org/pixeldroid/app/settings/LicenseActivity.kt @@ -4,7 +4,10 @@ import android.os.Bundle import com.google.gson.Gson import org.pixeldroid.app.R import org.pixeldroid.app.databinding.OpenSourceLicenseBinding +import org.pixeldroid.app.settings.licenseObjects.Libraries +import org.pixeldroid.app.settings.licenseObjects.OpenSourceItem import org.pixeldroid.app.utils.BaseActivity +import java.io.FileNotFoundException /** * Displays licenses for all app dependencies. JSON is @@ -30,13 +33,10 @@ class LicenseActivity: BaseActivity() { private fun setupRecyclerView() { val text: String = applicationContext.assets.open("licenses.json") .bufferedReader().use { it.readText() } + val listObj: List = Gson().fromJson(text, Libraries::class.java).libraries - val adapter = OpenSourceLicenseAdapter() + val adapter = OpenSourceLicenseAdapter(listObj) binding.openSourceLicenseRecyclerView.adapter = adapter - - - adapter.updateList(listObj) - } } \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/settings/OpenSourceLicenseAdapter.kt b/app/src/main/java/org/pixeldroid/app/settings/OpenSourceLicenseAdapter.kt index c5edec13..c474ab17 100644 --- a/app/src/main/java/org/pixeldroid/app/settings/OpenSourceLicenseAdapter.kt +++ b/app/src/main/java/org/pixeldroid/app/settings/OpenSourceLicenseAdapter.kt @@ -7,18 +7,11 @@ import android.view.ViewGroup import androidx.core.view.isVisible import androidx.recyclerview.widget.RecyclerView import org.pixeldroid.app.databinding.OpenSourceItemBinding +import org.pixeldroid.app.settings.licenseObjects.OpenSourceItem -class OpenSourceLicenseAdapter : +class OpenSourceLicenseAdapter(private val openSourceItems: List) : RecyclerView.Adapter() { - private var openSourceItems: List = emptyList() - - @SuppressLint("NotifyDataSetChanged") - fun updateList(newOpenSourceItems: List) { - openSourceItems = newOpenSourceItems - notifyDataSetChanged() - } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OpenSourceLicenceViewHolder { val itemBinding = OpenSourceItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) @@ -67,15 +60,4 @@ class OpenSourceLicenseAdapter : } } } -} -data class OpenSourceItem( - val libraryName: String?, - val copyrightHolder: String?, - val url: String?, - val license: String?, - val licenseUrl: String?, -) - -data class Libraries( - val libraries: List -) \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/settings/licenseObjects/Libraries.kt b/app/src/main/java/org/pixeldroid/app/settings/licenseObjects/Libraries.kt new file mode 100644 index 00000000..2695456a --- /dev/null +++ b/app/src/main/java/org/pixeldroid/app/settings/licenseObjects/Libraries.kt @@ -0,0 +1,5 @@ +package org.pixeldroid.app.settings.licenseObjects + +data class Libraries( + val libraries: List +) \ No newline at end of file diff --git a/app/src/main/java/org/pixeldroid/app/settings/licenseObjects/OpenSourceItem.kt b/app/src/main/java/org/pixeldroid/app/settings/licenseObjects/OpenSourceItem.kt new file mode 100644 index 00000000..4bcb0223 --- /dev/null +++ b/app/src/main/java/org/pixeldroid/app/settings/licenseObjects/OpenSourceItem.kt @@ -0,0 +1,10 @@ +package org.pixeldroid.app.settings.licenseObjects + + +data class OpenSourceItem( + val libraryName: String?, + val copyrightHolder: String?, + val url: String?, + val license: String?, + val licenseUrl: String?, +) \ No newline at end of file