diff --git a/build.gradle b/build.gradle
index 4125ec44..556e0877 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,9 +1,7 @@
import com.android.build.gradle.AppExtension
import com.android.build.gradle.api.ApkVariantOutput
import com.android.build.gradle.api.ApplicationVariant
-
-apply plugin: 'com.android.application'
-apply plugin: 'kotlin-android'
+import com.github.jk1.license.render.TextReportRenderer
buildscript {
ext.kotlin_version = '1.4.21'
@@ -19,6 +17,14 @@ buildscript {
}
}
+plugins {
+ id 'com.github.jk1.dependency-license-report' version '1.16'
+}
+def licenseResDir = new File("$projectDir/build/dependency-license-res")
+
+apply plugin: 'com.android.application'
+apply plugin: 'kotlin-android'
+
android {
compileSdkVersion 29
defaultConfig {
@@ -49,7 +55,7 @@ android {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['resources']
- res.srcDirs = ['res']
+ res.srcDirs = ['res', licenseResDir]
assets.srcDirs = ['assets']
}
test {
@@ -203,3 +209,16 @@ repositories {
google()
mavenCentral()
}
+
+licenseReport {
+ configurations = ALL
+ renderers = [new TextReportRenderer()]
+}
+generateLicenseReport.doLast {
+ def target = new File(licenseResDir, "raw/license")
+ target.parentFile.mkdirs()
+ target.text =
+ files("COPYING", "$projectDir/build/reports/dependency-license/THIRD-PARTY-NOTICES.txt")
+ .collect { it.getText() }.join('\n')
+}
+preBuild.dependsOn(generateLicenseReport)
diff --git a/res/drawable/ic_baseline_attach_money_24.xml b/res/drawable/ic_baseline_attach_money_24.xml
new file mode 100644
index 00000000..fecf0313
--- /dev/null
+++ b/res/drawable/ic_baseline_attach_money_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/res/drawable/ic_baseline_bug_report_24.xml b/res/drawable/ic_baseline_bug_report_24.xml
new file mode 100644
index 00000000..7853f61c
--- /dev/null
+++ b/res/drawable/ic_baseline_bug_report_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/res/drawable/ic_baseline_code_24.xml b/res/drawable/ic_baseline_code_24.xml
new file mode 100644
index 00000000..b97ee53f
--- /dev/null
+++ b/res/drawable/ic_baseline_code_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/res/drawable/ic_baseline_gavel_24.xml b/res/drawable/ic_baseline_gavel_24.xml
new file mode 100644
index 00000000..cbe17b2e
--- /dev/null
+++ b/res/drawable/ic_baseline_gavel_24.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 446bb62c..3c6119a5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -420,5 +420,12 @@
- light
- dark
+ Report Bug
+ https://bugs.kde.org/enter_bug.cgi?product=kdeconnect&component=android-application
+ Donate
+ https://kde.org/community/donations/?app=kdeconnect-android
+ Source Code
+ https://invent.kde.org/network/kdeconnect-android/
+ Licenses
diff --git a/src/org/kde/kdeconnect/UserInterface/SettingsFragment.java b/src/org/kde/kdeconnect/UserInterface/SettingsFragment.java
index 47bd7368..0f7f0adc 100644
--- a/src/org/kde/kdeconnect/UserInterface/SettingsFragment.java
+++ b/src/org/kde/kdeconnect/UserInterface/SettingsFragment.java
@@ -1,9 +1,11 @@
package org.kde.kdeconnect.UserInterface;
+import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Color;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
@@ -18,13 +20,45 @@ import androidx.preference.ListPreference;
import com.google.android.material.snackbar.Snackbar;
+import org.apache.commons.io.IOUtils;
import org.kde.kdeconnect.BackgroundService;
import org.kde.kdeconnect.Helpers.DeviceHelper;
import org.kde.kdeconnect.Helpers.NotificationHelper;
import org.kde.kdeconnect_tp.R;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
public class SettingsFragment extends PreferenceFragmentCompat {
+ private static class LicenseTextSingleton {
+ private static volatile String licenseText;
+
+ // Need these separate methods because Context is required to load the string
+ // Mixing Context and static here is fine because the license
+ // is a pure function of the project directory (i.e. doesn't depend on language, etc.)
+
+ static synchronized String getOrLoadLicenseText(Context context) {
+ String licenseText = LicenseTextSingleton.licenseText;
+ if (licenseText != null) {
+ return licenseText;
+ }
+ try (InputStream is = context.getResources().openRawResource(R.raw.license)) {
+ licenseText = IOUtils.toString(is, Charset.defaultCharset());
+ } catch (IOException ie) {
+ throw new RuntimeException(ie);
+ }
+ return LicenseTextSingleton.licenseText = licenseText;
+ }
+
+ static synchronized void startLoadingLicenseText(Context context) {
+ if (licenseText == null) {
+ new Thread(() -> getOrLoadLicenseText(context)).start();
+ }
+ }
+ }
+
private EditTextPreference renameDevice;
@Override
@@ -153,6 +187,40 @@ public class SettingsFragment extends PreferenceFragmentCompat {
moreSettingsText.setSummary(R.string.settings_more_settings_text);
screen.addPreference(moreSettingsText);
+ Preference bug = new Preference(context);
+ bug.setTitle(R.string.report_bug);
+ bug.setPersistent(false);
+ bug.setIcon(R.drawable.ic_baseline_bug_report_24);
+ bug.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.report_bug_url))));
+ screen.addPreference(bug);
+
+ Preference donate = new Preference(context);
+ donate.setTitle(R.string.donate);
+ donate.setPersistent(false);
+ donate.setIcon(R.drawable.ic_baseline_attach_money_24);
+ donate.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.donate_url))));
+ screen.addPreference(donate);
+
+ Preference source = new Preference(context);
+ source.setTitle(R.string.source_code);
+ source.setPersistent(false);
+ source.setIcon(R.drawable.ic_baseline_code_24);
+ source.setIntent(new Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.source_code_url))));
+ screen.addPreference(source);
+
+ Preference licences = new Preference(context);
+ licences.setTitle(R.string.licenses);
+ licences.setPersistent(false);
+ licences.setIcon(R.drawable.ic_baseline_gavel_24);
+ licences.setOnPreferenceClickListener(preference -> {
+ new AlertDialog.Builder(context)
+ .setMessage(LicenseTextSingleton.getOrLoadLicenseText(context))
+ .create().show();
+ return true;
+ });
+ LicenseTextSingleton.startLoadingLicenseText(context);
+ screen.addPreference(licences);
+
setPreferenceScreen(screen);