Added licenses screen
This commit is contained in:
parent
b401c5b64b
commit
d9e122f6d2
|
@ -0,0 +1,111 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<libraries>
|
||||||
|
<library
|
||||||
|
name="AntennaPod"
|
||||||
|
author="The AntennaPod team"
|
||||||
|
website="https://github.com/AntennaPod/AntennaPod/"
|
||||||
|
license="MIT"
|
||||||
|
licenseText="LICENSE.txt" />
|
||||||
|
<library
|
||||||
|
name="AntennaPod-AudioPlayer"
|
||||||
|
author="The AntennaPod team"
|
||||||
|
website="https://github.com/AntennaPod/AntennaPod-AudioPlayer/"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_APACHE-2.0.txt" />
|
||||||
|
<library
|
||||||
|
name="Apache Commons"
|
||||||
|
author="The Apache Software Foundation"
|
||||||
|
website="http://commons.apache.org/"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_APACHE-2.0.txt" />
|
||||||
|
<library
|
||||||
|
name="EventBus"
|
||||||
|
author="greenrobot"
|
||||||
|
website="https://github.com/greenrobot/EventBus"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_APACHE-2.0.txt" />
|
||||||
|
<library
|
||||||
|
name="ExoPlayer"
|
||||||
|
author="Google"
|
||||||
|
website="https://github.com/google/ExoPlayer"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_APACHE-2.0.txt" />
|
||||||
|
<library
|
||||||
|
name="Floating Action Button Speed Dial"
|
||||||
|
author="Roberto Leinardi"
|
||||||
|
website="https://github.com/leinardi/FloatingActionButtonSpeedDial"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_APACHE-2.0.txt" />
|
||||||
|
<library
|
||||||
|
name="Glide"
|
||||||
|
author="bumptech"
|
||||||
|
website="https://github.com/bumptech/glide/"
|
||||||
|
license="Simplified BSD"
|
||||||
|
licenseText="LICENSE_GLIDE.txt" />
|
||||||
|
<library
|
||||||
|
name="Iconify"
|
||||||
|
author="Joan Zapata"
|
||||||
|
website="https://github.com/JoanZapata/android-iconify"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_ANDROID_ICONIFY.txt" />
|
||||||
|
<library
|
||||||
|
name="jsoup"
|
||||||
|
author="Jonathan Hedley"
|
||||||
|
website="http://jsoup.org/"
|
||||||
|
license="MIT"
|
||||||
|
licenseText="LICENSE_JSOUP.txt" />
|
||||||
|
<library
|
||||||
|
name="Material Design Icons"
|
||||||
|
author="Google"
|
||||||
|
website="https://github.com/google/material-design-icons"
|
||||||
|
license="Attribution-ShareAlike 4.0 International"
|
||||||
|
licenseText="LICENSE_MATERIAL_DESIGN_ICONS.txt" />
|
||||||
|
<library
|
||||||
|
name="Material Design Icons"
|
||||||
|
author="Templarian"
|
||||||
|
website="https://github.com/Templarian/MaterialDesign"
|
||||||
|
license="SIL Open Font, Version 1.1"
|
||||||
|
licenseText="LICENSE_SIL.txt" />
|
||||||
|
<library
|
||||||
|
name="OkHttp"
|
||||||
|
author="Square"
|
||||||
|
website="https://github.com/square/okhttp"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_OKHTTP.txt" />
|
||||||
|
<library
|
||||||
|
name="Okio"
|
||||||
|
author="Square"
|
||||||
|
website="https://github.com/square/okio"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_APACHE-2.0.txt" />
|
||||||
|
<library
|
||||||
|
name="Presto Client"
|
||||||
|
author="aocate"
|
||||||
|
website="http://www.aocate.com/presto/"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_PRESTO.txt" />
|
||||||
|
<library
|
||||||
|
name="RecyclerView-FlexibleDivider"
|
||||||
|
author="yqritc"
|
||||||
|
website="https://github.com/yqritc/RecyclerView-FlexibleDivider"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_APACHE-2.0.txt" />
|
||||||
|
<library
|
||||||
|
name="RxAndroid"
|
||||||
|
author="ReactiveX"
|
||||||
|
website="https://github.com/ReactiveX/RxAndroid"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_APACHE-2.0.txt" />
|
||||||
|
<library
|
||||||
|
name="StackBlur"
|
||||||
|
author="Enrique López Mañas"
|
||||||
|
website="https://github.com/kikoso/android-stackblur"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_APACHE-2.0.txt" />
|
||||||
|
<library
|
||||||
|
name="Triangle Label View"
|
||||||
|
author="Shota Saito"
|
||||||
|
website="https://github.com/shts/TriangleLabelView"
|
||||||
|
license="Apache 2.0"
|
||||||
|
licenseText="LICENSE_TRIANGLE_LABEL_VIEW.txt" />
|
||||||
|
</libraries>
|
|
@ -11,19 +11,19 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||||
import com.bumptech.glide.request.RequestOptions;
|
import com.bumptech.glide.request.RequestOptions;
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays a list of items that have a subtitle and an icon.
|
* Displays a list of items that have a subtitle and an icon.
|
||||||
*/
|
*/
|
||||||
public class SimpleIconListAdapter extends ArrayAdapter<SimpleIconListAdapter.ListItem> {
|
public class SimpleIconListAdapter<T extends SimpleIconListAdapter.ListItem> extends ArrayAdapter<T> {
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final ArrayList<ListItem> developers;
|
private final List<T> listItems;
|
||||||
|
|
||||||
public SimpleIconListAdapter(Context context, ArrayList<ListItem> developers) {
|
public SimpleIconListAdapter(Context context, List<T> listItems) {
|
||||||
super(context, R.layout.simple_icon_list_item, developers);
|
super(context, R.layout.simple_icon_list_item, listItems);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.developers = developers;
|
this.listItems = listItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -32,7 +32,7 @@ public class SimpleIconListAdapter extends ArrayAdapter<SimpleIconListAdapter.Li
|
||||||
view = View.inflate(context, R.layout.simple_icon_list_item, null);
|
view = View.inflate(context, R.layout.simple_icon_list_item, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
ListItem item = developers.get(position);
|
ListItem item = listItems.get(position);
|
||||||
((TextView) view.findViewById(R.id.title)).setText(item.title);
|
((TextView) view.findViewById(R.id.title)).setText(item.title);
|
||||||
((TextView) view.findViewById(R.id.subtitle)).setText(item.subtitle);
|
((TextView) view.findViewById(R.id.subtitle)).setText(item.subtitle);
|
||||||
Glide.with(context)
|
Glide.with(context)
|
||||||
|
@ -46,9 +46,9 @@ public class SimpleIconListAdapter extends ArrayAdapter<SimpleIconListAdapter.Li
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ListItem {
|
public static class ListItem {
|
||||||
final String title;
|
public final String title;
|
||||||
final String subtitle;
|
public final String subtitle;
|
||||||
final String imageUrl;
|
public final String imageUrl;
|
||||||
|
|
||||||
public ListItem(String title, String subtitle, String imageUrl) {
|
public ListItem(String title, String subtitle, String imageUrl) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class AboutDevelopersFragment extends ListFragment {
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
developers -> setListAdapter(new SimpleIconListAdapter(getContext(), developers)),
|
developers -> setListAdapter(new SimpleIconListAdapter<>(getContext(), developers)),
|
||||||
error -> Toast.makeText(getContext(), "Error while loading developers", Toast.LENGTH_LONG).show()
|
error -> Toast.makeText(getContext(), "Error while loading developers", Toast.LENGTH_LONG).show()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.google.android.material.snackbar.Snackbar;
|
||||||
import de.danoeh.antennapod.BuildConfig;
|
import de.danoeh.antennapod.BuildConfig;
|
||||||
import de.danoeh.antennapod.R;
|
import de.danoeh.antennapod.R;
|
||||||
import de.danoeh.antennapod.activity.PreferenceActivity;
|
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||||
|
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||||
|
|
||||||
public class AboutFragment extends PreferenceFragmentCompat {
|
public class AboutFragment extends PreferenceFragmentCompat {
|
||||||
|
|
||||||
|
@ -36,6 +37,15 @@ public class AboutFragment extends PreferenceFragmentCompat {
|
||||||
.addToBackStack(getString(R.string.translators)).commit();
|
.addToBackStack(getString(R.string.translators)).commit();
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
findPreference("about_privacy_policy").setOnPreferenceClickListener((preference) -> {
|
||||||
|
IntentUtils.openInBrowser(getContext(), "https://antennapod.org/privacy.html");
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
findPreference("about_licenses").setOnPreferenceClickListener((preference) -> {
|
||||||
|
getFragmentManager().beginTransaction().replace(R.id.content, new AboutLicensesFragment())
|
||||||
|
.addToBackStack(getString(R.string.translators)).commit();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
package de.danoeh.antennapod.fragment.preferences;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.fragment.app.ListFragment;
|
||||||
|
import de.danoeh.antennapod.R;
|
||||||
|
import de.danoeh.antennapod.activity.PreferenceActivity;
|
||||||
|
import de.danoeh.antennapod.adapter.SimpleIconListAdapter;
|
||||||
|
import de.danoeh.antennapod.core.util.IntentUtils;
|
||||||
|
import io.reactivex.Single;
|
||||||
|
import io.reactivex.SingleOnSubscribe;
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.Disposable;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
import org.w3c.dom.NamedNodeMap;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class AboutLicensesFragment extends ListFragment {
|
||||||
|
private Disposable licensesLoader;
|
||||||
|
private final ArrayList<LicenseItem> licenses = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
getListView().setDivider(null);
|
||||||
|
|
||||||
|
licensesLoader = Single.create((SingleOnSubscribe<ArrayList<LicenseItem>>) emitter -> {
|
||||||
|
licenses.clear();
|
||||||
|
InputStream stream = getContext().getAssets().open("licenses.xml");
|
||||||
|
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||||
|
NodeList libraryList = docBuilder.parse(stream).getElementsByTagName("library");
|
||||||
|
for (int i = 0; i < libraryList.getLength(); i++) {
|
||||||
|
NamedNodeMap lib = libraryList.item(i).getAttributes();
|
||||||
|
licenses.add(new LicenseItem(
|
||||||
|
lib.getNamedItem("name").getTextContent(),
|
||||||
|
String.format("By %s, %s license",
|
||||||
|
lib.getNamedItem("author").getTextContent(),
|
||||||
|
lib.getNamedItem("license").getTextContent()),
|
||||||
|
null,
|
||||||
|
lib.getNamedItem("website").getTextContent(),
|
||||||
|
lib.getNamedItem("licenseText").getTextContent()));
|
||||||
|
}
|
||||||
|
emitter.onSuccess(licenses);
|
||||||
|
})
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
developers -> setListAdapter(new SimpleIconListAdapter<LicenseItem>(getContext(), developers)),
|
||||||
|
error -> Toast.makeText(getContext(), "Error while loading licenses", Toast.LENGTH_LONG).show()
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LicenseItem extends SimpleIconListAdapter.ListItem {
|
||||||
|
final String licenseUrl;
|
||||||
|
final String licenseTextFile;
|
||||||
|
|
||||||
|
LicenseItem(String title, String subtitle, String imageUrl, String licenseUrl, String licenseTextFile) {
|
||||||
|
super(title, subtitle, imageUrl);
|
||||||
|
this.licenseUrl = licenseUrl;
|
||||||
|
this.licenseTextFile = licenseTextFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onListItemClick(@NonNull ListView l, @NonNull View v, int position, long id) {
|
||||||
|
super.onListItemClick(l, v, position, id);
|
||||||
|
|
||||||
|
LicenseItem item = licenses.get(position);
|
||||||
|
CharSequence[] items = {"View website", "View license"};
|
||||||
|
new AlertDialog.Builder(getContext())
|
||||||
|
.setTitle(item.title)
|
||||||
|
.setItems(items, (dialog, which) -> {
|
||||||
|
if (which == 0) {
|
||||||
|
IntentUtils.openInBrowser(getContext(), item.licenseUrl);
|
||||||
|
} else if (which == 1) {
|
||||||
|
showLicenseText(item.licenseTextFile);
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showLicenseText(String licenseTextFile) {
|
||||||
|
try {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(
|
||||||
|
getContext().getAssets().open(licenseTextFile)));
|
||||||
|
StringBuilder licenseText = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
licenseText.append(line).append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
new AlertDialog.Builder(getContext())
|
||||||
|
.setMessage(licenseText)
|
||||||
|
.show();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
if (licensesLoader != null) {
|
||||||
|
licensesLoader.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
((PreferenceActivity) getActivity()).getSupportActionBar().setTitle(R.string.licenses);
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,7 +42,7 @@ public class AboutTranslatorsFragment extends ListFragment {
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
translators -> setListAdapter(new SimpleIconListAdapter(getContext(), translators)),
|
translators -> setListAdapter(new SimpleIconListAdapter<>(getContext(), translators)),
|
||||||
error -> Toast.makeText(getContext(), "Error while loading translators", Toast.LENGTH_LONG).show()
|
error -> Toast.makeText(getContext(), "Error while loading translators", Toast.LENGTH_LONG).show()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
android:title="@string/translators"/>
|
android:title="@string/translators"/>
|
||||||
<Preference
|
<Preference
|
||||||
android:key="about_privacy_policy"
|
android:key="about_privacy_policy"
|
||||||
android:icon="?attr/action_about"
|
android:icon="?attr/ic_questionmark"
|
||||||
android:summary="https://antennapod.org/privacy.html"
|
android:summary="https://antennapod.org/privacy.html"
|
||||||
android:title="@string/privacy_policy"/>
|
android:title="@string/privacy_policy"/>
|
||||||
<Preference
|
<Preference
|
||||||
|
|
Loading…
Reference in New Issue